mirror of
https://github.com/Telecominfraproject/oopt-gnpy.git
synced 2025-10-29 17:22:42 +00:00
feat: Add conversion utilities for YANG and legacy formats in GNPy
This commit introduces new functions for converting between YANG formatted files and legacy formats. The conversion processes adhere to RFC7951 for encoding YANG data. Key changes include: - Conversion of float and empty type representations. - Transformation of Span and SI lists xx_power_range into dictionaries. - Addition of necessary namespaces. - use of oopt-gnpy-libyang to enforce compliancy to yang models These utilities enable full compatibility with GNPy. Co-authored-by: Renato Ambrosone <renato.ambrosone@polito.it> Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com> Change-Id: Ia004113bca2b0631d1648564e5ccb60504fe80f8
This commit is contained in:
@@ -488,6 +488,109 @@ def unique_ordered(elements):
|
||||
return unique_elements
|
||||
|
||||
|
||||
def convert_empty_to_none(json_data: Union[list, dict]) -> dict:
|
||||
"""Convert all instances of "a": [None] into "a": None
|
||||
|
||||
:param json_data: the input data.
|
||||
:type json_data: dict
|
||||
:return: the converted data.
|
||||
:rtype: dict
|
||||
|
||||
>>> json_data = {
|
||||
... "uid": "[east edfa in Lannion",
|
||||
... "type_variety": "multiband_booster",
|
||||
... "metadata": {
|
||||
... "location": {
|
||||
... "latitude": 0.000000,
|
||||
... "longitude": 0.000000,
|
||||
... "city": "Zion",
|
||||
... "region": ""
|
||||
... }
|
||||
... },
|
||||
... "type": "Multiband_amplifier",
|
||||
... "amplifiers": [{
|
||||
... "type_variety": "multiband_booster_LOW_C",
|
||||
... "operational": {
|
||||
... "gain_target": 12.22,
|
||||
... "delta_p": 4.19,
|
||||
... "out_voa": [None],
|
||||
... "tilt_target": 0.00,
|
||||
... "f_min": 191.3,
|
||||
... "f_max": 196.1
|
||||
... }
|
||||
... }, {
|
||||
... "type_variety": "multiband_booster_LOW_L",
|
||||
... "operational": {
|
||||
... "gain_target": 12.05,
|
||||
... "delta_p": 4.19,
|
||||
... "out_voa": [None],
|
||||
... "tilt_target": 0.00,
|
||||
... "f_min": 186.1,
|
||||
... "f_max": 190.9
|
||||
... }
|
||||
... }
|
||||
... ]
|
||||
... }
|
||||
>>> convert_empty_to_none(json_data)
|
||||
{'uid': '[east edfa in Lannion', 'type_variety': 'multiband_booster', \
|
||||
'metadata': {'location': {'latitude': 0.0, 'longitude': 0.0, 'city': 'Zion', 'region': ''}}, \
|
||||
'type': 'Multiband_amplifier', 'amplifiers': [{'type_variety': 'multiband_booster_LOW_C', \
|
||||
'operational': {'gain_target': 12.22, 'delta_p': 4.19, 'out_voa': None, 'tilt_target': 0.0, \
|
||||
'f_min': 191.3, 'f_max': 196.1}}, {'type_variety': 'multiband_booster_LOW_L', \
|
||||
'operational': {'gain_target': 12.05, 'delta_p': 4.19, 'out_voa': None, 'tilt_target': 0.0, \
|
||||
'f_min': 186.1, 'f_max': 190.9}}]}
|
||||
|
||||
"""
|
||||
if isinstance(json_data, dict):
|
||||
for key, value in json_data.items():
|
||||
json_data[key] = convert_empty_to_none(value)
|
||||
elif isinstance(json_data, list):
|
||||
if len(json_data) == 1 and json_data[0] is None:
|
||||
return None
|
||||
for i, elem in enumerate(json_data):
|
||||
json_data[i] = convert_empty_to_none(elem)
|
||||
return json_data
|
||||
|
||||
|
||||
def convert_none_to_empty(json_data: Union[list, dict]) -> dict:
|
||||
"""Convert all instances of "a": None into "a": [None], to be compliant with RFC7951.
|
||||
|
||||
:param json_data: the input data.
|
||||
:type json_data: dict
|
||||
:return: the converted data.
|
||||
:rtype: dict
|
||||
|
||||
>>> a = {'uid': '[east edfa in Lannion', 'type_variety': 'multiband_booster',
|
||||
... 'metadata': {'location': {'latitude': 0.0, 'longitude': 0.0, 'city': 'Zion', 'region': ''}},
|
||||
... 'type': 'Multiband_amplifier', 'amplifiers': [{'type_variety': 'multiband_booster_LOW_C',
|
||||
... 'operational': {'gain_target': 12.22, 'delta_p': 4.19, 'out_voa': None, 'tilt_target': 0.0,
|
||||
... 'f_min': 191.3, 'f_max': 196.1}}, {'type_variety': 'multiband_booster_LOW_L',
|
||||
... 'operational': {'gain_target': 12.05, 'delta_p': 4.19, 'out_voa': None, 'tilt_target': 0.0,
|
||||
... 'f_min': 186.1, 'f_max': 190.9}}]}
|
||||
>>> convert_none_to_empty(a)
|
||||
{'uid': '[east edfa in Lannion', 'type_variety': 'multiband_booster', \
|
||||
'metadata': {'location': {'latitude': 0.0, 'longitude': 0.0, 'city': 'Zion', 'region': ''}}, \
|
||||
'type': 'Multiband_amplifier', 'amplifiers': [{'type_variety': 'multiband_booster_LOW_C', \
|
||||
'operational': {'gain_target': 12.22, 'delta_p': 4.19, 'out_voa': [None], 'tilt_target': 0.0, \
|
||||
'f_min': 191.3, 'f_max': 196.1}}, {'type_variety': 'multiband_booster_LOW_L', \
|
||||
'operational': {'gain_target': 12.05, 'delta_p': 4.19, 'out_voa': [None], 'tilt_target': 0.0, \
|
||||
'f_min': 186.1, 'f_max': 190.9}}]}
|
||||
|
||||
"""
|
||||
if json_data == [None]:
|
||||
# already conformed
|
||||
return json_data
|
||||
if isinstance(json_data, dict):
|
||||
for key, value in json_data.items():
|
||||
json_data[key] = convert_none_to_empty(value)
|
||||
elif isinstance(json_data, list):
|
||||
for i, elem in enumerate(json_data):
|
||||
json_data[i] = convert_none_to_empty(elem)
|
||||
elif json_data is None:
|
||||
return [None]
|
||||
return json_data
|
||||
|
||||
|
||||
def calculate_absolute_min_or_zero(x: array) -> array:
|
||||
"""Calculates the element-wise absolute minimum between the x and zero.
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "std_low_gain",
|
||||
"type_variety": "std_low_gain_reduced",
|
||||
"type_def": "variable_gain",
|
||||
"gain_flatmax": 16,
|
||||
"gain_min": 8,
|
||||
@@ -295,7 +295,7 @@
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "std_low_gain_multiband_reduced",
|
||||
"type_variety": "std_low_gain_multiband_reduced_bis",
|
||||
"type_def": "multi_band",
|
||||
"amplifiers": [
|
||||
"std_low_gain_bis",
|
||||
|
||||
@@ -52,8 +52,8 @@
|
||||
"explicit-route-objects": {
|
||||
"route-object-include-exclude": [
|
||||
{
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"index": 0,
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"num-unnum-hop": {
|
||||
"node-id": "roadm Brest_KLA",
|
||||
"link-tp-id": "link-tp-id is not used",
|
||||
@@ -61,8 +61,8 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"index": 1,
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"num-unnum-hop": {
|
||||
"node-id": "roadm Lannion_CAS",
|
||||
"link-tp-id": "link-tp-id is not used",
|
||||
@@ -70,8 +70,8 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"index": 2,
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"num-unnum-hop": {
|
||||
"node-id": "roadm Lorient_KMA",
|
||||
"link-tp-id": "link-tp-id is not used",
|
||||
@@ -79,8 +79,8 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"index": 3,
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"num-unnum-hop": {
|
||||
"node-id": "roadm Vannes_KBE",
|
||||
"link-tp-id": "link-tp-id is not used",
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
]
|
||||
},
|
||||
"params": {
|
||||
"type_variety": "SSMF",
|
||||
"length": 80.0,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km",
|
||||
|
||||
243
gnpy/tools/convert_legacy_yang.py
Normal file
243
gnpy/tools/convert_legacy_yang.py
Normal file
@@ -0,0 +1,243 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# JSON files format conversion legacy <-> YANG
|
||||
# Copyright (C) 2025 Telecom Infra Project and GNPy contributors
|
||||
# see AUTHORS.rst for a list of contributors
|
||||
|
||||
"""
|
||||
YANG formatted to legacy format conversion
|
||||
==========================================
|
||||
|
||||
"""
|
||||
|
||||
from argparse import ArgumentParser
|
||||
from pathlib import Path
|
||||
from copy import deepcopy
|
||||
import json
|
||||
from typing import Dict
|
||||
|
||||
from gnpy.tools.yang_convert_utils import convert_degree, convert_back_degree, \
|
||||
convert_delta_power_range, convert_back_delta_power_range, \
|
||||
convert_dict, convert_back, \
|
||||
remove_null_region_city, remove_union_that_fail, \
|
||||
convert_design_band, convert_back_design_band, \
|
||||
convert_none_to_empty, convert_empty_to_none, \
|
||||
convert_loss_coeff_list, convert_back_loss_coeff_list, \
|
||||
ELEMENTS_KEY, PATH_REQUEST_KEY, RESPONSE_KEY, SPECTRUM_KEY, EQPT_TYPES, EDFA_CONFIG_KEYS, SIM_PARAMS_KEYS, \
|
||||
TOPO_NMSP, SERV_NMSP, EQPT_NMSP, SPECTRUM_NMSP, SIM_PARAMS_NMSP, EDFA_CONFIG_NMSP, RESP_NMSP, \
|
||||
dump_data, add_missing_default_type_variety, \
|
||||
remove_namespace_context, load_data, reorder_route_objects, reorder_lumped_losses_objects, \
|
||||
reorder_raman_pumps, convert_raman_coef, convert_back_raman_coef, convert_raman_efficiency, \
|
||||
convert_back_raman_efficiency, convert_nf_coef, convert_back_nf_coef, \
|
||||
convert_nf_fit_coef, convert_back_nf_fit_coef
|
||||
|
||||
|
||||
def legacy_to_yang(json_data: Dict) -> Dict:
|
||||
"""Convert legacy format to GNPy YANG format.
|
||||
|
||||
This function adds the required namespace if not present and processes the input JSON data
|
||||
based on its structure to convert it to the appropriate YANG format. There is no validation
|
||||
of yang formatted data.
|
||||
|
||||
:param json_data: The input JSON data to convert.
|
||||
:type json_data: Dict
|
||||
:return: The converted JSON data in GNPy YANG format.
|
||||
:rtype: Dict
|
||||
"""
|
||||
json_data = convert_none_to_empty(deepcopy(json_data))
|
||||
|
||||
# case of topology json
|
||||
if ELEMENTS_KEY in json_data:
|
||||
json_data = reorder_raman_pumps(json_data)
|
||||
json_data = reorder_lumped_losses_objects(json_data)
|
||||
json_data = remove_null_region_city(json_data)
|
||||
json_data = convert_degree(json_data)
|
||||
json_data = convert_design_band(json_data)
|
||||
json_data = convert_loss_coeff_list(json_data)
|
||||
json_data = convert_raman_coef(json_data)
|
||||
json_data = {TOPO_NMSP: json_data}
|
||||
elif TOPO_NMSP in json_data:
|
||||
# then this is a new format topology json, ensure that there are no issues
|
||||
json_data[TOPO_NMSP] = convert_degree(json_data[TOPO_NMSP])
|
||||
json_data[TOPO_NMSP] = convert_design_band(json_data[TOPO_NMSP])
|
||||
json_data[TOPO_NMSP] = convert_loss_coeff_list(json_data[TOPO_NMSP])
|
||||
json_data[TOPO_NMSP] = remove_null_region_city(json_data[TOPO_NMSP])
|
||||
|
||||
# case of equipment json
|
||||
elif any(k in json_data for k in EQPT_TYPES):
|
||||
json_data = convert_raman_efficiency(json_data)
|
||||
json_data = convert_delta_power_range(json_data)
|
||||
json_data = convert_nf_coef(json_data)
|
||||
json_data = add_missing_default_type_variety(json_data)
|
||||
json_data = {EQPT_NMSP: json_data}
|
||||
elif EQPT_NMSP in json_data:
|
||||
# then this is already a new format topology json, ensure that there are no issues
|
||||
json_data[EQPT_NMSP] = convert_raman_efficiency(json_data[EQPT_NMSP])
|
||||
json_data[EQPT_NMSP] = convert_delta_power_range(json_data[EQPT_NMSP])
|
||||
json_data[EQPT_NMSP] = convert_nf_coef(json_data[EQPT_NMSP])
|
||||
json_data[EQPT_NMSP] = add_missing_default_type_variety(json_data[EQPT_NMSP])
|
||||
|
||||
# case of service json
|
||||
elif PATH_REQUEST_KEY in json_data:
|
||||
json_data = reorder_route_objects(json_data)
|
||||
json_data = remove_union_that_fail(json_data)
|
||||
json_data = {SERV_NMSP: json_data}
|
||||
|
||||
elif SERV_NMSP in json_data:
|
||||
json_data[SERV_NMSP] = reorder_route_objects(json_data[SERV_NMSP])
|
||||
json_data[SERV_NMSP] = remove_union_that_fail(json_data[SERV_NMSP])
|
||||
|
||||
# case of edfa_config json
|
||||
elif any(k in json_data for k in EDFA_CONFIG_KEYS):
|
||||
json_data = convert_nf_fit_coef(json_data)
|
||||
json_data = {EDFA_CONFIG_NMSP: json_data}
|
||||
|
||||
elif EDFA_CONFIG_NMSP in json_data:
|
||||
json_data[EDFA_CONFIG_NMSP] = convert_nf_fit_coef(json_data[EDFA_CONFIG_NMSP])
|
||||
|
||||
# case of spectrum json
|
||||
elif SPECTRUM_KEY in json_data:
|
||||
json_data = {SPECTRUM_NMSP: json_data[SPECTRUM_KEY]}
|
||||
|
||||
# case of sim_params json
|
||||
elif any(k in json_data for k in SIM_PARAMS_KEYS):
|
||||
json_data = {SIM_PARAMS_NMSP: json_data}
|
||||
|
||||
# case of response json
|
||||
elif RESPONSE_KEY in json_data:
|
||||
json_data = {RESP_NMSP: json_data}
|
||||
|
||||
elif any(k in json_data for k in [SPECTRUM_NMSP, SIM_PARAMS_NMSP, RESP_NMSP]):
|
||||
# then this is a new format json, nothing to convert
|
||||
pass
|
||||
|
||||
else:
|
||||
raise ValueError('Unrecognized type of content (not topology, service or equipment)')
|
||||
|
||||
json_data = convert_dict(json_data)
|
||||
return json_data
|
||||
|
||||
|
||||
def yang_to_legacy(json_data: Dict) -> Dict:
|
||||
"""Convert GNPy YANG format to legacy format.
|
||||
|
||||
This function processes the input JSON data to convert it from the new GNPy YANG format
|
||||
back to the legacy format. It handles various types of content, including topology,
|
||||
equipment, and service jsons, ensuring that the necessary conversions are applied.
|
||||
The input data is validated with oopt-gnpy-libyang.
|
||||
|
||||
:param json_data: The input JSON data in GNPy YANG format to convert.
|
||||
:type json_data: Dict
|
||||
:return: The converted JSON data in legacy format.
|
||||
:rtype: Dict
|
||||
|
||||
:raises ValueError: If the input JSON data does not match any recognized content type
|
||||
(not topology, service, or equipment).
|
||||
"""
|
||||
# validate data compliance: make sure that this is yang formated data before validation.
|
||||
load_data(json.dumps(legacy_to_yang(json_data)))
|
||||
json_data = convert_empty_to_none(json_data)
|
||||
json_data = convert_back(json_data)
|
||||
|
||||
# case of topology json
|
||||
if ELEMENTS_KEY in json_data:
|
||||
json_data = convert_back_degree(json_data)
|
||||
json_data = convert_back_design_band(json_data)
|
||||
json_data = convert_back_loss_coeff_list(json_data)
|
||||
json_data = convert_back_raman_coef(json_data)
|
||||
elif TOPO_NMSP in json_data:
|
||||
json_data = convert_back_degree(json_data[TOPO_NMSP])
|
||||
json_data = convert_back_design_band(json_data)
|
||||
json_data = convert_back_loss_coeff_list(json_data)
|
||||
json_data = convert_back_raman_coef(json_data)
|
||||
|
||||
# case of equipment json
|
||||
elif any(k in json_data for k in EQPT_TYPES):
|
||||
json_data = convert_back_delta_power_range(json_data)
|
||||
json_data = convert_back_raman_efficiency(json_data)
|
||||
json_data = convert_back_nf_coef(json_data)
|
||||
json_data = remove_namespace_context(json_data, "gnpy-eqpt-config:")
|
||||
elif EQPT_NMSP in json_data:
|
||||
json_data[EQPT_NMSP] = convert_back_delta_power_range(json_data[EQPT_NMSP])
|
||||
json_data[EQPT_NMSP] = convert_back_raman_efficiency(json_data[EQPT_NMSP])
|
||||
json_data[EQPT_NMSP] = convert_back_nf_coef(json_data[EQPT_NMSP])
|
||||
json_data = remove_namespace_context(json_data[EQPT_NMSP], "gnpy-eqpt-config:")
|
||||
|
||||
# case of EDFA config json
|
||||
elif any(k in json_data for k in EDFA_CONFIG_KEYS):
|
||||
json_data = convert_back_nf_fit_coef(json_data)
|
||||
elif EDFA_CONFIG_NMSP in json_data:
|
||||
json_data[EDFA_CONFIG_NMSP] = convert_back_nf_fit_coef(json_data[EDFA_CONFIG_NMSP])
|
||||
|
||||
# case of service json
|
||||
elif SERV_NMSP in json_data:
|
||||
json_data = json_data[SERV_NMSP]
|
||||
|
||||
# case of sim_params json
|
||||
elif SIM_PARAMS_NMSP in json_data:
|
||||
json_data = json_data[SIM_PARAMS_NMSP]
|
||||
|
||||
# case of spectrum json
|
||||
elif SPECTRUM_NMSP in json_data:
|
||||
json_data = {SPECTRUM_KEY: json_data[SPECTRUM_NMSP]}
|
||||
|
||||
# case of planning response json
|
||||
elif RESP_NMSP in json_data:
|
||||
json_data = json_data[RESP_NMSP]
|
||||
elif any(k in json_data for k in SIM_PARAMS_KEYS + [SPECTRUM_KEY, RESPONSE_KEY, PATH_REQUEST_KEY]):
|
||||
# then this is a legacy format json, nothing to convert
|
||||
pass
|
||||
else:
|
||||
raise ValueError('Unrecognized type of content (not topology, service or equipment)')
|
||||
return json_data
|
||||
|
||||
|
||||
def main():
|
||||
"""Conversion function
|
||||
"""
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument('--legacy-to-yang', nargs='?', type=Path,
|
||||
help='convert file with this name into yangconformedname.json')
|
||||
parser.add_argument('--yang-to-legacy', nargs='?', type=Path,
|
||||
help='convert file with this name into gnpy'
|
||||
+ ' using decimal instead of strings and null instead of [null]')
|
||||
parser.add_argument('--validate', nargs='?', type=Path,
|
||||
help='validate yang conformity')
|
||||
parser.add_argument('-o', '--output', type=Path,
|
||||
help='Stores into file with this name; default = GNPy_legacy_formatted-<file_name>.json or'
|
||||
+ 'GNPy_yang_formatted-<file_name>.json')
|
||||
args = parser.parse_args()
|
||||
|
||||
if not (args.legacy_to_yang or args.yang_to_legacy or args.validate):
|
||||
parser.error("You must specify at least one of --legacy-to-yang, --yang-to-legacy, or --validate ")
|
||||
|
||||
output = None
|
||||
converted = None
|
||||
if args.validate:
|
||||
with open(args.validate, 'r', encoding='utf-8') as f:
|
||||
json_data = json.load(f)
|
||||
load_data(json.dumps(json_data))
|
||||
return 0
|
||||
elif args.legacy_to_yang:
|
||||
prefix = 'GNPy_yang_formatted-'
|
||||
with open(args.legacy_to_yang, 'r', encoding='utf-8') as f:
|
||||
json_data = json.load(f)
|
||||
# note that dump_data automatically validate date against yang models
|
||||
converted = dump_data(legacy_to_yang(json_data))
|
||||
output = prefix + str(args.legacy_to_yang.name)
|
||||
elif args.yang_to_legacy:
|
||||
prefix = 'GNPy_legacy_formatted-'
|
||||
with open(args.yang_to_legacy, 'r', encoding='utf-8') as f:
|
||||
json_data = json.load(f)
|
||||
converted = json.dumps(yang_to_legacy(json_data), indent=2, ensure_ascii=False)
|
||||
output = prefix + str(args.yang_to_legacy.name)
|
||||
if args.output:
|
||||
output = args.output
|
||||
with open(output, 'w', encoding='utf-8') as f:
|
||||
f.write(converted)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -34,6 +34,7 @@ from gnpy.topology.request import PathRequest, Disjunction, compute_spectrum_slo
|
||||
from gnpy.topology.spectrum_assignment import mvalue_to_slots
|
||||
from gnpy.tools.convert import xls_to_json_data
|
||||
from gnpy.tools.service_sheet import read_service_sheet
|
||||
from gnpy.tools.convert_legacy_yang import yang_to_legacy, legacy_to_yang
|
||||
|
||||
|
||||
_logger = getLogger(__name__)
|
||||
@@ -433,14 +434,14 @@ def load_equipments_and_configs(equipment_filename: Path,
|
||||
def load_equipment(filename: Path, extra_configs: Dict[str, Path] = DEFAULT_EXTRA_CONFIG) -> dict:
|
||||
"""Load equipment, returns equipment dict
|
||||
"""
|
||||
json_data = load_json(filename)
|
||||
json_data = load_gnpy_json(filename)
|
||||
return _equipment_from_json(json_data, extra_configs)
|
||||
|
||||
|
||||
def load_initial_spectrum(filename: Path) -> dict:
|
||||
"""Load spectrum to propagate, returns spectrum dict
|
||||
"""
|
||||
json_data = load_json(filename)
|
||||
json_data = load_gnpy_json(filename)
|
||||
return _spectrum_from_json(json_data['spectrum'])
|
||||
|
||||
|
||||
@@ -586,7 +587,7 @@ def load_network(filename: Path, equipment: dict) -> DiGraph:
|
||||
if filename.suffix.lower() in ('.xls', '.xlsx'):
|
||||
json_data = xls_to_json_data(filename)
|
||||
elif filename.suffix.lower() == '.json':
|
||||
json_data = load_json(filename)
|
||||
json_data = load_gnpy_json(filename)
|
||||
else:
|
||||
raise ValueError(f'unsupported topology filename extension {filename.suffix.lower()}')
|
||||
return network_from_json(json_data, equipment)
|
||||
@@ -747,17 +748,33 @@ def network_to_json(network: DiGraph) -> dict:
|
||||
|
||||
|
||||
def load_json(filename: Path) -> dict:
|
||||
"""load json data, convert from the yang to the legacy
|
||||
supports both legacy ang yang formatted inputs based on yang models
|
||||
"""load json data
|
||||
|
||||
:param filename: Path to the file to convert
|
||||
:type filemname: Path
|
||||
:return: json data in a dictionnary
|
||||
:rtype: Dict
|
||||
"""
|
||||
with open(filename, 'r', encoding='utf-8') as f:
|
||||
data = json.load(f)
|
||||
return data
|
||||
|
||||
|
||||
def save_json(obj: Dict, filename: Path):
|
||||
"""Save in json format. Use yang formatted data for Topo and Services
|
||||
def load_gnpy_json(filename: Path) -> dict:
|
||||
"""load json data. It supports both legacy ang yang formatted inputs based on yang models.
|
||||
|
||||
:param filename: Path to the file to convert
|
||||
:type filemname: Path
|
||||
:return: json data in a dictionnary
|
||||
:rtype: Dict
|
||||
"""
|
||||
return yang_to_legacy(load_json(filename))
|
||||
|
||||
|
||||
def save_json(obj: dict, filename: Path):
|
||||
"""Save in json format. Export yang formatted data (RFC7951)
|
||||
"""
|
||||
data = legacy_to_yang(obj)
|
||||
with open(filename, 'w', encoding='utf-8') as f:
|
||||
json.dump(obj, f, indent=2, ensure_ascii=False)
|
||||
|
||||
|
||||
960
gnpy/tools/yang_convert_utils.py
Normal file
960
gnpy/tools/yang_convert_utils.py
Normal file
@@ -0,0 +1,960 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# Utils for yang <-> legacy format conversion
|
||||
# Copyright (C) 2025 Telecom Infra Project and GNPy contributors
|
||||
# see AUTHORS.rst for a list of contributors
|
||||
|
||||
"""
|
||||
Utils for yang <-> legacy format conversion
|
||||
===========================================
|
||||
|
||||
Format conversion utils.
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
from copy import deepcopy
|
||||
from typing import Dict, Union, List, Any, NamedTuple
|
||||
import json
|
||||
import os
|
||||
|
||||
import oopt_gnpy_libyang as ly
|
||||
|
||||
from gnpy.yang.precision_dict import PRECISION_DICT
|
||||
|
||||
ELEMENTS_KEY = 'elements'
|
||||
ROADM_KEY = 'Roadm'
|
||||
PARAMS_KEY = 'params'
|
||||
METADATA_KEY = 'metadata'
|
||||
LOCATION_KEY = 'location'
|
||||
DEGREE_KEY = 'degree_uid'
|
||||
PATH_REQUEST_KEY = 'path-request'
|
||||
RESPONSE_KEY = 'response'
|
||||
SPECTRUM_KEY = 'spectrum'
|
||||
LOSS_COEF_KEY = 'loss_coef'
|
||||
LOSS_COEF_KEY_PER_FREQ = 'loss_coef_per_frequency'
|
||||
RAMAN_COEF_KEY = 'raman_coefficient'
|
||||
RAMAN_EFFICIENCY_KEY = 'raman_efficiency'
|
||||
EQPT_TYPES = ['Edfa', 'Transceiver', 'Fiber', 'Roadm']
|
||||
EDFA_CONFIG_KEYS = ['nf_fit_coeff', 'nf_ripple', 'gain_ripple', 'dgt']
|
||||
SIM_PARAMS_KEYS = ['raman_params', 'nli_params']
|
||||
TOPO_NMSP = 'gnpy-network-topology:topology'
|
||||
EQPT_NMSP = 'gnpy-eqpt-config:equipment'
|
||||
SERV_NMSP = 'gnpy-path-computation:services'
|
||||
RESP_NMSP = 'gnpy-path-computation:responses'
|
||||
EDFA_CONFIG_NMSP = 'gnpy-edfa-config:edfa-config'
|
||||
SIM_PARAMS_NMSP = 'gnpy-sim-params:sim-params'
|
||||
SPECTRUM_NMSP = 'gnpy-spectrum:spectrum'
|
||||
|
||||
|
||||
class PrettyFloat(float):
|
||||
""""A float subclass for formatting according to specific fraction digit requirements.
|
||||
|
||||
>>> PrettyFloat(3.1245)
|
||||
3.12
|
||||
>>> PrettyFloat(100.65, 5)
|
||||
100.65
|
||||
>>> PrettyFloat(2.1e-5, 8)
|
||||
0.000021
|
||||
>>> PrettyFloat(10, 3)
|
||||
10.0
|
||||
>>> PrettyFloat(-0.3110761646066259, 18)
|
||||
-0.3110761646066259
|
||||
"""
|
||||
def __new__(cls, value: float, fraction_digit: int = 2):
|
||||
"""Create a new instance of PrettyFloat"""
|
||||
instance = super().__new__(cls, value)
|
||||
instance.fraction_digit = fraction_digit
|
||||
instance.value = value
|
||||
return instance
|
||||
|
||||
def __repr__(self) -> str:
|
||||
"""Return the string representation of the float formatted to the specified fraction digits. It removes
|
||||
scientific notation ("e-x").
|
||||
"""
|
||||
# When fraction digit is over 16, the usual formatting does not works properly because of floating point issues.
|
||||
# For example -0.3110761646066259 is represented as "-0.311076164606625905". The following function makes
|
||||
# sure that the unwanted floating point issue does not change the value. Maximum fraction digit in YANG is 18.
|
||||
if self.fraction_digit in range(0, 19):
|
||||
temp = str(self.value)
|
||||
if 'e' in temp or '.' not in temp or self.fraction_digit < 17:
|
||||
formatted_value = f'{self:.{self.fraction_digit}f}' # noqa E231
|
||||
if '.' in formatted_value:
|
||||
formatted_value = formatted_value.rstrip('0')
|
||||
if formatted_value.endswith('.'):
|
||||
formatted_value += '0'
|
||||
return formatted_value
|
||||
if '.' in temp:
|
||||
parts = temp.split('.')
|
||||
formatted_value = parts[0] + '.' + parts[1][0:min(self.fraction_digit, len(parts[1]))]
|
||||
formatted_value = formatted_value.rstrip('0')
|
||||
if formatted_value.endswith('.'):
|
||||
formatted_value += '0'
|
||||
return formatted_value
|
||||
return temp
|
||||
raise ValueError(f'Fraction digit {self.fraction_digit} not handled')
|
||||
|
||||
|
||||
def gnpy_precision_dict() -> Dict[str, int]:
|
||||
"""Return a dictionary of fraction-digit definitions for GNPy.
|
||||
Precision correspond to fraction digit number if it is a decimal64 yang type, or 0 if it is an
|
||||
(u)int < 64 or -1 if it is a string or an (u)int64 type.
|
||||
|
||||
:return: Dictionnary mapping key names with digit numbers for values.
|
||||
:rtype: Dict[str, int]
|
||||
"""
|
||||
return PRECISION_DICT
|
||||
|
||||
|
||||
def convert_dict(data: Dict, fraction_digit: int = 2, precision: Union[Dict[str, int], None] = None) \
|
||||
-> Union[Dict, List, float, int, str, None]:
|
||||
"""Recursive conversion from float to str, conformed to RFC7951
|
||||
does not work for int64 (will not returm str as stated in standard)
|
||||
If nothing is stated precision is using gnpy_precision_dict.
|
||||
|
||||
:param data: the input dictionary to convert.
|
||||
:type data: data: Dict
|
||||
:param fraction_digit: the number of decimal places to format.
|
||||
:type fraction_digit: int
|
||||
:param precision: A dictionary defining precision for specific keys.
|
||||
:type precision: Union[Dict[str, int], None]
|
||||
:return: A new dictionary with converted values.
|
||||
:rtype: Dict
|
||||
|
||||
>>> convert_dict({"y": "amp", "t": "vn", "g": 25, "gamma": 0.0016, "p": 21.5, "o": True, \
|
||||
"output-power": 14.12457896})
|
||||
{'y': 'amp', 't': 'vn', 'g': '25.0', 'gamma': '0.0016', 'p': '21.5', 'o': True, 'output-power': '14.12457896'}
|
||||
"""
|
||||
if not precision:
|
||||
precision = gnpy_precision_dict()
|
||||
if isinstance(data, dict):
|
||||
for k, v in data.items():
|
||||
fraction_digit = precision.get(k, 2)
|
||||
data[k] = convert_dict(v, fraction_digit, precision=precision)
|
||||
elif isinstance(data, list):
|
||||
temp = deepcopy(data)
|
||||
for i, el in enumerate(temp):
|
||||
if isinstance(el, float):
|
||||
data[i] = PrettyFloat(el, fraction_digit)
|
||||
data[i] = str(data[i])
|
||||
else:
|
||||
data[i] = convert_dict(el, fraction_digit=fraction_digit, precision=precision)
|
||||
elif isinstance(data, bool):
|
||||
return data
|
||||
elif isinstance(data, int):
|
||||
data = PrettyFloat(data)
|
||||
data.fraction_digit = fraction_digit
|
||||
if fraction_digit > 0:
|
||||
return str(data)
|
||||
if fraction_digit < 0:
|
||||
return data
|
||||
return int(data)
|
||||
elif isinstance(data, float):
|
||||
data = PrettyFloat(data)
|
||||
data.fraction_digit = fraction_digit
|
||||
return str(data)
|
||||
return data
|
||||
|
||||
|
||||
def convert_back(data: Dict, fraction_digit: Union[int, None] = None, precision: Union[Dict[str, int], None] = None) \
|
||||
-> Union[Dict, List, float, int, str, None]:
|
||||
"""Recursively convert strings back to their original types int, float according to RFC7951.
|
||||
|
||||
:param data: the input dictionary to convert.
|
||||
:type data: Dict
|
||||
:param fraction_digit: the number of decimal places to format.
|
||||
:type fraction_digit: Union[int, None]
|
||||
:param precision: A dictionary defining precision for specific keys.
|
||||
:type precision: Union[Dict[str, int], None]
|
||||
:return: A new dictionary with converted values.
|
||||
:rtype: Dict
|
||||
|
||||
>>> a = {'y': 'amp', 't': 'vn', 'N': '25', 'gamma': '0.0000000000000016', 'p': '21.50', 'o': True, \
|
||||
'output-power': '14.12458'}
|
||||
>>> convert_back({'a': a, 'delta_power_range_db': ['12.3', '10.6', True]})
|
||||
{'a': {'y': 'amp', 't': 'vn', 'N': 25, 'gamma': 1.6e-15, 'p': '21.50', 'o': True, 'output-power': 14.12458}, \
|
||||
'delta_power_range_db': ['12.3', '10.6', True]}
|
||||
"""
|
||||
if not precision:
|
||||
precision = gnpy_precision_dict()
|
||||
if isinstance(data, dict):
|
||||
for k, v in data.items():
|
||||
fraction_digit = None
|
||||
if k in precision:
|
||||
fraction_digit = precision[k]
|
||||
data[k] = convert_back(v, fraction_digit, precision=precision)
|
||||
elif isinstance(data, list):
|
||||
for i, el in enumerate(data):
|
||||
if isinstance(el, str) and fraction_digit not in [None, -1]:
|
||||
data[i] = float(data[i])
|
||||
else:
|
||||
data[i] = convert_back(el, fraction_digit=fraction_digit, precision=precision)
|
||||
elif isinstance(data, (bool, int, float)):
|
||||
return data
|
||||
elif isinstance(data, str) and fraction_digit is not None:
|
||||
if fraction_digit > 0:
|
||||
return float(data)
|
||||
if fraction_digit < 0:
|
||||
return data
|
||||
return int(data)
|
||||
return data
|
||||
|
||||
|
||||
def model_path() -> Path:
|
||||
"""Filesystem path to YANG models.
|
||||
|
||||
return: path to the GNPy YANG modules.
|
||||
rtype: Path
|
||||
"""
|
||||
return Path(__file__).parent.parent / 'yang'
|
||||
|
||||
|
||||
def external_yang() -> Path:
|
||||
"""Filesystem to the IETF external yang modules.
|
||||
|
||||
return: path to the IETF modules.
|
||||
rtype: Path
|
||||
"""
|
||||
return Path(__file__).parent.parent / 'yang' / 'ext'
|
||||
|
||||
|
||||
def yang_lib() -> Path:
|
||||
"""Path to the json library of needed yang modules.
|
||||
|
||||
return: path to the library describing all modules and revisions for this gnpy release.
|
||||
rtype: Path
|
||||
"""
|
||||
return Path(__file__).parent.parent / 'yang' / 'yang-library-gnpy.json'
|
||||
|
||||
|
||||
def _create_context(yang_library) -> ly.Context:
|
||||
"""Prepare a libyang context for validating data against GNPy YANG models.
|
||||
|
||||
:param yang_library: path to the library describing all modules and revisions to be considered for the formatted
|
||||
string generation.
|
||||
:type yang_library: Path
|
||||
:return: Context used to hold all information about schemas.
|
||||
:rtype: ly.Context
|
||||
"""
|
||||
ly.set_log_options(ly.LogOptions.Log | ly.LogOptions.Store)
|
||||
ctx = ly.Context(str(model_path()) + os.pathsep + str(external_yang()),
|
||||
ly.ContextOptions.AllImplemented | ly.ContextOptions.DisableSearchCwd)
|
||||
with open(yang_library, 'r', encoding='utf-8') as file:
|
||||
data = json.load(file)
|
||||
yang_modules = [{'name': e['name'], 'revision': e['revision']}
|
||||
for e in data['ietf-yang-library:modules-state']['module']]
|
||||
for module in yang_modules:
|
||||
ctx.load_module(module['name'], revision=module['revision'])
|
||||
return ctx
|
||||
|
||||
|
||||
class ErrorMessage(NamedTuple):
|
||||
# pylint: disable=C0115
|
||||
what: str
|
||||
where: str
|
||||
|
||||
|
||||
def load_data(s: str, yang_library: Path = yang_lib()) -> ly.DataNode:
|
||||
"""Load data from YANG-based JSON input and validate them.
|
||||
|
||||
:param data: a string contating the json data to be loaded.
|
||||
:type data: str
|
||||
:param yang_library: path to the library describing all modules and revisions to be considered for the formatted
|
||||
string generation.
|
||||
:type yang_library: Path
|
||||
:return: DataNode containing the loaded data
|
||||
:rtype: ly.DataNode
|
||||
"""
|
||||
ctx = _create_context(yang_library)
|
||||
try:
|
||||
data = ctx.parse_data(s, ly.DataFormat.JSON,
|
||||
ly.ParseOptions.Strict | ly.ParseOptions.Ordered,
|
||||
ly.ValidationOptions.Present
|
||||
| ly.ValidationOptions.MultiError)
|
||||
except ly.Error as exc:
|
||||
raise ly.Error(exc, [ErrorMessage(err.message, err.path) for err in ctx.errors()]) from None
|
||||
return data
|
||||
|
||||
|
||||
def dump_data(data: Dict, yang_library: Path = yang_lib()) -> str:
|
||||
"""Creates a formatted string using oopt-gnpy-libyang.
|
||||
|
||||
:param data: a json dict with data already formatted
|
||||
:type data: Dict
|
||||
:param yang_library: path to the library describing all modules and revisions to be considered for the formatted
|
||||
string generation.
|
||||
:type yang_library: Path
|
||||
:return: formatted string data
|
||||
:rtype: str
|
||||
"""
|
||||
return load_data(json.dumps(data), yang_library).print(ly.DataFormat.JSON, ly.PrintFlags.WithSiblings)
|
||||
|
||||
|
||||
def convert_degree(json_data: Dict) -> Dict:
|
||||
"""Convert legacy json topology format to gnpy yang format revision 2025-01-20:
|
||||
|
||||
:param json_data: The input JSON topology data to convert.
|
||||
:type json_data: Dict
|
||||
:return: the converted JSON data
|
||||
:rtype: Dict
|
||||
"""
|
||||
for elem in json_data[ELEMENTS_KEY]:
|
||||
if elem['type'] == ROADM_KEY and PARAMS_KEY in elem:
|
||||
new_targets = []
|
||||
for equalization_type in ['per_degree_pch_out_db', 'per_degree_psd_out_mWperGHz',
|
||||
'per_degree_psd_out_mWperSlotWidth']:
|
||||
targets = elem[PARAMS_KEY].pop(equalization_type, None)
|
||||
if targets:
|
||||
new_targets.extend([{DEGREE_KEY: degree, equalization_type: target}
|
||||
for degree, target in targets.items()])
|
||||
if new_targets:
|
||||
elem[PARAMS_KEY]['per_degree_power_targets'] = new_targets
|
||||
return json_data
|
||||
|
||||
|
||||
def convert_back_degree(json_data: Dict) -> Dict:
|
||||
"""Convert gnpy yang format back to legacy json topology format.
|
||||
|
||||
:param json_data: The input JSON topology data to convert back.
|
||||
:type json_data: Dict
|
||||
:return: the converted JSON data
|
||||
:rtype: Dict
|
||||
"""
|
||||
for elem in json_data[ELEMENTS_KEY]:
|
||||
if elem['type'] != ROADM_KEY or PARAMS_KEY not in elem:
|
||||
continue
|
||||
power_targets = elem[PARAMS_KEY].pop('per_degree_power_targets', None)
|
||||
if not power_targets:
|
||||
continue
|
||||
# Process each power target
|
||||
process_power_targets(elem, power_targets)
|
||||
return json_data
|
||||
|
||||
|
||||
def process_power_targets(elem: Dict, power_targets: List[Dict]) -> None:
|
||||
"""Process power targets and update element parameters.
|
||||
|
||||
:param elem: The element to update
|
||||
:type elem: Dict
|
||||
:param power_targets: List of power target configurations
|
||||
:type power_targets: List[Dict]
|
||||
"""
|
||||
equalization_types = [
|
||||
'per_degree_pch_out_db',
|
||||
'per_degree_psd_out_mWperGHz',
|
||||
'per_degree_psd_out_mWperSlotWidth'
|
||||
]
|
||||
|
||||
for target in power_targets:
|
||||
degree_uid = target[DEGREE_KEY]
|
||||
for eq_type in equalization_types:
|
||||
if eq_type not in target:
|
||||
continue
|
||||
# Initialize the equalization type dict if needed
|
||||
if eq_type not in elem[PARAMS_KEY]:
|
||||
elem[PARAMS_KEY][eq_type] = {}
|
||||
# Set the value for this degree
|
||||
elem[PARAMS_KEY][eq_type][degree_uid] = target[eq_type]
|
||||
|
||||
|
||||
def convert_loss_coeff_list(json_data: Dict) -> Dict:
|
||||
"""Convert legacy json topology format to gnpy yang format revision 2025-01-20:
|
||||
|
||||
:param json_data: The input JSON topology data to convert.
|
||||
:type json_data: Dict
|
||||
:return: the converted JSON data
|
||||
:rtype: Dict
|
||||
"""
|
||||
for elem in json_data[ELEMENTS_KEY]:
|
||||
if PARAMS_KEY in elem and LOSS_COEF_KEY in elem[PARAMS_KEY] \
|
||||
and isinstance(elem[PARAMS_KEY][LOSS_COEF_KEY], dict):
|
||||
loss_coef_per_frequency = elem[PARAMS_KEY].pop(LOSS_COEF_KEY)
|
||||
loss_coef_list = loss_coef_per_frequency.pop('loss_coef_value', None)
|
||||
frequency_list = loss_coef_per_frequency.pop('frequency', None)
|
||||
if loss_coef_list:
|
||||
new_loss_coef_per_frequency = [{'frequency': f, 'loss_coef_value': v}
|
||||
for f, v in zip(frequency_list, loss_coef_list)]
|
||||
elem[PARAMS_KEY][LOSS_COEF_KEY_PER_FREQ] = new_loss_coef_per_frequency
|
||||
return json_data
|
||||
|
||||
|
||||
def convert_back_loss_coeff_list(json_data: Dict) -> Dict:
|
||||
"""Convert gnpy yang format revision 2025-01-20 back to legacy json topology format
|
||||
|
||||
:param json_data: The input JSON topology data to convert back
|
||||
:type json_data: Dict
|
||||
:return: the converted JSON data
|
||||
:rtype: Dict
|
||||
"""
|
||||
for elem in json_data[ELEMENTS_KEY]:
|
||||
if PARAMS_KEY in elem and LOSS_COEF_KEY_PER_FREQ in elem[PARAMS_KEY]:
|
||||
loss_coef_per_frequency = elem[PARAMS_KEY].pop(LOSS_COEF_KEY_PER_FREQ)
|
||||
if loss_coef_per_frequency:
|
||||
new_loss_coef_per_frequency = {
|
||||
'frequency': [item['frequency'] for item in loss_coef_per_frequency],
|
||||
'loss_coef_value': [item['loss_coef_value'] for item in loss_coef_per_frequency]}
|
||||
elem[PARAMS_KEY]['loss_coef'] = new_loss_coef_per_frequency
|
||||
return json_data
|
||||
|
||||
|
||||
def convert_design_band(json_data: Dict) -> Dict:
|
||||
"""Convert legacy json topology format to gnpy yang format revision 2025-01-20:
|
||||
|
||||
:param json_data: The input JSON topology data to convert.
|
||||
:type json_data: Dict
|
||||
:return: the converted JSON data
|
||||
:rtype: Dict
|
||||
"""
|
||||
for elem in json_data[ELEMENTS_KEY]:
|
||||
if elem['type'] == ROADM_KEY and PARAMS_KEY in elem:
|
||||
new_targets = []
|
||||
targets = elem[PARAMS_KEY].pop('per_degree_design_bands', None)
|
||||
if targets:
|
||||
new_targets.extend([{DEGREE_KEY: degree, 'design_bands': target}
|
||||
for degree, target in targets.items()])
|
||||
if new_targets:
|
||||
elem[PARAMS_KEY]['per_degree_design_bands_targets'] = new_targets
|
||||
return json_data
|
||||
|
||||
|
||||
def convert_back_design_band(json_data: Dict) -> Dict:
|
||||
"""Convert gnpy yang format revision 2025-01-20 back to legacy json topology format
|
||||
|
||||
:param json_data: The input JSON topology data to convert back
|
||||
:type json_data: Dict
|
||||
:return: the converted JSON data
|
||||
:rtype: Dict
|
||||
"""
|
||||
for elem in json_data[ELEMENTS_KEY]:
|
||||
if elem['type'] == ROADM_KEY and PARAMS_KEY in elem:
|
||||
targets = elem[PARAMS_KEY].pop('per_degree_design_bands_targets', None)
|
||||
if targets:
|
||||
design_bands = {}
|
||||
for target in targets:
|
||||
design_bands[target[DEGREE_KEY]] = target['design_bands']
|
||||
if design_bands:
|
||||
elem[PARAMS_KEY]['per_degree_design_bands'] = design_bands
|
||||
return json_data
|
||||
|
||||
|
||||
def convert_range_to_dict(range_values: List[float]) -> Dict[str, float]:
|
||||
"""Convert a range list to a dictionary format:
|
||||
|
||||
:param range_values: range of loat values defined with the format [min, max, step].
|
||||
:type range_value: List[float]
|
||||
:return: range formatted as a dict {"min_value": min, "max_value": max, "step": step}
|
||||
:rtype: Dict[str, float]
|
||||
"""
|
||||
return {
|
||||
'min_value': range_values[0],
|
||||
'max_value': range_values[1],
|
||||
'step': range_values[2]
|
||||
}
|
||||
|
||||
|
||||
def process_span_data(span: Dict) -> None:
|
||||
"""Convert Span data with range in dict format
|
||||
:param span: The span data to process.
|
||||
:type span: Dict
|
||||
"""
|
||||
if 'delta_power_range_dict_db' in span:
|
||||
return
|
||||
|
||||
if 'delta_power_range_db' not in span:
|
||||
raise KeyError('delta_power_range or delta_power_range_dict_db missing in Span dict.')
|
||||
|
||||
delta_power_range_db = span.get('delta_power_range_db', [0, 0, 0])
|
||||
span['delta_power_range_dict_db'] = convert_range_to_dict(delta_power_range_db)
|
||||
del span['delta_power_range_db']
|
||||
|
||||
|
||||
def process_si_data(si: Dict) -> None:
|
||||
"""Convert Span data with range in dict format
|
||||
:param si: The span data to process.
|
||||
:type si: Dict
|
||||
"""
|
||||
if 'power_range_dict_db' in si:
|
||||
return
|
||||
|
||||
if 'power_range_db' not in si:
|
||||
raise KeyError('power_range_db or power_range_dict_db missing in SI dict.')
|
||||
|
||||
power_range_db = si.get('power_range_db', [0, 0, 0])
|
||||
si['power_range_dict_db'] = convert_range_to_dict(power_range_db)
|
||||
del si['power_range_db']
|
||||
|
||||
|
||||
def convert_delta_power_range(json_data: Dict) -> Dict:
|
||||
"""Convert legacy json equipment format to GNPy yang format revision 2025-01-20
|
||||
|
||||
:param json_data: the input JSON data to convert.
|
||||
:type json_data: Dict
|
||||
:return: The converted JSON data.
|
||||
:rtype: Dict
|
||||
"""
|
||||
if 'Span' in json_data:
|
||||
for span in json_data['Span']:
|
||||
process_span_data(span)
|
||||
|
||||
if 'SI' in json_data:
|
||||
for si in json_data['SI']:
|
||||
process_si_data(si)
|
||||
|
||||
return json_data
|
||||
|
||||
|
||||
def convert_back_delta_power_range(json_data: Dict) -> Dict:
|
||||
"""Convert Yang JSON revision 2025-01-20 equipment format to legacy GNPy format.
|
||||
|
||||
:param json_data: the input JSON data to convert.
|
||||
:type json_data: Dict
|
||||
:return: The converted JSON data.
|
||||
:rtype: Dict
|
||||
"""
|
||||
if 'Span' in json_data and 'delta_power_range_dict_db' in json_data['Span'][0]:
|
||||
delta_power_range_db = json_data['Span'][0]['delta_power_range_dict_db']
|
||||
json_data['Span'][0]['delta_power_range_db'] = [
|
||||
delta_power_range_db['min_value'],
|
||||
delta_power_range_db['max_value'],
|
||||
delta_power_range_db['step']]
|
||||
del json_data['Span'][0]['delta_power_range_dict_db']
|
||||
if 'SI' in json_data and 'power_range_dict_db' in json_data['SI'][0]:
|
||||
power_range_db = json_data['SI'][0]['power_range_dict_db']
|
||||
json_data['SI'][0]['power_range_db'] = [
|
||||
power_range_db['min_value'],
|
||||
power_range_db['max_value'],
|
||||
power_range_db['step']]
|
||||
del json_data['SI'][0]['power_range_dict_db']
|
||||
return json_data
|
||||
|
||||
|
||||
def add_missing_default_type_variety(json_data: Dict) -> Dict:
|
||||
"""Case of ROADM: legacy does not enforce type_variety to be present.
|
||||
This utils ensures that 'default' type_variety is inserted if the key is missing.
|
||||
|
||||
:param json_data: the input JSON data to convert.
|
||||
:type json_data: Dict
|
||||
:return: The converted JSON data.
|
||||
:rtype: Dict
|
||||
"""
|
||||
if 'Roadm' not in json_data:
|
||||
return json_data
|
||||
for i, elem in enumerate(json_data['Roadm']):
|
||||
if 'type_variety' not in elem:
|
||||
# make sure type_variety is the first key in the elem
|
||||
temp = {'type_variety': 'default'}
|
||||
temp.update(elem)
|
||||
json_data['Roadm'][i] = temp
|
||||
break
|
||||
return json_data
|
||||
|
||||
|
||||
def remove_null_region_city(json_data: Dict) -> Dict:
|
||||
"""if present, name should not be None.
|
||||
|
||||
:param json_data: the input JSON data to convert.
|
||||
:type json_data: Dict
|
||||
:return: The converted JSON data.
|
||||
:rtype: Dict
|
||||
"""
|
||||
for elem in json_data[ELEMENTS_KEY]:
|
||||
if "metadata" in elem and "location" in elem[METADATA_KEY]:
|
||||
for name in ['city', 'region']:
|
||||
if name in elem[METADATA_KEY][LOCATION_KEY] \
|
||||
and elem[METADATA_KEY][LOCATION_KEY][name] is None:
|
||||
elem[METADATA_KEY][LOCATION_KEY][name] = ""
|
||||
return json_data
|
||||
|
||||
|
||||
def remove_union_that_fail(json_data: Dict) -> Dict:
|
||||
"""Convert GNPy legacy JSON request format to GNPy yang format revision 2025-01-20
|
||||
If present "N": or "M": should not contain empy data.
|
||||
If present max-nb-of-channel should not contain empty data.
|
||||
|
||||
:param json_data: the input JSON data to convert.
|
||||
:type json_data: Dict
|
||||
:return: The converted JSON data.
|
||||
:rtype: Dict
|
||||
"""
|
||||
for elem in json_data[PATH_REQUEST_KEY]:
|
||||
te = elem['path-constraints']['te-bandwidth']
|
||||
freq_slot = te.get('effective-freq-slot', None)
|
||||
if freq_slot:
|
||||
for slot in freq_slot:
|
||||
if slot.get('N', None) is None:
|
||||
slot.pop('N', None)
|
||||
if slot.get('M', None) is None:
|
||||
slot.pop('M', None)
|
||||
if not slot:
|
||||
te['effective-freq-slot'].remove(slot)
|
||||
if not te['effective-freq-slot']:
|
||||
te.pop('effective-freq-slot', None)
|
||||
for attribute in ['max-nb-of-channel', 'trx_mode', 'output-power']:
|
||||
if te.get(attribute) is None:
|
||||
te.pop(attribute, None)
|
||||
return json_data
|
||||
|
||||
|
||||
def convert_none_to_empty(json_data: Any):
|
||||
"""Convert all instances of None in the input to [None].
|
||||
|
||||
This function recursively traverses the input and replaces any None
|
||||
values with a list containing None. If the input is already a list
|
||||
containing None, it returns the input unchanged.
|
||||
|
||||
:param json_data: The input data to process, which can be of any type.
|
||||
:type json_data: Any
|
||||
:return: A new representation of the input with None values replaced by [None].
|
||||
:rtype: Any
|
||||
|
||||
:example:
|
||||
>>> a = {'uid': '[930/WRT-2-2-SIG=>923/WRT-1-9-SIG]-923/AMP-1-13', 'type_variety': 'AMP',
|
||||
... 'metadata': {'location': {'latitude': 0.0, 'longitude': 0.0, 'city': 'Zion', 'region': ''}},
|
||||
... 'type': 'Multiband_amplifier', 'amplifiers': [{'type_variety': 'AMP_LOW_C',
|
||||
... 'operational': {'gain_target': 12.22, 'delta_p': 4.19, 'out_voa': None, 'tilt_target': 0.0,
|
||||
... 'f_min': 191.3, 'f_max': 196.1}}, {'type_variety': 'AMP_LOW_L',
|
||||
... 'operational': {'gain_target': 12.05, 'delta_p': 4.19, 'out_voa': None, 'tilt_target': 0.0,
|
||||
... 'f_min': 186.1, 'f_max': 190.9}}]}
|
||||
>>> convert_none_to_empty(a)
|
||||
{'uid': '[930/WRT-2-2-SIG=>923/WRT-1-9-SIG]-923/AMP-1-13', 'type_variety': 'AMP', \
|
||||
'metadata': {'location': {'latitude': 0.0, 'longitude': 0.0, 'city': 'Zion', 'region': ''}}, \
|
||||
'type': 'Multiband_amplifier', 'amplifiers': [{'type_variety': 'AMP_LOW_C', \
|
||||
'operational': {'gain_target': 12.22, 'delta_p': 4.19, 'out_voa': [None], 'tilt_target': 0.0, \
|
||||
'f_min': 191.3, 'f_max': 196.1}}, {'type_variety': 'AMP_LOW_L', \
|
||||
'operational': {'gain_target': 12.05, 'delta_p': 4.19, 'out_voa': [None], 'tilt_target': 0.0, \
|
||||
'f_min': 186.1, 'f_max': 190.9}}]}
|
||||
|
||||
"""
|
||||
if json_data == [None]:
|
||||
# already conformed
|
||||
return json_data
|
||||
if isinstance(json_data, dict):
|
||||
for key, value in json_data.items():
|
||||
json_data[key] = convert_none_to_empty(value)
|
||||
elif isinstance(json_data, list):
|
||||
for i, elem in enumerate(json_data):
|
||||
json_data[i] = convert_none_to_empty(elem)
|
||||
elif json_data is None:
|
||||
return [None]
|
||||
return json_data
|
||||
|
||||
|
||||
def convert_empty_to_none(json_data: Any):
|
||||
"""Convert all instances of [None] in the input to None.
|
||||
|
||||
This function recursively traverses the input data and replaces any
|
||||
lists containing a single None element with None. If the input is
|
||||
already None, it returns None unchanged.
|
||||
|
||||
:param json_data: The input data to process, which can be of any type.
|
||||
:type json_data: Any
|
||||
:return: A new representation of the input with [None] replaced by None.
|
||||
:rtype: Any
|
||||
|
||||
>>> json_data = {
|
||||
... "uid": "[930/WRT-2-2-SIG=>923/WRT-1-9-SIG]-923/AMP-1-13",
|
||||
... "type_variety": "AMP",
|
||||
... "metadata": {
|
||||
... "location": {
|
||||
... "latitude": 0.000000,
|
||||
... "longitude": 0.000000,
|
||||
... "city": "Zion",
|
||||
... "region": ""
|
||||
... }
|
||||
... },
|
||||
... "type": "Multiband_amplifier",
|
||||
... "amplifiers": [{
|
||||
... "type_variety": "AMP_LOW_C",
|
||||
... "operational": {
|
||||
... "gain_target": 12.22,
|
||||
... "delta_p": 4.19,
|
||||
... "out_voa": [None],
|
||||
... "tilt_target": 0.00,
|
||||
... "f_min": 191.3,
|
||||
... "f_max": 196.1
|
||||
... }
|
||||
... }, {
|
||||
... "type_variety": "AMP_LOW_L",
|
||||
... "operational": {
|
||||
... "gain_target": 12.05,
|
||||
... "delta_p": 4.19,
|
||||
... "out_voa": [None],
|
||||
... "tilt_target": 0.00,
|
||||
... "f_min": 186.1,
|
||||
... "f_max": 190.9
|
||||
... }
|
||||
... }
|
||||
... ]
|
||||
... }
|
||||
>>> convert_empty_to_none(json_data)
|
||||
{'uid': '[930/WRT-2-2-SIG=>923/WRT-1-9-SIG]-923/AMP-1-13', 'type_variety': 'AMP', \
|
||||
'metadata': {'location': {'latitude': 0.0, 'longitude': 0.0, 'city': 'Zion', 'region': ''}}, \
|
||||
'type': 'Multiband_amplifier', 'amplifiers': [{'type_variety': 'AMP_LOW_C', \
|
||||
'operational': {'gain_target': 12.22, 'delta_p': 4.19, 'out_voa': None, 'tilt_target': 0.0, \
|
||||
'f_min': 191.3, 'f_max': 196.1}}, {'type_variety': 'AMP_LOW_L', \
|
||||
'operational': {'gain_target': 12.05, 'delta_p': 4.19, 'out_voa': None, 'tilt_target': 0.0, \
|
||||
'f_min': 186.1, 'f_max': 190.9}}]}
|
||||
|
||||
"""
|
||||
if isinstance(json_data, dict):
|
||||
for key, value in json_data.items():
|
||||
json_data[key] = convert_empty_to_none(value)
|
||||
elif isinstance(json_data, list):
|
||||
if len(json_data) == 1 and json_data[0] is None:
|
||||
return None
|
||||
for i, elem in enumerate(json_data):
|
||||
json_data[i] = convert_empty_to_none(elem)
|
||||
return json_data
|
||||
|
||||
|
||||
def remove_namespace_context(json_data: Union[Dict, List, float, int, str, bool, None], namespace: str) \
|
||||
-> Union[Dict, List, float, int, str, bool, None]:
|
||||
"""Serialisation with yang introduces a namespace in values that
|
||||
are defined as identity. this function filter them out.
|
||||
|
||||
:param json_data: The input JSON topology data to process.
|
||||
:type json_data: Union[Dict, List, float, int, str, bool, None]
|
||||
:param namespace: a namespace string
|
||||
:type namespace: str
|
||||
:return: the converted JSON data
|
||||
:rtype: Union[Dict, List, float, int, str, bool, None]
|
||||
|
||||
>>> a = [{"a": 123, "b": "123:alkdje"}, {"a": 456, "c": "123", "d": "123:123"}]
|
||||
>>> remove_namespace_context(a, "123:")
|
||||
[{'a': 123, 'b': 'alkdje'}, {'a': 456, 'c': '123', 'd': '123'}]
|
||||
|
||||
"""
|
||||
if isinstance(json_data, dict):
|
||||
for key, value in json_data.items():
|
||||
json_data[key] = remove_namespace_context(value, namespace)
|
||||
elif isinstance(json_data, list):
|
||||
for i, elem in enumerate(json_data):
|
||||
json_data[i] = remove_namespace_context(elem, namespace)
|
||||
elif isinstance(json_data, str) and namespace in json_data:
|
||||
return json_data.split(namespace)[1]
|
||||
return json_data
|
||||
|
||||
|
||||
def convert_nf_coef(json_data: Dict) -> Dict:
|
||||
"""Convert gnpy legacy format yang topology format.
|
||||
|
||||
:param json_data: The input JSON topology data to convert.
|
||||
:type json_data: Dict
|
||||
:return: the converted JSON data
|
||||
:rtype: dict
|
||||
"""
|
||||
if 'Edfa' not in json_data:
|
||||
return json_data
|
||||
for edfa in json_data['Edfa']:
|
||||
if 'nf_coef' in edfa and not isinstance(edfa['nf_coef'][0], dict):
|
||||
nf_coef = edfa.pop('nf_coef')
|
||||
new_nf_coef = [{'coef_order': i, 'nf_coef': c} for i, c in enumerate(nf_coef)]
|
||||
edfa['nf_coef'] = new_nf_coef
|
||||
return json_data
|
||||
|
||||
|
||||
def convert_back_nf_coef(json_data: Dict) -> Dict:
|
||||
"""Convert gnpy yang format back to legacy json topology format.
|
||||
|
||||
:param json_data: The input JSON topology data to convert back.
|
||||
:type json_data: Dict
|
||||
:return: the converted back JSON data
|
||||
:rtype: dict
|
||||
"""
|
||||
if 'Edfa' not in json_data:
|
||||
return json_data
|
||||
for edfa in json_data['Edfa']:
|
||||
if 'nf_coef' in edfa and isinstance(edfa['nf_coef'][0], dict):
|
||||
nf_coef = edfa.pop('nf_coef')
|
||||
sorted_nf_coef = sorted(nf_coef, key=lambda x: x['coef_order'])
|
||||
new_nf_coef = [c['nf_coef'] for c in sorted_nf_coef]
|
||||
edfa['nf_coef'] = new_nf_coef
|
||||
return json_data
|
||||
|
||||
|
||||
def convert_nf_fit_coef(json_data: Dict) -> Dict:
|
||||
"""Convert gnpy legacy format yang topology format.
|
||||
|
||||
:param json_data: The input JSON topology data to convert.
|
||||
:type json_data: Dict
|
||||
:return: the converted JSON data
|
||||
:rtype: dict
|
||||
"""
|
||||
if 'nf_fit_coeff' in json_data and not isinstance(json_data['nf_fit_coeff'][0], dict):
|
||||
nf_coef = json_data.pop('nf_fit_coeff')
|
||||
new_nf_coef = [{'coef_order': i, 'nf_coef': c} for i, c in enumerate(nf_coef)]
|
||||
json_data['nf_fit_coeff'] = new_nf_coef
|
||||
return json_data
|
||||
|
||||
|
||||
def convert_back_nf_fit_coef(json_data: Dict) -> Dict:
|
||||
"""Convert gnpy yang format back to legacy json topology format.
|
||||
|
||||
:param json_data: The input JSON topology data to convert back.
|
||||
:type json_data: Dict
|
||||
:return: the converted back JSON data
|
||||
:rtype: dict
|
||||
"""
|
||||
if 'nf_fit_coeff' in json_data and isinstance(json_data['nf_fit_coeff'][0], dict):
|
||||
nf_coef = json_data.pop('nf_fit_coeff')
|
||||
sorted_nf_coef = sorted(nf_coef, key=lambda x: x['coef_order'])
|
||||
new_nf_coef = [c['nf_coef'] for c in sorted_nf_coef]
|
||||
json_data['nf_fit_coeff'] = new_nf_coef
|
||||
return json_data
|
||||
|
||||
|
||||
def convert_raman_coef(json_data: Dict) -> Dict:
|
||||
"""Convert gnpy legacy format yang topology format.
|
||||
|
||||
:param json_data: The input JSON topology data to convert.
|
||||
:type json_data: Dict
|
||||
:return: the converted JSON data
|
||||
:rtype: dict
|
||||
"""
|
||||
for elem in json_data[ELEMENTS_KEY]:
|
||||
if PARAMS_KEY in elem and RAMAN_COEF_KEY in elem[PARAMS_KEY] \
|
||||
and 'g0' in elem[PARAMS_KEY][RAMAN_COEF_KEY]:
|
||||
raman_coef = elem[PARAMS_KEY].pop(RAMAN_COEF_KEY)
|
||||
g0_list = raman_coef.pop('g0', [])
|
||||
frequency_offset_list = raman_coef.pop('frequency_offset', [])
|
||||
if frequency_offset_list:
|
||||
new_raman_coef = {'reference_frequency': raman_coef['reference_frequency'],
|
||||
'g0_per_frequency': [{'frequency_offset': f, 'g0': v}
|
||||
for f, v in zip(frequency_offset_list, g0_list)]}
|
||||
elem[PARAMS_KEY][RAMAN_COEF_KEY] = new_raman_coef
|
||||
return json_data
|
||||
|
||||
|
||||
def convert_back_raman_coef(json_data: Dict) -> Dict:
|
||||
"""Convert gnpy yang format back to legacy json topology format.
|
||||
|
||||
:param json_data: The input JSON topology data to convert back.
|
||||
:type json_data: Dict
|
||||
:return: the converted back JSON data
|
||||
:rtype: dict
|
||||
"""
|
||||
for elem in json_data[ELEMENTS_KEY]:
|
||||
if PARAMS_KEY in elem and RAMAN_COEF_KEY in elem[PARAMS_KEY] \
|
||||
and 'g0_per_frequency' in elem[PARAMS_KEY][RAMAN_COEF_KEY]:
|
||||
raman_coef = elem[PARAMS_KEY].pop(RAMAN_COEF_KEY)
|
||||
g0_list = [g['g0'] for g in raman_coef.pop('g0_per_frequency', [])]
|
||||
frequency_offset_list = [f['frequency_offset'] for f in raman_coef.pop('g0_per_frequency', [])]
|
||||
if frequency_offset_list:
|
||||
new_raman_coef = {'reference_frequency': raman_coef['reference_frequency'],
|
||||
'g0': g0_list,
|
||||
'frequency_offset': frequency_offset_list}
|
||||
elem[PARAMS_KEY][RAMAN_COEF_KEY] = new_raman_coef
|
||||
return json_data
|
||||
|
||||
|
||||
def convert_raman_efficiency(json_data: Dict) -> Dict:
|
||||
"""Convert gnpy legacy format yang topology format.
|
||||
|
||||
:param json_data: The input JSON topology data to convert.
|
||||
:type json_data: Dict
|
||||
:return: the converted JSON data
|
||||
:rtype: dict
|
||||
"""
|
||||
if 'RamanFiber' not in json_data:
|
||||
return json_data
|
||||
for fiber_eqpt in json_data['RamanFiber']:
|
||||
if RAMAN_EFFICIENCY_KEY in fiber_eqpt \
|
||||
and 'cr' in fiber_eqpt[RAMAN_EFFICIENCY_KEY]:
|
||||
raman_efficiency = fiber_eqpt.pop(RAMAN_EFFICIENCY_KEY)
|
||||
cr_list = raman_efficiency.pop('cr', [])
|
||||
frequency_offset_list = raman_efficiency.pop('frequency_offset', [])
|
||||
if frequency_offset_list:
|
||||
new_raman_efficiency = [{'frequency_offset': f, 'cr': v}
|
||||
for f, v in zip(frequency_offset_list, cr_list)]
|
||||
fiber_eqpt[RAMAN_EFFICIENCY_KEY] = new_raman_efficiency
|
||||
return json_data
|
||||
|
||||
|
||||
def convert_back_raman_efficiency(json_data: Dict) -> Dict:
|
||||
"""Convert gnpy yang format back to legacy json topology format.
|
||||
|
||||
:param json_data: The input JSON topology data to convert back.
|
||||
:type json_data: Dict
|
||||
:return: the converted back JSON data
|
||||
:rtype: dict
|
||||
"""
|
||||
if 'RamanFiber' not in json_data:
|
||||
return json_data
|
||||
for fiber_eqpt in json_data['RamanFiber']:
|
||||
if RAMAN_EFFICIENCY_KEY in fiber_eqpt and isinstance(fiber_eqpt[RAMAN_EFFICIENCY_KEY], list):
|
||||
raman_efficiency = fiber_eqpt.pop(RAMAN_EFFICIENCY_KEY)
|
||||
cr_list = [c['cr'] for c in raman_efficiency]
|
||||
frequency_offset_list = [f['frequency_offset'] for f in raman_efficiency]
|
||||
if frequency_offset_list:
|
||||
old_raman_efficiency = {'cr': cr_list,
|
||||
'frequency_offset': frequency_offset_list}
|
||||
fiber_eqpt[RAMAN_COEF_KEY] = old_raman_efficiency
|
||||
return json_data
|
||||
|
||||
|
||||
def reorder_keys(data_list: List, key: str) -> List:
|
||||
"""Roarder item in a dict placing the key (the key of a list with YANG meaning) first.
|
||||
This is required because oopt-gnpy-libyang does not recognize the key when it is not placed first in the data node.
|
||||
|
||||
:param json_data: the list of dictionary items.
|
||||
:type data_list: List
|
||||
:return: the converted back JSON data
|
||||
:rtype: List
|
||||
"""
|
||||
for item in data_list:
|
||||
index_value = item.pop(key, None)
|
||||
if index_value is not None:
|
||||
# Place key first
|
||||
new_item = {key: index_value}
|
||||
# add other items
|
||||
new_item.update(item)
|
||||
# replace old element with new element
|
||||
for k in list(item.keys()):
|
||||
item.pop(k)
|
||||
item.update(new_item)
|
||||
return data_list
|
||||
|
||||
|
||||
# next functions because ly requires that the key of a list be in the first position in the item
|
||||
def reorder_route_objects(json_data: Dict) -> Dict:
|
||||
"""Make sure that the index of a route object is placed first in the object.
|
||||
|
||||
:param json_data: The input JSON topology data to convert.
|
||||
:type json_data: Dict
|
||||
:return: the converted JSON data
|
||||
:rtype: dict
|
||||
"""
|
||||
for request in json_data['path-request']:
|
||||
if "explicit-route-objects" in request:
|
||||
request["explicit-route-objects"]["route-object-include-exclude"] = \
|
||||
reorder_keys(request["explicit-route-objects"]["route-object-include-exclude"], "index")
|
||||
return json_data
|
||||
|
||||
|
||||
def reorder_lumped_losses_objects(json_data: Dict) -> Dict:
|
||||
"""Make sure that the position of a lumped loss object is placed first in the object.
|
||||
|
||||
:param json_data: The input JSON topology data to convert.
|
||||
:type json_data: Dict
|
||||
:return: the converted JSON data
|
||||
:rtype: dict
|
||||
"""
|
||||
for element in json_data['elements']:
|
||||
if "params" in element and "lumped_losses" in element["params"]:
|
||||
element["params"]["lumped_losses"] = reorder_keys(element["params"]["lumped_losses"], "position")
|
||||
return json_data
|
||||
|
||||
|
||||
def reorder_raman_pumps(json_data: Dict) -> Dict:
|
||||
"""Make sure that the frequency of a Raman pum object is placed first in the object.
|
||||
|
||||
:param json_data: The input JSON topology data to convert.
|
||||
:type json_data: Dict
|
||||
:return: the converted JSON data
|
||||
:rtype: dict
|
||||
"""
|
||||
for element in json_data['elements']:
|
||||
if "operational" in element and "raman_pumps" in element["operational"]:
|
||||
element["operational"]["raman_pumps"] = reorder_keys(element["operational"]["raman_pumps"], "frequency")
|
||||
return json_data
|
||||
293
gnpy/yang/precision_dict.py
Normal file
293
gnpy/yang/precision_dict.py
Normal file
@@ -0,0 +1,293 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# precision of fraction digits collected in yang models
|
||||
# Copyright (C) 2025 Telecom Infra Project and GNPy contributors
|
||||
# see AUTHORS.rst for a list of contributors
|
||||
|
||||
PRECISION_DICT = {
|
||||
"contact": -1, "date": -1, "description": -1, "module": -1, "organization": -1,
|
||||
"f_min": 1,
|
||||
"f_max": 1,
|
||||
"length": 6,
|
||||
"loss_coef": 6,
|
||||
"pmd_coef": 18,
|
||||
"frequency": 1,
|
||||
"freq": 2, "ref_frequency": 1, "ref_wavelength": 12,
|
||||
"g0": 14, "loss_coef_value": 16, "position": 6, "reference_frequency": 1,
|
||||
"att_in": 2,
|
||||
"con_in": 2,
|
||||
"con_out": 2,
|
||||
"temperature": 2,
|
||||
"power": 9,
|
||||
"gain_target": 6,
|
||||
"tilt_target": 6,
|
||||
"out_voa": 2,
|
||||
"in_voa": 2,
|
||||
"delta_p": 6,
|
||||
"spacing": 2,
|
||||
"target_pch_out_db": 2,
|
||||
"target_psd_out_mWperGHz": 10,
|
||||
"target_out_mWperSlotWidth": 10,
|
||||
"per_degree_pch_out_db": 2,
|
||||
"per_degree_psd_out_mWperGHz": 10,
|
||||
"per_degree_psd_out_mWperSlotWidth": 10,
|
||||
"number-of-channels": 0,
|
||||
"loss": 2,
|
||||
"city": -1,
|
||||
"region": -1,
|
||||
"latitude": 6,
|
||||
"longitude": 6,
|
||||
"length_units": -1,
|
||||
"propagation_direction": -1,
|
||||
"type_variety": -1,
|
||||
"degree_uid": -1,
|
||||
"preamp_variety_list": -1,
|
||||
"booster_variety_list": -1,
|
||||
"from_degree": -1,
|
||||
"to_degree": -1,
|
||||
"impairment_id": 0,
|
||||
"variety_list": -1,
|
||||
"uid": -1,
|
||||
"type": -1,
|
||||
"from_node": -1,
|
||||
"to_node": -1,
|
||||
"network_name": -1,
|
||||
"output-power": 8,
|
||||
"tx_power": 5,
|
||||
"path_bandwidth": 1,
|
||||
"accumulative-value": 8,
|
||||
"N": 0,
|
||||
"M": 0,
|
||||
"trx_mode": -1,
|
||||
"max-nb-of-channel": 0,
|
||||
"technology": -1,
|
||||
"trx_type": -1,
|
||||
"transponder-type": -1,
|
||||
"transponder-mode": -1,
|
||||
"explicit-route-usage": -1,
|
||||
"disjointness": -1,
|
||||
"index": 0,
|
||||
"node-id": -1,
|
||||
"link-tp-id": -1,
|
||||
"hop-type": -1,
|
||||
"source": -1,
|
||||
"destination": -1,
|
||||
"src-tp-id": -1,
|
||||
"dst-tp-id": -1,
|
||||
"synchronization-id": -1,
|
||||
"relaxable": -1,
|
||||
"request-id-number": -1,
|
||||
"request-id": -1,
|
||||
"bidirectional": -1,
|
||||
"metric-type": -1,
|
||||
"response-id": -1,
|
||||
"no-path": -1,
|
||||
"result_spatial_resolution": 3,
|
||||
"solver_spatial_resolution": 3,
|
||||
"dispersion_tolerance": 1,
|
||||
"phase_shift_tolerance": 1,
|
||||
"flag": -1,
|
||||
"order": 0,
|
||||
"method": -1,
|
||||
"computed_channels": 0,
|
||||
"computed_number_of_channels": 0,
|
||||
"nf_min": 2,
|
||||
"nf_max": 2,
|
||||
"nf0": 2,
|
||||
"nf_coef": 10,
|
||||
"coef_order": 0,
|
||||
"gain_flatmax": 2,
|
||||
"gain_min": 2,
|
||||
"extended_gain_range": 2,
|
||||
"p_max": 2,
|
||||
"dispersion": 8,
|
||||
'dispersion_slope': 11,
|
||||
"gamma": 8,
|
||||
"effective_area": 14,
|
||||
"min_value": 2,
|
||||
"max_value": 2,
|
||||
"step": 2,
|
||||
"lower-frequency": 2,
|
||||
"upper-frequency": 2,
|
||||
"cr": 9,
|
||||
"frequency_offset": 2,
|
||||
"max_length": 2,
|
||||
"max_loss": 2,
|
||||
"max_fiber_lineic_loss_for_raman": 2,
|
||||
"target_extended_gain": 2,
|
||||
"padding": 2,
|
||||
"EOL": 2,
|
||||
"span_loss_ref": 2,
|
||||
"power_slope": 2,
|
||||
"voa_margin": 2,
|
||||
"voa_step": 2,
|
||||
"add_drop_osnr": 2,
|
||||
"pmd": 15,
|
||||
"pdl": 2,
|
||||
"baud_rate": 2,
|
||||
"power_dbm": 2,
|
||||
"roll_off": 2,
|
||||
"tx_osnr": 2,
|
||||
"tx_power_dbm": 2,
|
||||
"sys_margins": 2,
|
||||
"min": 2,
|
||||
"max": 2,
|
||||
"OSNR": 2,
|
||||
"min_spacing": 2,
|
||||
"bit_rate": 2,
|
||||
"cost": 2,
|
||||
"chromatic_dispersion": 2,
|
||||
"penalty_value": 2,
|
||||
"equalization_offset_db": 4,
|
||||
"preamp_variety": -1,
|
||||
"booster_variety": -1,
|
||||
"amplifiers": -1,
|
||||
"advanced_config_from_json": -1,
|
||||
"default_config_from_json": -1,
|
||||
"allowed_for_design": -1,
|
||||
"type_def": -1,
|
||||
"raman": -1,
|
||||
"out_voa_auto": -1,
|
||||
"in_voa_auto": -1,
|
||||
"other_name": -1,
|
||||
"power_mode": -1,
|
||||
"roadm-path-impairments-id": 0,
|
||||
"use_si_channel_count_for_design": -1,
|
||||
"comment": -1,
|
||||
"format": -1,
|
||||
"roadm-osnr": 2,
|
||||
"nf_ripple": 18,
|
||||
"dgt": 18,
|
||||
"gain_ripple": 18,
|
||||
"slot_width": 2,
|
||||
"delta_pdb": 2,
|
||||
"label": -1,
|
||||
"roadm-pmd": 8,
|
||||
"otsi-carrier-frequency": 9,
|
||||
"oms-element-uid": -1,
|
||||
"configured-mode": -1,
|
||||
"type-variety": -1,
|
||||
"frequency-range-id": 0,
|
||||
"stage-order": 0,
|
||||
"name": -1,
|
||||
"nominal-carrier-power": 2,
|
||||
"nominal-psd": 16,
|
||||
"actual-gain": 2,
|
||||
"in-voa": 2,
|
||||
"out-voa": 2,
|
||||
"tilt-target": 2,
|
||||
"total-output-power": 2,
|
||||
"raman-direction": -1,
|
||||
"pump-id": 0,
|
||||
"delta-power": 2,
|
||||
"loss-coef": 2,
|
||||
"total-loss": 2,
|
||||
"conn-in": 2,
|
||||
"conn-out": 2,
|
||||
"roadm-cd": 5,
|
||||
"roadm-pdl": 2,
|
||||
"roadm-inband-crosstalk": 2,
|
||||
"roadm-maxloss": 2,
|
||||
"roadm-pmax": 2,
|
||||
"roadm-noise-figure": 5,
|
||||
"roadm-minloss": 2,
|
||||
"roadm-typloss": 2,
|
||||
"roadm-pmin": 2,
|
||||
"roadm-ptyp": 2,
|
||||
"generalized-snr": 2,
|
||||
"equalization-mode": -1,
|
||||
"otsi-carrier-id": 0,
|
||||
"e2e-mc-path-id": 0,
|
||||
"otsi-group-ref": -1,
|
||||
"media-channel-id": 0,
|
||||
"otsi-carrier-ref": -1,
|
||||
"e2e-mc-path-ref": -1,
|
||||
"elt-index": 0,
|
||||
"link-ref": -1,
|
||||
"oms-element-ref": -1,
|
||||
"otsi-ref": -1,
|
||||
"otsi-group-id": -1,
|
||||
"explicit-transceiver-mode-id": -1,
|
||||
"transponder-id": 0,
|
||||
"termination-type-capabilities": -1,
|
||||
"transceiver-id": 0,
|
||||
"explicit-transceiver-mode-ref": -1,
|
||||
"configured-termination-type": -1,
|
||||
"group-id": 0,
|
||||
"regen-metric": 0,
|
||||
"transponder-ref": -1,
|
||||
"transceiver-ref": -1,
|
||||
"protection-type": -1,
|
||||
"inter-layer-sequence-number": 0,
|
||||
"roadm-path-impairments": -1,
|
||||
"ltp-ref": -1,
|
||||
"add-path-impairments": -1,
|
||||
"drop-path-impairments": -1,
|
||||
"ttp-transponder-ref": -1,
|
||||
"ttp-transceiver-ref": -1,
|
||||
"is-allowed": -1,
|
||||
"penalty-value": 2,
|
||||
"max-chromatic-dispersion": 2,
|
||||
"cd-value": 2,
|
||||
"max-polarization-mode-dispersion": 2,
|
||||
"pmd-value": 2,
|
||||
"available-baud-rate": 1,
|
||||
"roll-off": 4,
|
||||
"fec-code-rate": 8,
|
||||
"fec-threshold": 8,
|
||||
"polarization-skew": 2,
|
||||
"dwdm-n": -1,
|
||||
"cwdm-n": -1,
|
||||
"wson-dwdm-channel-spacing": -1,
|
||||
"wson-cwdm-channel-spacing": -1,
|
||||
"subcarrier-dwdm-n": 0,
|
||||
"slot-width-granularity": -1,
|
||||
"min-slot-width-factor": 0,
|
||||
"max-slot-width-factor": 0,
|
||||
"grid-type": -1,
|
||||
"priority": 0,
|
||||
"flexi-n": 0,
|
||||
"flexi-m": 0,
|
||||
"flexi-grid-channel-spacing": -1,
|
||||
"flexi-ncfg": -1,
|
||||
"flexi-n-step": 0,
|
||||
"mode-id": -1,
|
||||
"supported-application-codes": -1,
|
||||
"supported-organizational-modes": -1,
|
||||
"standard-mode": -1,
|
||||
"operational-mode": -1,
|
||||
"organization-identifier": -1,
|
||||
"line-coding-bitrate": -1,
|
||||
"bitrate": 0,
|
||||
"max-diff-group-delay": 2,
|
||||
"max-polarization-dependant-loss": 2,
|
||||
"pdl-value": 2,
|
||||
"available-modulation-type": -1,
|
||||
"min-OSNR": 2,
|
||||
"rx-ref-channel-power": 2,
|
||||
"rx-channel-power-value": 2,
|
||||
"min-Q-factor": 2,
|
||||
"min-carrier-spacing": 6,
|
||||
"available-fec-type": -1,
|
||||
"in-band-osnr": 2,
|
||||
"out-of-band-osnr": 2,
|
||||
"tx-polarization-power-difference": 2,
|
||||
"min-central-frequency": 9,
|
||||
"max-central-frequency": 9,
|
||||
"transceiver-tunability": 6,
|
||||
"tx-channel-power-min": 2,
|
||||
"tx-channel-power-max": 2,
|
||||
"rx-channel-power-min": 2,
|
||||
"rx-channel-power-max": 2,
|
||||
"rx-total-power-max": 2,
|
||||
"tx-channel-power": 2,
|
||||
"rx-channel-power": 2,
|
||||
"rx-total-power": 2,
|
||||
"wavelength-assignment": -1,
|
||||
"gsnr-extra-margin": 2,
|
||||
"estimated-gsnr": 2,
|
||||
"estimated-eol-gsnr": 2,
|
||||
"estimated-lowest-gsnr": 2
|
||||
}
|
||||
61
gnpy/yang/yang-library-gnpy.json
Normal file
61
gnpy/yang/yang-library-gnpy.json
Normal file
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"ietf-yang-library:modules-state": {
|
||||
"module-set-id": "gnpy-library",
|
||||
"module": [
|
||||
{
|
||||
"name": "gnpy-network-topology",
|
||||
"namespace": "gnpy:gnpy-network-topology",
|
||||
"revision": "2025-03-01",
|
||||
"conformance-type": "implement"
|
||||
},
|
||||
{
|
||||
"name": "gnpy-path-computation",
|
||||
"namespace": "gnpy:gnpy-path-computation",
|
||||
"revision": "2025-01-20",
|
||||
"conformance-type": "implement"
|
||||
},
|
||||
{
|
||||
"name": "gnpy-sim-params",
|
||||
"namespace": "gnpy:gnpy-sim-params",
|
||||
"revision": "2025-04-10",
|
||||
"conformance-type": "implement"
|
||||
},
|
||||
{
|
||||
"name": "gnpy-eqpt-config",
|
||||
"namespace": "gnpy:gnpy-eqpt",
|
||||
"revision": "2025-05-26",
|
||||
"conformance-type": "implement"
|
||||
},
|
||||
{
|
||||
"name": "gnpy-edfa-config",
|
||||
"namespace": "gnpy:gnpy-edfa-config",
|
||||
"revision": "2025-04-10",
|
||||
"conformance-type": "implement"
|
||||
},
|
||||
{
|
||||
"name": "gnpy-sim-params",
|
||||
"namespace": "gnpy:gnpy-sim-params",
|
||||
"revision": "2025-04-10",
|
||||
"conformance-type": "implement"
|
||||
},
|
||||
{
|
||||
"name": "gnpy-spectrum",
|
||||
"namespace": "gnpy:gnpy-spectrum",
|
||||
"revision": "2025-04-10",
|
||||
"conformance-type": "implement"
|
||||
},
|
||||
{
|
||||
"name": "ietf-optical-impairment-topology",
|
||||
"namespace": "urn:ietf:params:xml:ns:yang:ietf-optical-impairment-topology",
|
||||
"revision": "2024-05-21",
|
||||
"conformance-type": "implement"
|
||||
},
|
||||
{
|
||||
"name": "ietf-layer0-types",
|
||||
"namespace": "urn:ietf:params:xml:ns:yang:ietf-layer0-types",
|
||||
"revision": "2024-03-04",
|
||||
"conformance-type": "implement"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -58,6 +58,7 @@ install_requires =
|
||||
networkx>=3.1,<4
|
||||
# numpy 1.25 removed support for Python 3.8
|
||||
numpy>=1.24.4,<2
|
||||
oopt_gnpy_libyang>=0.0.14
|
||||
pbr>=6.0.0,<7
|
||||
# scipy 1.11 removed support for Python 3.8
|
||||
scipy>=1.10.1,<2
|
||||
|
||||
3820
tests/data/convert/GNPy_api_example.json
Normal file
3820
tests/data/convert/GNPy_api_example.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,81 @@
|
||||
{
|
||||
"network_name": "EDFA Example Network - P2P",
|
||||
"elements": [
|
||||
{
|
||||
"uid": "Site_A",
|
||||
"type": "Transceiver",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Site A",
|
||||
"region": "",
|
||||
"latitude": 0.0,
|
||||
"longitude": 0.0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span1",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80.0,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km",
|
||||
"att_in": 0.0,
|
||||
"con_in": 0.5,
|
||||
"con_out": 0.5,
|
||||
"pmd_coef": 3.0e-15
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1.0,
|
||||
"longitude": 0.0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa1",
|
||||
"type": "Edfa",
|
||||
"type_variety": "std_low_gain",
|
||||
"operational": {
|
||||
"gain_target": 17.0,
|
||||
"tilt_target": 0.0,
|
||||
"out_voa": 0.0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2.0,
|
||||
"longitude": 0.0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Site_B",
|
||||
"type": "Transceiver",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Site B",
|
||||
"region": "",
|
||||
"latitude": 2.0,
|
||||
"longitude": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"from_node": "Site_A",
|
||||
"to_node": "Span1"
|
||||
},
|
||||
{
|
||||
"from_node": "Span1",
|
||||
"to_node": "Edfa1"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa1",
|
||||
"to_node": "Site_B"
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
318
tests/data/convert/GNPy_yang_formatted-edfa-config_expected.json
Normal file
318
tests/data/convert/GNPy_yang_formatted-edfa-config_expected.json
Normal file
@@ -0,0 +1,318 @@
|
||||
{
|
||||
"gnpy-edfa-config:edfa-config": {
|
||||
"f_min": "191275000000000.0",
|
||||
"f_max": "196125000000000.0",
|
||||
"nf_fit_coeff": [
|
||||
{
|
||||
"coef_order": 0,
|
||||
"nf_coef": "0.000168241"
|
||||
},
|
||||
{
|
||||
"coef_order": 1,
|
||||
"nf_coef": "0.0469961"
|
||||
},
|
||||
{
|
||||
"coef_order": 2,
|
||||
"nf_coef": "0.0359549"
|
||||
},
|
||||
{
|
||||
"coef_order": 3,
|
||||
"nf_coef": "5.82851"
|
||||
}
|
||||
],
|
||||
"nf_ripple": [
|
||||
"-0.3110761646066259",
|
||||
"-0.3110761646066259",
|
||||
"-0.31110274831665313",
|
||||
"-0.31419329378173544",
|
||||
"-0.3172854168606314",
|
||||
"-0.32037911876162584",
|
||||
"-0.3233255190215882",
|
||||
"-0.31624321721895354",
|
||||
"-0.30915729645781326",
|
||||
"-0.30206775396360075",
|
||||
"-0.2949045115165272",
|
||||
"-0.26632156113294336",
|
||||
"-0.23772399031437283",
|
||||
"-0.20911178784023846",
|
||||
"-0.18048410390821285",
|
||||
"-0.14379944379052215",
|
||||
"-0.10709599992470213",
|
||||
"-0.07037375788020579",
|
||||
"-0.03372858157230583",
|
||||
"-0.015660302006048",
|
||||
"0.0024172385953583",
|
||||
"0.020504047353947653",
|
||||
"0.03860013139908377",
|
||||
"0.05670549786742816",
|
||||
"0.07482015390297145",
|
||||
"0.0838762040768461",
|
||||
"0.09284481475528361",
|
||||
"0.1018180306253394",
|
||||
"0.11079585523492333",
|
||||
"0.1020395478432815",
|
||||
"0.09310160456603413",
|
||||
"0.08415906712621996",
|
||||
"0.07521193198077789",
|
||||
"0.0676340601339394",
|
||||
"0.06005437964543287",
|
||||
"0.052470799141237305",
|
||||
"0.044883315610536455",
|
||||
"0.037679759069084225",
|
||||
"0.03047647598902483",
|
||||
"0.02326948274513522",
|
||||
"0.01605877647020772",
|
||||
"0.021248462316134083",
|
||||
"0.02657315875107553",
|
||||
"0.03190060058247842",
|
||||
"0.03723078993416436",
|
||||
"0.04256372893215024",
|
||||
"0.047899419704645264",
|
||||
"0.03915515813685565",
|
||||
"0.030289222542492025",
|
||||
"0.021418708618354456",
|
||||
"0.012573926129294415",
|
||||
"0.006240488799898697",
|
||||
"-0.000096221623730266",
|
||||
"-0.006436207679519103",
|
||||
"-0.012779471908040341",
|
||||
"-0.02038153550619876",
|
||||
"-0.027999803010447587",
|
||||
"-0.035622012697103154",
|
||||
"-0.043236398934156144",
|
||||
"-0.04493583574805963",
|
||||
"-0.04663615264317309",
|
||||
"-0.048337350303318156",
|
||||
"-0.050039429413028365",
|
||||
"-0.051742390657545205",
|
||||
"-0.05342028484370278",
|
||||
"-0.05254242298580185",
|
||||
"-0.05166410580536087",
|
||||
"-0.05078533294804249",
|
||||
"-0.04990610405914272",
|
||||
"-0.05409792133358102",
|
||||
"-0.05832916277634124",
|
||||
"-0.06256260169582961",
|
||||
"-0.06660356886269536",
|
||||
"-0.04779792991567815",
|
||||
"-0.028982516728038848",
|
||||
"-0.010157321677553965",
|
||||
"0.00861320615127981",
|
||||
"0.01913736978785662",
|
||||
"0.029667009055877668",
|
||||
"0.04020212822983975",
|
||||
"0.050742731588695494",
|
||||
"0.061288823415841555",
|
||||
"0.07184040799914815",
|
||||
"0.1043252636301016",
|
||||
"0.13687829834471027",
|
||||
"0.1694483010211072",
|
||||
"0.202035284929368",
|
||||
"0.23624619427167134",
|
||||
"0.27048596623174515",
|
||||
"0.30474360397422756",
|
||||
"0.3390191214858807",
|
||||
"0.36358851509924695",
|
||||
"0.38814205928193013",
|
||||
"0.41270842850729195",
|
||||
"0.4372876328262819",
|
||||
"0.4372876328262819"
|
||||
],
|
||||
"dgt": [
|
||||
"2.714526681131686",
|
||||
"2.705443819238505",
|
||||
"2.6947834587664494",
|
||||
"2.6841217449620203",
|
||||
"2.6681935771243177",
|
||||
"2.6521732021128046",
|
||||
"2.630396440815385",
|
||||
"2.602860350286428",
|
||||
"2.5696460593920065",
|
||||
"2.5364027376452056",
|
||||
"2.499446286796604",
|
||||
"2.4587748041127506",
|
||||
"2.414398437185221",
|
||||
"2.3699990328716107",
|
||||
"2.322373696229342",
|
||||
"2.271520771371253",
|
||||
"2.2174389328192197",
|
||||
"2.16337565384239",
|
||||
"2.1183028432496016",
|
||||
"2.082225099873648",
|
||||
"2.055100772005235",
|
||||
"2.0279625371819305",
|
||||
"2.0008103857988204",
|
||||
"1.9736443063300082",
|
||||
"1.9482128147680253",
|
||||
"1.9245345552113182",
|
||||
"1.9026104247588487",
|
||||
"1.8806927939516411",
|
||||
"1.862235672444246",
|
||||
"1.847275503201129",
|
||||
"1.835814081380705",
|
||||
"1.824381436842932",
|
||||
"1.8139629377087627",
|
||||
"1.8045606557581335",
|
||||
"1.7961751115773796",
|
||||
"1.7877868031023945",
|
||||
"1.7793941781790852",
|
||||
"1.7709972329654864",
|
||||
"1.7625959636196327",
|
||||
"1.7541903672600494",
|
||||
"1.7459181197626403",
|
||||
"1.737780757913635",
|
||||
"1.7297783508684146",
|
||||
"1.7217732861435076",
|
||||
"1.7137640932265894",
|
||||
"1.7057507692361864",
|
||||
"1.6918150918099673",
|
||||
"1.6719047669939942",
|
||||
"1.6460167077689267",
|
||||
"1.6201194134191075",
|
||||
"1.5986915141218316",
|
||||
"1.5817353179379183",
|
||||
"1.569199764184379",
|
||||
"1.5566577309558969",
|
||||
"1.545374152761467",
|
||||
"1.5353620432989845",
|
||||
"1.5266220576235803",
|
||||
"1.5178910621476225",
|
||||
"1.5097346239790443",
|
||||
"1.502153039909686",
|
||||
"1.495145456062699",
|
||||
"1.488134243479226",
|
||||
"1.48111939735681",
|
||||
"1.474100442252211",
|
||||
"1.4670307626366115",
|
||||
"1.4599103316162523",
|
||||
"1.45273959485914",
|
||||
"1.445565137158368",
|
||||
"1.4340878115214444",
|
||||
"1.418273806730323",
|
||||
"1.3981208704326855",
|
||||
"1.3779439775587023",
|
||||
"1.3598972673004606",
|
||||
"1.3439818461440451",
|
||||
"1.3301807335621048",
|
||||
"1.316383926863083",
|
||||
"1.3040618749785347",
|
||||
"1.2932153453410835",
|
||||
"1.2838336236692311",
|
||||
"1.2744470198196236",
|
||||
"1.2650555289898042",
|
||||
"1.2556591482982988",
|
||||
"1.2428104897182262",
|
||||
"1.2264996957264114",
|
||||
"1.2067249615595257",
|
||||
"1.1869318618366975",
|
||||
"1.1672278304018044",
|
||||
"1.1476135933863398",
|
||||
"1.1280891949729075",
|
||||
"1.108555289615659",
|
||||
"1.0895983485572227",
|
||||
"1.0712204022764056",
|
||||
"1.0534217504465226",
|
||||
"1.0356155337864215",
|
||||
"1.017807767853702",
|
||||
"1.0"
|
||||
],
|
||||
"gain_ripple": [
|
||||
"0.1359703369791596",
|
||||
"0.11822862697916037",
|
||||
"0.09542181697916163",
|
||||
"0.06245819697916133",
|
||||
"0.02602813697916062",
|
||||
"-0.003619983020840322",
|
||||
"-0.018326963020840026",
|
||||
"-0.0246928330208398",
|
||||
"-0.016792253020838643",
|
||||
"-0.002813863020840301",
|
||||
"0.017572956979162058",
|
||||
"0.038328296979159404",
|
||||
"0.054956336979159914",
|
||||
"0.0670723869791594",
|
||||
"0.07091459697916136",
|
||||
"0.07094413697916124",
|
||||
"0.07114372697916238",
|
||||
"0.07533675697916209",
|
||||
"0.08731066697916035",
|
||||
"0.10313984697916112",
|
||||
"0.12276252697916235",
|
||||
"0.14239527697916188",
|
||||
"0.15945681697916214",
|
||||
"0.1739275269791598",
|
||||
"0.1767381569791624",
|
||||
"0.17037189697916233",
|
||||
"0.15216302697916007",
|
||||
"0.13114358697916018",
|
||||
"0.10802383697916085",
|
||||
"0.08548825697916129",
|
||||
"0.06916723697916183",
|
||||
"0.05848224697916038",
|
||||
"0.05447361697916264",
|
||||
"0.05154489697916276",
|
||||
"0.04946107697915991",
|
||||
"0.04717897697916129",
|
||||
"0.04551704697916037",
|
||||
"0.04467697697916151",
|
||||
"0.04072968697916224",
|
||||
"0.03285456697916089",
|
||||
"0.023488786979161347",
|
||||
"0.01659282697915998",
|
||||
"0.013321846979160057",
|
||||
"0.011234826979162449",
|
||||
"0.01030063697916006",
|
||||
"0.00936596697916059",
|
||||
"0.00874012697916271",
|
||||
"0.00842583697916055",
|
||||
"0.006965146979162284",
|
||||
"0.004043586979161517",
|
||||
"0.000710466979160884",
|
||||
"-0.001576313020837716",
|
||||
"-0.006936193020838033",
|
||||
"-0.016475303020840215",
|
||||
"-0.028748483020837767",
|
||||
"-0.039618433020837784",
|
||||
"-0.051112303020840244",
|
||||
"-0.06468462302083822",
|
||||
"-0.07868024302083754",
|
||||
"-0.09101254302083817",
|
||||
"-0.10103437302083762",
|
||||
"-0.11041488302083735",
|
||||
"-0.11916081302083725",
|
||||
"-0.12789859302083784",
|
||||
"-0.1353792530208402",
|
||||
"-0.14160178302083892",
|
||||
"-0.1455411330208385",
|
||||
"-0.1484450830208388",
|
||||
"-0.14823350302084037",
|
||||
"-0.14591937302083835",
|
||||
"-0.1409032730208395",
|
||||
"-0.13525493302083902",
|
||||
"-0.1279646530208396",
|
||||
"-0.11963431302083904",
|
||||
"-0.11089282302084058",
|
||||
"-0.1027863830208382",
|
||||
"-0.09717347302083823",
|
||||
"-0.09343261302083761",
|
||||
"-0.0913487130208388",
|
||||
"-0.08906007302083907",
|
||||
"-0.0865687230208394",
|
||||
"-0.08407607302083875",
|
||||
"-0.07844600302084004",
|
||||
"-0.06968090302083851",
|
||||
"-0.05947139302083926",
|
||||
"-0.05095282302083959",
|
||||
"-0.042428283020839785",
|
||||
"-0.03218106302083967",
|
||||
"-0.01819858302084043",
|
||||
"-0.002172653020839021",
|
||||
"0.01393231697916164",
|
||||
"0.028098946979159933",
|
||||
"0.040326236979161934",
|
||||
"0.05257029697916238",
|
||||
"0.06479749697916048",
|
||||
"0.07704745697916238"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"gnpy-network-topology:topology": {
|
||||
"network_name": "EDFA Example Network - P2P",
|
||||
"elements": [
|
||||
{
|
||||
"uid": "Site_A",
|
||||
"type": "Transceiver",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Site A",
|
||||
"region": "",
|
||||
"latitude": "0.0",
|
||||
"longitude": "0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span1",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": "80.0",
|
||||
"loss_coef": "0.200000",
|
||||
"length_units": "km",
|
||||
"att_in": "0.0",
|
||||
"con_in": "0.5",
|
||||
"con_out": "0.5",
|
||||
"pmd_coef": "0.000000000000003"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": "1.0",
|
||||
"longitude": "0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa1",
|
||||
"type": "Edfa",
|
||||
"type_variety": "std_low_gain",
|
||||
"operational": {
|
||||
"gain_target": "17.0",
|
||||
"tilt_target": "0.0",
|
||||
"out_voa": "0.0"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": "2.0",
|
||||
"longitude": "0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Site_B",
|
||||
"type": "Transceiver",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Site B",
|
||||
"region": "",
|
||||
"latitude": "2.0",
|
||||
"longitude": "0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"from_node": "Site_A",
|
||||
"to_node": "Span1"
|
||||
},
|
||||
{
|
||||
"from_node": "Span1",
|
||||
"to_node": "Edfa1"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa1",
|
||||
"to_node": "Site_B"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,471 @@
|
||||
{
|
||||
"gnpy-network-topology:topology": {
|
||||
"network_name": "EDFA Example Network - P2P",
|
||||
"elements": [
|
||||
{
|
||||
"uid": "Site_A",
|
||||
"type": "Transceiver",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Site A",
|
||||
"region": "",
|
||||
"latitude": "0.0",
|
||||
"longitude": "0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span1",
|
||||
"type": "RamanFiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": "80.0",
|
||||
"loss_coef": "0.2",
|
||||
"length_units": "km",
|
||||
"att_in": "0.0",
|
||||
"con_in": "0.5",
|
||||
"con_out": "0.0",
|
||||
"lumped_losses": [
|
||||
{
|
||||
"position": "7.0",
|
||||
"loss": "0.5"
|
||||
}
|
||||
],
|
||||
"dispersion": "0.0000167",
|
||||
"effective_area": "0.000000000083",
|
||||
"pmd_coef": "0.000000000000001265",
|
||||
"raman_coefficient": {
|
||||
"reference_frequency": "206184634112792.0",
|
||||
"g0_per_frequency": [
|
||||
{
|
||||
"frequency_offset": "0.0",
|
||||
"g0": "0.0"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "500000000000.0",
|
||||
"g0": "0.000011235161"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "1000000000000.0",
|
||||
"g0": "0.0000347838074"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "1500000000000.0",
|
||||
"g0": "0.0000579356636"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "2000000000000.0",
|
||||
"g0": "0.000080692168"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "2500000000000.0",
|
||||
"g0": "0.0000979845709"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "3000000000000.0",
|
||||
"g0": "0.000110454361"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "3500000000000.0",
|
||||
"g0": "0.000118735302"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "4000000000000.0",
|
||||
"g0": "0.000124736889"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "4500000000000.0",
|
||||
"g0": "0.000130110053"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "5000000000000.0",
|
||||
"g0": "0.000141001273"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "5500000000000.0",
|
||||
"g0": "0.000146383247"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "6000000000000.0",
|
||||
"g0": "0.000157011792"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "6500000000000.0",
|
||||
"g0": "0.000170765865"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "7000000000000.0",
|
||||
"g0": "0.000188408911"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "7500000000000.0",
|
||||
"g0": "0.000205914127"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "8000000000000.0",
|
||||
"g0": "0.000224074028"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "8500000000000.0",
|
||||
"g0": "0.000247508283"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "9000000000000.0",
|
||||
"g0": "0.000277729174"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "9500000000000.0",
|
||||
"g0": "0.000308044243"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "10000000000000.0",
|
||||
"g0": "0.000334764439"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "10500000000000.0",
|
||||
"g0": "0.000356481704"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "11000000000000.0",
|
||||
"g0": "0.000377127256"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "11500000000000.0",
|
||||
"g0": "0.000396269124"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "12000000000000.0",
|
||||
"g0": "0.000410955175"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "12500000000000.0",
|
||||
"g0": "0.000418718761"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "12750000000000.0",
|
||||
"g0": "0.000419511263"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "13000000000000.0",
|
||||
"g0": "0.000417025384"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "13250000000000.0",
|
||||
"g0": "0.000413565369"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "13500000000000.0",
|
||||
"g0": "0.000407726048"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "14000000000000.0",
|
||||
"g0": "0.000383671291"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "14500000000000.0",
|
||||
"g0": "0.000408564283"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "14750000000000.0",
|
||||
"g0": "0.000369571936"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "15000000000000.0",
|
||||
"g0": "0.00031444209"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "15500000000000.0",
|
||||
"g0": "0.000216074535"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "16000000000000.0",
|
||||
"g0": "0.000123097823"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "16500000000000.0",
|
||||
"g0": "0.0000895457457"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "17000000000000.0",
|
||||
"g0": "0.00007524704"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "17500000000000.0",
|
||||
"g0": "0.0000719806145"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "18000000000000.0",
|
||||
"g0": "0.0000887961158"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "18250000000000.0",
|
||||
"g0": "0.0000930812065"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "18500000000000.0",
|
||||
"g0": "0.0000937058268"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "18750000000000.0",
|
||||
"g0": "0.0000845719619"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "19000000000000.0",
|
||||
"g0": "0.0000690585286"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "19500000000000.0",
|
||||
"g0": "0.0000450407159"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "20000000000000.0",
|
||||
"g0": "0.0000336521245"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "20500000000000.0",
|
||||
"g0": "0.0000302292475"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "21000000000000.0",
|
||||
"g0": "0.0000269376939"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "21500000000000.0",
|
||||
"g0": "0.0000260020897"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "22000000000000.0",
|
||||
"g0": "0.0000282958958"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "22500000000000.0",
|
||||
"g0": "0.0000308667558"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "23000000000000.0",
|
||||
"g0": "0.0000366024657"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "23500000000000.0",
|
||||
"g0": "0.0000580610307"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "24000000000000.0",
|
||||
"g0": "0.0000654797937"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "24500000000000.0",
|
||||
"g0": "0.0000625022715"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "25000000000000.0",
|
||||
"g0": "0.0000537806442"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "25500000000000.0",
|
||||
"g0": "0.0000394996621"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "26000000000000.0",
|
||||
"g0": "0.0000268120644"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "26500000000000.0",
|
||||
"g0": "0.0000233038554"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "27000000000000.0",
|
||||
"g0": "0.0000179140757"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "27500000000000.0",
|
||||
"g0": "0.0000152472424"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "28000000000000.0",
|
||||
"g0": "0.0000132707565"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "28500000000000.0",
|
||||
"g0": "0.000010654176"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "29000000000000.0",
|
||||
"g0": "0.00000984649374"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "29500000000000.0",
|
||||
"g0": "0.00000913999627"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "30000000000000.0",
|
||||
"g0": "0.00000908971012"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "30500000000000.0",
|
||||
"g0": "0.0000104227525"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "31000000000000.0",
|
||||
"g0": "0.0000150419271"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "31500000000000.0",
|
||||
"g0": "0.0000177838232"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "32000000000000.0",
|
||||
"g0": "0.0000215810815"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "32500000000000.0",
|
||||
"g0": "0.0000203744008"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "33000000000000.0",
|
||||
"g0": "0.0000181939341"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "33500000000000.0",
|
||||
"g0": "0.0000131862121"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "34000000000000.0",
|
||||
"g0": "0.00000965352116"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "34500000000000.0",
|
||||
"g0": "0.00000862698322"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "35000000000000.0",
|
||||
"g0": "0.00000918688016"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "35500000000000.0",
|
||||
"g0": "0.0000101737784"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "36000000000000.0",
|
||||
"g0": "0.0000108017817"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "36500000000000.0",
|
||||
"g0": "0.0000103903588"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "37000000000000.0",
|
||||
"g0": "0.00000930040333"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "37500000000000.0",
|
||||
"g0": "0.00000830809173"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "38000000000000.0",
|
||||
"g0": "0.00000690650401"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "38500000000000.0",
|
||||
"g0": "0.00000552238029"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "39000000000000.0",
|
||||
"g0": "0.00000390648708"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "39500000000000.0",
|
||||
"g0": "0.00000222908227"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "40000000000000.0",
|
||||
"g0": "0.00000155796177"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "40500000000000.0",
|
||||
"g0": "0.00000097721872"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "41000000000000.0",
|
||||
"g0": "0.00000032347724"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "41500000000000.0",
|
||||
"g0": "0.00000016060245"
|
||||
},
|
||||
{
|
||||
"frequency_offset": "42000000000000.0",
|
||||
"g0": "0.00000007973064"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"operational": {
|
||||
"temperature": "283.0",
|
||||
"raman_pumps": [
|
||||
{
|
||||
"frequency": "205000000000000.0",
|
||||
"power": "0.2",
|
||||
"propagation_direction": "counterprop"
|
||||
},
|
||||
{
|
||||
"frequency": "201000000000000.0",
|
||||
"power": "0.206",
|
||||
"propagation_direction": "counterprop"
|
||||
}
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": "1.0",
|
||||
"longitude": "0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa1",
|
||||
"type": "Edfa",
|
||||
"type_variety": "std_low_gain",
|
||||
"operational": {
|
||||
"gain_target": "17.0",
|
||||
"tilt_target": "0.0",
|
||||
"out_voa": "0.0"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": "2.0",
|
||||
"longitude": "0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Site_B",
|
||||
"type": "Transceiver",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Site B",
|
||||
"region": "",
|
||||
"latitude": "2.0",
|
||||
"longitude": "0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"from_node": "Site_A",
|
||||
"to_node": "Span1"
|
||||
},
|
||||
{
|
||||
"from_node": "Span1",
|
||||
"to_node": "Edfa1"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa1",
|
||||
"to_node": "Site_B"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
381
tests/data/convert/GNPy_yang_formatted-eqpt_config_expected.json
Normal file
381
tests/data/convert/GNPy_yang_formatted-eqpt_config_expected.json
Normal file
@@ -0,0 +1,381 @@
|
||||
{
|
||||
"gnpy-eqpt-config:equipment": {
|
||||
"Edfa": [
|
||||
{
|
||||
"type_variety": "CienaDB_medium_gain",
|
||||
"type_def": "advanced_model",
|
||||
"gain_flatmax": "25.0",
|
||||
"gain_min": "15.0",
|
||||
"p_max": "21.0",
|
||||
"advanced_config_from_json": "std_medium_gain_advanced_config.json",
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "std_medium_gain",
|
||||
"type_def": "variable_gain",
|
||||
"gain_flatmax": "26.0",
|
||||
"gain_min": "15.0",
|
||||
"p_max": "21.0",
|
||||
"nf_min": "6.0",
|
||||
"nf_max": "10.0",
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "std_low_gain",
|
||||
"type_def": "variable_gain",
|
||||
"gain_flatmax": "16.0",
|
||||
"gain_min": "8.0",
|
||||
"p_max": "21.0",
|
||||
"nf_min": "7.0",
|
||||
"nf_max": "11.0",
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "test",
|
||||
"type_def": "variable_gain",
|
||||
"gain_flatmax": "25.0",
|
||||
"gain_min": "15.0",
|
||||
"p_max": "21.0",
|
||||
"nf_min": "5.8",
|
||||
"nf_max": "10.0",
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "test_fixed_gain",
|
||||
"type_def": "fixed_gain",
|
||||
"gain_flatmax": "21.0",
|
||||
"gain_min": "20.0",
|
||||
"p_max": "21.0",
|
||||
"nf0": "5.0",
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "std_booster",
|
||||
"type_def": "fixed_gain",
|
||||
"gain_flatmax": "21.0",
|
||||
"gain_min": "20.0",
|
||||
"p_max": "21.0",
|
||||
"nf0": "5.0",
|
||||
"allowed_for_design": false
|
||||
}
|
||||
],
|
||||
"Fiber": [
|
||||
{
|
||||
"type_variety": "SSMF",
|
||||
"dispersion": "0.0000167",
|
||||
"effective_area": "0.000000000083",
|
||||
"pmd_coef": "0.000000000000001265"
|
||||
}
|
||||
],
|
||||
"Span": [
|
||||
{
|
||||
"power_mode": true,
|
||||
"max_fiber_lineic_loss_for_raman": "0.25",
|
||||
"target_extended_gain": "2.5",
|
||||
"max_length": "150.0",
|
||||
"length_units": "km",
|
||||
"max_loss": "28.0",
|
||||
"padding": "10.0",
|
||||
"EOL": "0.0",
|
||||
"con_in": "0.0",
|
||||
"con_out": "0.0",
|
||||
"delta_power_range_dict_db": {
|
||||
"min_value": "0.0",
|
||||
"max_value": "0.0",
|
||||
"step": "0.5"
|
||||
}
|
||||
}
|
||||
],
|
||||
"Roadm": [
|
||||
{
|
||||
"type_variety": "example_test",
|
||||
"target_pch_out_db": "-18.0",
|
||||
"add_drop_osnr": "35.0",
|
||||
"pmd": "0.000000000001",
|
||||
"pdl": "0.5",
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
},
|
||||
"roadm-path-impairments": []
|
||||
},
|
||||
{
|
||||
"type_variety": "example_detailed_impairments",
|
||||
"target_pch_out_db": "-20.0",
|
||||
"add_drop_osnr": "35.0",
|
||||
"pmd": "0.0",
|
||||
"pdl": "0.0",
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
},
|
||||
"roadm-path-impairments": [
|
||||
{
|
||||
"roadm-path-impairments-id": 0,
|
||||
"roadm-express-path": [
|
||||
{
|
||||
"frequency-range": {
|
||||
"lower-frequency": "191300000000000.0",
|
||||
"upper-frequency": "196100000000000.0"
|
||||
},
|
||||
"roadm-pmd": "0.0",
|
||||
"roadm-cd": "0.0",
|
||||
"roadm-pdl": "0.0",
|
||||
"roadm-inband-crosstalk": "0.0",
|
||||
"roadm-maxloss": "16.5"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"roadm-path-impairments-id": 1,
|
||||
"roadm-add-path": [
|
||||
{
|
||||
"frequency-range": {
|
||||
"lower-frequency": "191300000000000.0",
|
||||
"upper-frequency": "196100000000000.0"
|
||||
},
|
||||
"roadm-pmd": "0.0",
|
||||
"roadm-cd": "0.0",
|
||||
"roadm-pdl": "0.0",
|
||||
"roadm-inband-crosstalk": "0.0",
|
||||
"roadm-maxloss": "11.5",
|
||||
"roadm-pmax": "2.5",
|
||||
"roadm-osnr": "41.0",
|
||||
"roadm-noise-figure": "23.0"
|
||||
},
|
||||
{
|
||||
"frequency-range": {
|
||||
"lower-frequency": "186300000000000.0",
|
||||
"upper-frequency": "190100000000000.0"
|
||||
},
|
||||
"roadm-pmd": "0.0",
|
||||
"roadm-cd": "0.0",
|
||||
"roadm-pdl": "0.5",
|
||||
"roadm-inband-crosstalk": "0.0",
|
||||
"roadm-maxloss": "5.0",
|
||||
"roadm-pmax": "0.0",
|
||||
"roadm-osnr": "35.0",
|
||||
"roadm-noise-figure": "6.0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"roadm-path-impairments-id": 2,
|
||||
"roadm-drop-path": [
|
||||
{
|
||||
"frequency-range": {
|
||||
"lower-frequency": "191300000000000.0",
|
||||
"upper-frequency": "196100000000000.0"
|
||||
},
|
||||
"roadm-pmd": "0.0",
|
||||
"roadm-cd": "0.0",
|
||||
"roadm-pdl": "0.0",
|
||||
"roadm-inband-crosstalk": "0.0",
|
||||
"roadm-maxloss": "11.5",
|
||||
"roadm-minloss": "7.5",
|
||||
"roadm-typloss": "10.0",
|
||||
"roadm-pmin": "-13.5",
|
||||
"roadm-pmax": "-9.5",
|
||||
"roadm-ptyp": "-12.0",
|
||||
"roadm-osnr": "41.0",
|
||||
"roadm-noise-figure": "15.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type_variety": "default",
|
||||
"target_pch_out_db": "-20.0",
|
||||
"add_drop_osnr": "38.0",
|
||||
"pmd": "0.0",
|
||||
"pdl": "0.0",
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type_variety": "detailed_impairments",
|
||||
"target_pch_out_db": "-20.0",
|
||||
"add_drop_osnr": "35.0",
|
||||
"pmd": "0.0",
|
||||
"pdl": "0.0",
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
},
|
||||
"roadm-path-impairments": [
|
||||
{
|
||||
"roadm-path-impairments-id": 0,
|
||||
"roadm-express-path": [
|
||||
{
|
||||
"frequency-range": {
|
||||
"lower-frequency": "191300000000000.0",
|
||||
"upper-frequency": "196100000000000.0"
|
||||
},
|
||||
"roadm-pmd": "0.0",
|
||||
"roadm-cd": "0.0",
|
||||
"roadm-pdl": "0.0",
|
||||
"roadm-inband-crosstalk": "0.0",
|
||||
"roadm-maxloss": "16.5"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"SI": [
|
||||
{
|
||||
"type_variety": "default",
|
||||
"f_min": "191300000000000.0",
|
||||
"f_max": "196100000000000.0",
|
||||
"baud_rate": "32000000000.0",
|
||||
"spacing": "50000000000.0",
|
||||
"power_dbm": "0.0",
|
||||
"roll_off": "0.15",
|
||||
"tx_osnr": "100.0",
|
||||
"sys_margins": "0.0",
|
||||
"use_si_channel_count_for_design": false,
|
||||
"power_range_dict_db": {
|
||||
"min_value": "0.0",
|
||||
"max_value": "0.0",
|
||||
"step": "0.5"
|
||||
}
|
||||
}
|
||||
],
|
||||
"Transceiver": [
|
||||
{
|
||||
"type_variety": "vendorA_trx-type1",
|
||||
"frequency": {
|
||||
"min": "191350000000000.0",
|
||||
"max": "196100000000000.0"
|
||||
},
|
||||
"mode": [
|
||||
{
|
||||
"format": "PS_SP64_1",
|
||||
"baud_rate": "32000000000.0",
|
||||
"OSNR": "11.0",
|
||||
"bit_rate": "100000000000.0",
|
||||
"roll_off": "0.15",
|
||||
"tx_osnr": "100.0",
|
||||
"min_spacing": "50000000000.0",
|
||||
"cost": "1.0"
|
||||
},
|
||||
{
|
||||
"format": "PS_SP64_2",
|
||||
"baud_rate": "64000000000.0",
|
||||
"OSNR": "15.0",
|
||||
"bit_rate": "200000000000.0",
|
||||
"roll_off": "0.15",
|
||||
"tx_osnr": "100.0",
|
||||
"min_spacing": "75000000000.0",
|
||||
"cost": "1.0"
|
||||
},
|
||||
{
|
||||
"format": "mode 1",
|
||||
"baud_rate": "32000000000.0",
|
||||
"OSNR": "11.0",
|
||||
"bit_rate": "100000000000.0",
|
||||
"roll_off": "0.15",
|
||||
"tx_osnr": "100.0",
|
||||
"min_spacing": "50000000000.0",
|
||||
"cost": "1.0"
|
||||
},
|
||||
{
|
||||
"format": "mode 2",
|
||||
"baud_rate": "64000000000.0",
|
||||
"OSNR": "15.0",
|
||||
"bit_rate": "200000000000.0",
|
||||
"roll_off": "0.15",
|
||||
"tx_osnr": "100.0",
|
||||
"min_spacing": "75000000000.0",
|
||||
"cost": "1.0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type_variety": "Voyager_16QAM",
|
||||
"frequency": {
|
||||
"min": "191350000000000.0",
|
||||
"max": "196100000000000.0"
|
||||
},
|
||||
"mode": [
|
||||
{
|
||||
"format": "16QAM",
|
||||
"baud_rate": "32000000000.0",
|
||||
"OSNR": "19.0",
|
||||
"bit_rate": "200000000000.0",
|
||||
"roll_off": "0.15",
|
||||
"tx_osnr": "100.0",
|
||||
"min_spacing": "50000000000.0",
|
||||
"cost": "1.0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type_variety": "Voyager",
|
||||
"frequency": {
|
||||
"min": "191350000000000.0",
|
||||
"max": "196100000000000.0"
|
||||
},
|
||||
"mode": [
|
||||
{
|
||||
"format": "mode 1",
|
||||
"baud_rate": "32000000000.0",
|
||||
"OSNR": "12.0",
|
||||
"bit_rate": "100000000000.0",
|
||||
"roll_off": "0.15",
|
||||
"tx_osnr": "45.0",
|
||||
"min_spacing": "50000000000.0",
|
||||
"cost": "1.0"
|
||||
},
|
||||
{
|
||||
"format": "mode 3",
|
||||
"baud_rate": "44000000000.0",
|
||||
"OSNR": "18.0",
|
||||
"bit_rate": "300000000000.0",
|
||||
"roll_off": "0.15",
|
||||
"tx_osnr": "45.0",
|
||||
"min_spacing": "62500000000.0",
|
||||
"cost": "1.0"
|
||||
},
|
||||
{
|
||||
"format": "mode 2",
|
||||
"baud_rate": "66000000000.0",
|
||||
"OSNR": "21.0",
|
||||
"bit_rate": "400000000000.0",
|
||||
"roll_off": "0.15",
|
||||
"tx_osnr": "45.0",
|
||||
"min_spacing": "75000000000.0",
|
||||
"cost": "1.0"
|
||||
},
|
||||
{
|
||||
"format": "mode 2 - fake",
|
||||
"baud_rate": "66000000000.0",
|
||||
"OSNR": "21.0",
|
||||
"bit_rate": "400000000000.0",
|
||||
"roll_off": "0.15",
|
||||
"tx_osnr": "45.0",
|
||||
"min_spacing": "75000000000.0",
|
||||
"cost": "1.0"
|
||||
},
|
||||
{
|
||||
"format": "mode 4",
|
||||
"baud_rate": "66000000000.0",
|
||||
"OSNR": "16.0",
|
||||
"bit_rate": "200000000000.0",
|
||||
"roll_off": "0.15",
|
||||
"tx_osnr": "45.0",
|
||||
"min_spacing": "75000000000.0",
|
||||
"cost": "1.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"gnpy-eqpt-config:equipment": {
|
||||
"Transceiver": [
|
||||
{
|
||||
"type_variety": "ZR400G",
|
||||
"frequency": {
|
||||
"min": "191350000000000.0",
|
||||
"max": "196100000000000.0"
|
||||
},
|
||||
"mode": [
|
||||
{
|
||||
"format": "400G",
|
||||
"baud_rate": "60000000000.0",
|
||||
"OSNR": "24.0",
|
||||
"bit_rate": "400000000000.0",
|
||||
"roll_off": "0.2",
|
||||
"tx_osnr": "38.0",
|
||||
"min_spacing": "75000000000.0",
|
||||
"cost": "1.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Edfa": [
|
||||
{
|
||||
"type_variety": "user_defined_default_amplifier",
|
||||
"type_def": "advanced_model",
|
||||
"gain_flatmax": "25.0",
|
||||
"gain_min": "15.0",
|
||||
"p_max": "21.0",
|
||||
"advanced_config_from_json": "default_edfa_config.json",
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"gnpy-sim-params:sim-params": {
|
||||
"raman_params": {
|
||||
"flag": true,
|
||||
"result_spatial_resolution": "10000.0",
|
||||
"solver_spatial_resolution": "10000.0"
|
||||
},
|
||||
"nli_params": {
|
||||
"method": "ggn_spectrally_separated",
|
||||
"dispersion_tolerance": "1.0",
|
||||
"phase_shift_tolerance": "0.1",
|
||||
"computed_channels": [
|
||||
1,
|
||||
18,
|
||||
37,
|
||||
56,
|
||||
75
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"gnpy-spectrum:spectrum": [
|
||||
{
|
||||
"f_min": "191400000000000.0",
|
||||
"f_max": "193100000000000.0",
|
||||
"baud_rate": "32000000000.0",
|
||||
"slot_width": "50000000000.0",
|
||||
"delta_pdb": "0.0",
|
||||
"roll_off": "0.15",
|
||||
"tx_osnr": "40.0",
|
||||
"label": "mode_1"
|
||||
},
|
||||
{
|
||||
"f_min": "193162500000000.0",
|
||||
"f_max": "195000000000000.0",
|
||||
"baud_rate": "64000000000.0",
|
||||
"slot_width": "75000000000.0",
|
||||
"roll_off": "0.15",
|
||||
"tx_osnr": "40.0",
|
||||
"tx_power_dbm": "-10.0",
|
||||
"label": "mode_2"
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
1717
tests/data/convert/GNPy_yang_formatted-testTopology_response.json
Normal file
1717
tests/data/convert/GNPy_yang_formatted-testTopology_response.json
Normal file
File diff suppressed because it is too large
Load Diff
291
tests/data/convert/edfa_example_network.json
Normal file
291
tests/data/convert/edfa_example_network.json
Normal file
@@ -0,0 +1,291 @@
|
||||
{
|
||||
"network_name": "EDFA Example Network - P2P",
|
||||
"elements": [
|
||||
{
|
||||
"uid": "Site_A",
|
||||
"type": "Transceiver",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Site A",
|
||||
"region": "",
|
||||
"latitude": 0,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span1",
|
||||
"type": "RamanFiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km",
|
||||
"att_in": 0,
|
||||
"con_in": 0.5,
|
||||
"con_out": 0.0,
|
||||
"lumped_losses": [
|
||||
{
|
||||
"position": 7,
|
||||
"loss": 0.5
|
||||
}
|
||||
],
|
||||
"dispersion": 0.0000167,
|
||||
"effective_area": 83e-12,
|
||||
"raman_coefficient": {
|
||||
"g0": [
|
||||
0.00000000e+00,
|
||||
1.12351610e-05,
|
||||
3.47838074e-05,
|
||||
5.79356636e-05,
|
||||
8.06921680e-05,
|
||||
9.79845709e-05,
|
||||
1.10454361e-04,
|
||||
1.18735302e-04,
|
||||
1.24736889e-04,
|
||||
1.30110053e-04,
|
||||
1.41001273e-04,
|
||||
1.46383247e-04,
|
||||
1.57011792e-04,
|
||||
1.70765865e-04,
|
||||
1.88408911e-04,
|
||||
2.05914127e-04,
|
||||
2.24074028e-04,
|
||||
2.47508283e-04,
|
||||
2.77729174e-04,
|
||||
3.08044243e-04,
|
||||
3.34764439e-04,
|
||||
3.56481704e-04,
|
||||
3.77127256e-04,
|
||||
3.96269124e-04,
|
||||
4.10955175e-04,
|
||||
4.18718761e-04,
|
||||
4.19511263e-04,
|
||||
4.17025384e-04,
|
||||
4.13565369e-04,
|
||||
4.07726048e-04,
|
||||
3.83671291e-04,
|
||||
4.08564283e-04,
|
||||
3.69571936e-04,
|
||||
3.14442090e-04,
|
||||
2.16074535e-04,
|
||||
1.23097823e-04,
|
||||
8.95457457e-05,
|
||||
7.52470400e-05,
|
||||
7.19806145e-05,
|
||||
8.87961158e-05,
|
||||
9.30812065e-05,
|
||||
9.37058268e-05,
|
||||
8.45719619e-05,
|
||||
6.90585286e-05,
|
||||
4.50407159e-05,
|
||||
3.36521245e-05,
|
||||
3.02292475e-05,
|
||||
2.69376939e-05,
|
||||
2.60020897e-05,
|
||||
2.82958958e-05,
|
||||
3.08667558e-05,
|
||||
3.66024657e-05,
|
||||
5.80610307e-05,
|
||||
6.54797937e-05,
|
||||
6.25022715e-05,
|
||||
5.37806442e-05,
|
||||
3.94996621e-05,
|
||||
2.68120644e-05,
|
||||
2.33038554e-05,
|
||||
1.79140757e-05,
|
||||
1.52472424e-05,
|
||||
1.32707565e-05,
|
||||
1.06541760e-05,
|
||||
9.84649374e-06,
|
||||
9.13999627e-06,
|
||||
9.08971012e-06,
|
||||
1.04227525e-05,
|
||||
1.50419271e-05,
|
||||
1.77838232e-05,
|
||||
2.15810815e-05,
|
||||
2.03744008e-05,
|
||||
1.81939341e-05,
|
||||
1.31862121e-05,
|
||||
9.65352116e-06,
|
||||
8.62698322e-06,
|
||||
9.18688016e-06,
|
||||
1.01737784e-05,
|
||||
1.08017817e-05,
|
||||
1.03903588e-05,
|
||||
9.30040333e-06,
|
||||
8.30809173e-06,
|
||||
6.90650401e-06,
|
||||
5.52238029e-06,
|
||||
3.90648708e-06,
|
||||
2.22908227e-06,
|
||||
1.55796177e-06,
|
||||
9.77218716e-07,
|
||||
3.23477236e-07,
|
||||
1.60602454e-07,
|
||||
7.97306386e-08
|
||||
],
|
||||
"frequency_offset": [
|
||||
0.0e12,
|
||||
0.5e12,
|
||||
1.0e12,
|
||||
1.5e12,
|
||||
2.0e12,
|
||||
2.5e12,
|
||||
3.0e12,
|
||||
3.5e12,
|
||||
4.0e12,
|
||||
4.5e12,
|
||||
5.0e12,
|
||||
5.5e12,
|
||||
6.0e12,
|
||||
6.5e12,
|
||||
7.0e12,
|
||||
7.5e12,
|
||||
8.0e12,
|
||||
8.5e12,
|
||||
9.0e12,
|
||||
9.5e12,
|
||||
10.0e12,
|
||||
10.5e12,
|
||||
11.0e12,
|
||||
11.5e12,
|
||||
12.0e12,
|
||||
12.5e12,
|
||||
12.75e12,
|
||||
13.0e12,
|
||||
13.25e12,
|
||||
13.5e12,
|
||||
14.0e12,
|
||||
14.5e12,
|
||||
14.75e12,
|
||||
15.0e12,
|
||||
15.5e12,
|
||||
16.0e12,
|
||||
16.5e12,
|
||||
17.0e12,
|
||||
17.5e12,
|
||||
18.0e12,
|
||||
18.25e12,
|
||||
18.5e12,
|
||||
18.75e12,
|
||||
19.0e12,
|
||||
19.5e12,
|
||||
20.0e12,
|
||||
20.5e12,
|
||||
21.0e12,
|
||||
21.5e12,
|
||||
22.0e12,
|
||||
22.5e12,
|
||||
23.0e12,
|
||||
23.5e12,
|
||||
24.0e12,
|
||||
24.5e12,
|
||||
25.0e12,
|
||||
25.5e12,
|
||||
26.0e12,
|
||||
26.5e12,
|
||||
27.0e12,
|
||||
27.5e12,
|
||||
28.0e12,
|
||||
28.5e12,
|
||||
29.0e12,
|
||||
29.5e12,
|
||||
30.0e12,
|
||||
30.5e12,
|
||||
31.0e12,
|
||||
31.5e12,
|
||||
32.0e12,
|
||||
32.5e12,
|
||||
33.0e12,
|
||||
33.5e12,
|
||||
34.0e12,
|
||||
34.5e12,
|
||||
35.0e12,
|
||||
35.5e12,
|
||||
36.0e12,
|
||||
36.5e12,
|
||||
37.0e12,
|
||||
37.5e12,
|
||||
38.0e12,
|
||||
38.5e12,
|
||||
39.0e12,
|
||||
39.5e12,
|
||||
40.0e12,
|
||||
40.5e12,
|
||||
41.0e12,
|
||||
41.5e12,
|
||||
42.0e12
|
||||
],
|
||||
"reference_frequency": 206184634112792
|
||||
},
|
||||
"pmd_coef": 1.265e-15
|
||||
},
|
||||
"operational": {
|
||||
"temperature": 283,
|
||||
"raman_pumps": [
|
||||
{
|
||||
"power": 0.2,
|
||||
"frequency": 205000000000000,
|
||||
"propagation_direction": "counterprop"
|
||||
},
|
||||
{
|
||||
"power": 0.206,
|
||||
"frequency": 201000000000000,
|
||||
"propagation_direction": "counterprop"
|
||||
}
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa1",
|
||||
"type": "Edfa",
|
||||
"type_variety": "std_low_gain",
|
||||
"operational": {
|
||||
"gain_target": 17,
|
||||
"tilt_target": 0,
|
||||
"out_voa": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Site_B",
|
||||
"type": "Transceiver",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Site B",
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"from_node": "Site_A",
|
||||
"to_node": "Span1"
|
||||
},
|
||||
{
|
||||
"from_node": "Span1",
|
||||
"to_node": "Edfa1"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa1",
|
||||
"to_node": "Site_B"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"gnpy-network-topology:topology": {
|
||||
"network_name": "EDFA Example Network - P2P",
|
||||
"elements": [
|
||||
{
|
||||
"uid": "Site_A",
|
||||
"type": "Transceiver",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"latitude": 0.0,
|
||||
"longitude": 0.0,
|
||||
"city": "Site A",
|
||||
"region": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span1",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80.0,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km",
|
||||
"att_in": 0.0,
|
||||
"con_in": 0.5,
|
||||
"con_out": 0.5,
|
||||
"pmd_coef": 3e-15
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"latitude": 1.0,
|
||||
"longitude": 0.0,
|
||||
"city": [
|
||||
null
|
||||
],
|
||||
"region": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa1",
|
||||
"type": "Edfa",
|
||||
"type_variety": "std_low_gain",
|
||||
"operational": {
|
||||
"gain_target": 15.0,
|
||||
"delta_p": -2,
|
||||
"tilt_target": 0,
|
||||
"out_voa": 0.0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"latitude": 2.0,
|
||||
"longitude": 0.0,
|
||||
"city": [
|
||||
null
|
||||
],
|
||||
"region": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Site_B",
|
||||
"type": "Transceiver",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"latitude": 2.0,
|
||||
"longitude": 0.0,
|
||||
"city": "Site B",
|
||||
"region": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"from_node": "Site_A",
|
||||
"to_node": "Span1"
|
||||
},
|
||||
{
|
||||
"from_node": "Span1",
|
||||
"to_node": "Edfa1"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa1",
|
||||
"to_node": "Site_B"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
378
tests/data/convert/eqpt_config.json
Normal file
378
tests/data/convert/eqpt_config.json
Normal file
@@ -0,0 +1,378 @@
|
||||
{
|
||||
"Edfa": [
|
||||
{
|
||||
"type_variety": "CienaDB_medium_gain",
|
||||
"type_def": "advanced_model",
|
||||
"gain_flatmax": 25,
|
||||
"gain_min": 15,
|
||||
"p_max": 21,
|
||||
"advanced_config_from_json": "std_medium_gain_advanced_config.json",
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "std_medium_gain",
|
||||
"type_def": "variable_gain",
|
||||
"gain_flatmax": 26,
|
||||
"gain_min": 15,
|
||||
"p_max": 21,
|
||||
"nf_min": 6,
|
||||
"nf_max": 10,
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "std_low_gain",
|
||||
"type_def": "variable_gain",
|
||||
"gain_flatmax": 16,
|
||||
"gain_min": 8,
|
||||
"p_max": 21,
|
||||
"nf_min": 7,
|
||||
"nf_max": 11,
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "test",
|
||||
"type_def": "variable_gain",
|
||||
"gain_flatmax": 25,
|
||||
"gain_min": 15,
|
||||
"p_max": 21,
|
||||
"nf_min": 5.8,
|
||||
"nf_max": 10,
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "test_fixed_gain",
|
||||
"type_def": "fixed_gain",
|
||||
"gain_flatmax": 21,
|
||||
"gain_min": 20,
|
||||
"p_max": 21,
|
||||
"nf0": 5,
|
||||
"allowed_for_design": true
|
||||
},
|
||||
{
|
||||
"type_variety": "std_booster",
|
||||
"type_def": "fixed_gain",
|
||||
"gain_flatmax": 21,
|
||||
"gain_min": 20,
|
||||
"p_max": 21,
|
||||
"nf0": 5,
|
||||
"allowed_for_design": false
|
||||
}
|
||||
],
|
||||
"Fiber": [
|
||||
{
|
||||
"type_variety": "SSMF",
|
||||
"dispersion": 1.67e-05,
|
||||
"effective_area": 83e-12,
|
||||
"pmd_coef": 1.265e-15
|
||||
}
|
||||
],
|
||||
"Span": [
|
||||
{
|
||||
"power_mode": true,
|
||||
"delta_power_range_db": [
|
||||
0,
|
||||
0,
|
||||
0.5
|
||||
],
|
||||
"max_fiber_lineic_loss_for_raman": 0.25,
|
||||
"target_extended_gain": 2.5,
|
||||
"max_length": 150,
|
||||
"length_units": "km",
|
||||
"max_loss": 28,
|
||||
"padding": 10,
|
||||
"EOL": 0,
|
||||
"con_in": 0,
|
||||
"con_out": 0
|
||||
}
|
||||
],
|
||||
"Roadm": [
|
||||
{
|
||||
"type_variety": "example_test",
|
||||
"target_pch_out_db": -18,
|
||||
"add_drop_osnr": 35,
|
||||
"pmd": 1e-12,
|
||||
"pdl": 0.5,
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
},
|
||||
"roadm-path-impairments": []
|
||||
},
|
||||
{
|
||||
"type_variety": "example_detailed_impairments",
|
||||
"target_pch_out_db": -20,
|
||||
"add_drop_osnr": 35,
|
||||
"pmd": 0,
|
||||
"pdl": 0,
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
},
|
||||
"roadm-path-impairments": [
|
||||
{
|
||||
"roadm-path-impairments-id": 0,
|
||||
"roadm-express-path": [
|
||||
{
|
||||
"frequency-range": {
|
||||
"lower-frequency": 191.3e12,
|
||||
"upper-frequency": 196.1e12
|
||||
},
|
||||
"roadm-pmd": 0,
|
||||
"roadm-cd": 0,
|
||||
"roadm-pdl": 0,
|
||||
"roadm-inband-crosstalk": 0,
|
||||
"roadm-maxloss": 16.5
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"roadm-path-impairments-id": 1,
|
||||
"roadm-add-path": [
|
||||
{
|
||||
"frequency-range": {
|
||||
"lower-frequency": 191.3e12,
|
||||
"upper-frequency": 196.1e12
|
||||
},
|
||||
"roadm-pmd": 0,
|
||||
"roadm-cd": 0,
|
||||
"roadm-pdl": 0,
|
||||
"roadm-inband-crosstalk": 0,
|
||||
"roadm-maxloss": 11.5,
|
||||
"roadm-pmax": 2.5,
|
||||
"roadm-osnr": 41,
|
||||
"roadm-noise-figure": 23
|
||||
},
|
||||
{
|
||||
"frequency-range": {
|
||||
"lower-frequency": 186.3e12,
|
||||
"upper-frequency": 190.1e12
|
||||
},
|
||||
"roadm-pmd": 0,
|
||||
"roadm-cd": 0,
|
||||
"roadm-pdl": 0.5,
|
||||
"roadm-inband-crosstalk": 0,
|
||||
"roadm-maxloss": 5,
|
||||
"roadm-pmax": 0,
|
||||
"roadm-osnr": 35,
|
||||
"roadm-noise-figure": 6
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"roadm-path-impairments-id": 2,
|
||||
"roadm-drop-path": [
|
||||
{
|
||||
"frequency-range": {
|
||||
"lower-frequency": 191.3e12,
|
||||
"upper-frequency": 196.1e12
|
||||
},
|
||||
"roadm-pmd": 0,
|
||||
"roadm-cd": 0,
|
||||
"roadm-pdl": 0,
|
||||
"roadm-inband-crosstalk": 0,
|
||||
"roadm-maxloss": 11.5,
|
||||
"roadm-minloss": 7.5,
|
||||
"roadm-typloss": 10,
|
||||
"roadm-pmin": -13.5,
|
||||
"roadm-pmax": -9.5,
|
||||
"roadm-ptyp": -12,
|
||||
"roadm-osnr": 41,
|
||||
"roadm-noise-figure": 15
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"target_pch_out_db": -20,
|
||||
"add_drop_osnr": 38,
|
||||
"pmd": 0,
|
||||
"pdl": 0,
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type_variety": "detailed_impairments",
|
||||
"target_pch_out_db": -20,
|
||||
"add_drop_osnr": 35,
|
||||
"pmd": 0,
|
||||
"pdl": 0,
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
},
|
||||
"roadm-path-impairments": [
|
||||
{
|
||||
"roadm-path-impairments-id": 0,
|
||||
"roadm-express-path": [
|
||||
{
|
||||
"frequency-range": {
|
||||
"lower-frequency": 191.3e12,
|
||||
"upper-frequency": 196.1e12
|
||||
},
|
||||
"roadm-pmd": 0,
|
||||
"roadm-cd": 0,
|
||||
"roadm-pdl": 0,
|
||||
"roadm-inband-crosstalk": 0,
|
||||
"roadm-maxloss": 16.5
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"SI": [
|
||||
{
|
||||
"type_variety": "default",
|
||||
"f_min": 191.3e12,
|
||||
"f_max": 196.1e12,
|
||||
"baud_rate": 32e9,
|
||||
"spacing": 50e9,
|
||||
"power_dbm": 0,
|
||||
"power_range_db": [
|
||||
0,
|
||||
0,
|
||||
0.5
|
||||
],
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"sys_margins": 0,
|
||||
"use_si_channel_count_for_design": false
|
||||
}
|
||||
],
|
||||
"Transceiver": [
|
||||
{
|
||||
"type_variety": "vendorA_trx-type1",
|
||||
"frequency": {
|
||||
"min": 191.35e12,
|
||||
"max": 196.1e12
|
||||
},
|
||||
"mode": [
|
||||
{
|
||||
"format": "PS_SP64_1",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 11,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 50e9,
|
||||
"cost": 1
|
||||
},
|
||||
{
|
||||
"format": "PS_SP64_2",
|
||||
"baud_rate": 64e9,
|
||||
"OSNR": 15,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
},
|
||||
{
|
||||
"format": "mode 1",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 11,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 50e9,
|
||||
"cost": 1
|
||||
},
|
||||
{
|
||||
"format": "mode 2",
|
||||
"baud_rate": 64e9,
|
||||
"OSNR": 15,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type_variety": "Voyager_16QAM",
|
||||
"frequency": {
|
||||
"min": 191.35e12,
|
||||
"max": 196.1e12
|
||||
},
|
||||
"mode": [
|
||||
{
|
||||
"format": "16QAM",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 19,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 50e9,
|
||||
"cost": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type_variety": "Voyager",
|
||||
"frequency": {
|
||||
"min": 191.35e12,
|
||||
"max": 196.1e12
|
||||
},
|
||||
"mode": [
|
||||
{
|
||||
"format": "mode 1",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 12,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 50e9,
|
||||
"cost": 1
|
||||
},
|
||||
{
|
||||
"format": "mode 3",
|
||||
"baud_rate": 44e9,
|
||||
"OSNR": 18,
|
||||
"bit_rate": 300e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 62.5e9,
|
||||
"cost": 1
|
||||
},
|
||||
{
|
||||
"format": "mode 2",
|
||||
"baud_rate": 66e9,
|
||||
"OSNR": 21,
|
||||
"bit_rate": 400e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
},
|
||||
{
|
||||
"format": "mode 2 - fake",
|
||||
"baud_rate": 66e9,
|
||||
"OSNR": 21,
|
||||
"bit_rate": 400e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
},
|
||||
{
|
||||
"format": "mode 4",
|
||||
"baud_rate": 66e9,
|
||||
"OSNR": 16,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 45,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
35
tests/data/convert/extra_eqpt_config.json
Normal file
35
tests/data/convert/extra_eqpt_config.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"Transceiver": [
|
||||
{
|
||||
"type_variety": "ZR400G",
|
||||
"frequency": {
|
||||
"min": 191.35e12,
|
||||
"max": 196.1e12
|
||||
},
|
||||
"mode": [
|
||||
{
|
||||
"format": "400G",
|
||||
"baud_rate": 60e9,
|
||||
"OSNR": 24,
|
||||
"bit_rate": 400e9,
|
||||
"roll_off": 0.2,
|
||||
"tx_osnr": 38,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Edfa": [
|
||||
{
|
||||
"type_variety": "user_defined_default_amplifier",
|
||||
"type_def": "advanced_model",
|
||||
"gain_flatmax": 25,
|
||||
"gain_min": 15,
|
||||
"p_max": 21,
|
||||
"advanced_config_from_json": "default_edfa_config.json",
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": false
|
||||
}
|
||||
]
|
||||
}
|
||||
13
tests/data/convert/sim_params.json
Normal file
13
tests/data/convert/sim_params.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"raman_params": {
|
||||
"flag": true,
|
||||
"result_spatial_resolution": 10e3,
|
||||
"solver_spatial_resolution": 10e3
|
||||
},
|
||||
"nli_params": {
|
||||
"method": "ggn_spectrally_separated",
|
||||
"dispersion_tolerance": 1,
|
||||
"phase_shift_tolerance": 0.1,
|
||||
"computed_channels": [1, 18, 37, 56, 75]
|
||||
}
|
||||
}
|
||||
24
tests/data/convert/spectrum.json
Normal file
24
tests/data/convert/spectrum.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"spectrum": [
|
||||
{
|
||||
"f_min": 191.4e12,
|
||||
"f_max": 193.1e12,
|
||||
"baud_rate": 32e9,
|
||||
"slot_width": 50e9,
|
||||
"delta_pdb": 0,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40,
|
||||
"label": "mode_1"
|
||||
},
|
||||
{
|
||||
"f_min": 193.1625e12,
|
||||
"f_max": 195e12,
|
||||
"baud_rate": 64e9,
|
||||
"slot_width": 75e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40,
|
||||
"tx_power_dbm": -10,
|
||||
"label": "mode_2"
|
||||
}
|
||||
]
|
||||
}
|
||||
304
tests/data/convert/std_medium_gain_advanced_config.json
Normal file
304
tests/data/convert/std_medium_gain_advanced_config.json
Normal file
@@ -0,0 +1,304 @@
|
||||
{
|
||||
"f_min": 191.275e12,
|
||||
"f_max": 196.125e12,
|
||||
"nf_fit_coeff": [
|
||||
0.000168241,
|
||||
0.0469961,
|
||||
0.0359549,
|
||||
5.82851
|
||||
],
|
||||
"nf_ripple": [
|
||||
-0.3110761646066259,
|
||||
-0.3110761646066259,
|
||||
-0.31110274831665313,
|
||||
-0.31419329378173544,
|
||||
-0.3172854168606314,
|
||||
-0.32037911876162584,
|
||||
-0.3233255190215882,
|
||||
-0.31624321721895354,
|
||||
-0.30915729645781326,
|
||||
-0.30206775396360075,
|
||||
-0.2949045115165272,
|
||||
-0.26632156113294336,
|
||||
-0.23772399031437283,
|
||||
-0.20911178784023846,
|
||||
-0.18048410390821285,
|
||||
-0.14379944379052215,
|
||||
-0.10709599992470213,
|
||||
-0.07037375788020579,
|
||||
-0.03372858157230583,
|
||||
-0.015660302006048,
|
||||
0.0024172385953583004,
|
||||
0.020504047353947653,
|
||||
0.03860013139908377,
|
||||
0.05670549786742816,
|
||||
0.07482015390297145,
|
||||
0.0838762040768461,
|
||||
0.09284481475528361,
|
||||
0.1018180306253394,
|
||||
0.11079585523492333,
|
||||
0.1020395478432815,
|
||||
0.09310160456603413,
|
||||
0.08415906712621996,
|
||||
0.07521193198077789,
|
||||
0.0676340601339394,
|
||||
0.06005437964543287,
|
||||
0.052470799141237305,
|
||||
0.044883315610536455,
|
||||
0.037679759069084225,
|
||||
0.03047647598902483,
|
||||
0.02326948274513522,
|
||||
0.01605877647020772,
|
||||
0.021248462316134083,
|
||||
0.02657315875107553,
|
||||
0.03190060058247842,
|
||||
0.03723078993416436,
|
||||
0.04256372893215024,
|
||||
0.047899419704645264,
|
||||
0.03915515813685565,
|
||||
0.030289222542492025,
|
||||
0.021418708618354456,
|
||||
0.012573926129294415,
|
||||
0.006240488799898697,
|
||||
-9.622162373026585e-05,
|
||||
-0.006436207679519103,
|
||||
-0.012779471908040341,
|
||||
-0.02038153550619876,
|
||||
-0.027999803010447587,
|
||||
-0.035622012697103154,
|
||||
-0.043236398934156144,
|
||||
-0.04493583574805963,
|
||||
-0.04663615264317309,
|
||||
-0.048337350303318156,
|
||||
-0.050039429413028365,
|
||||
-0.051742390657545205,
|
||||
-0.05342028484370278,
|
||||
-0.05254242298580185,
|
||||
-0.05166410580536087,
|
||||
-0.05078533294804249,
|
||||
-0.04990610405914272,
|
||||
-0.05409792133358102,
|
||||
-0.05832916277634124,
|
||||
-0.06256260169582961,
|
||||
-0.06660356886269536,
|
||||
-0.04779792991567815,
|
||||
-0.028982516728038848,
|
||||
-0.010157321677553965,
|
||||
0.00861320615127981,
|
||||
0.01913736978785662,
|
||||
0.029667009055877668,
|
||||
0.04020212822983975,
|
||||
0.050742731588695494,
|
||||
0.061288823415841555,
|
||||
0.07184040799914815,
|
||||
0.1043252636301016,
|
||||
0.13687829834471027,
|
||||
0.1694483010211072,
|
||||
0.202035284929368,
|
||||
0.23624619427167134,
|
||||
0.27048596623174515,
|
||||
0.30474360397422756,
|
||||
0.3390191214858807,
|
||||
0.36358851509924695,
|
||||
0.38814205928193013,
|
||||
0.41270842850729195,
|
||||
0.4372876328262819,
|
||||
0.4372876328262819
|
||||
],
|
||||
"dgt": [
|
||||
2.714526681131686,
|
||||
2.705443819238505,
|
||||
2.6947834587664494,
|
||||
2.6841217449620203,
|
||||
2.6681935771243177,
|
||||
2.6521732021128046,
|
||||
2.630396440815385,
|
||||
2.602860350286428,
|
||||
2.5696460593920065,
|
||||
2.5364027376452056,
|
||||
2.499446286796604,
|
||||
2.4587748041127506,
|
||||
2.414398437185221,
|
||||
2.3699990328716107,
|
||||
2.322373696229342,
|
||||
2.271520771371253,
|
||||
2.2174389328192197,
|
||||
2.16337565384239,
|
||||
2.1183028432496016,
|
||||
2.082225099873648,
|
||||
2.055100772005235,
|
||||
2.0279625371819305,
|
||||
2.0008103857988204,
|
||||
1.9736443063300082,
|
||||
1.9482128147680253,
|
||||
1.9245345552113182,
|
||||
1.9026104247588487,
|
||||
1.8806927939516411,
|
||||
1.862235672444246,
|
||||
1.847275503201129,
|
||||
1.835814081380705,
|
||||
1.824381436842932,
|
||||
1.8139629377087627,
|
||||
1.8045606557581335,
|
||||
1.7961751115773796,
|
||||
1.7877868031023945,
|
||||
1.7793941781790852,
|
||||
1.7709972329654864,
|
||||
1.7625959636196327,
|
||||
1.7541903672600494,
|
||||
1.7459181197626403,
|
||||
1.737780757913635,
|
||||
1.7297783508684146,
|
||||
1.7217732861435076,
|
||||
1.7137640932265894,
|
||||
1.7057507692361864,
|
||||
1.6918150918099673,
|
||||
1.6719047669939942,
|
||||
1.6460167077689267,
|
||||
1.6201194134191075,
|
||||
1.5986915141218316,
|
||||
1.5817353179379183,
|
||||
1.569199764184379,
|
||||
1.5566577309558969,
|
||||
1.545374152761467,
|
||||
1.5353620432989845,
|
||||
1.5266220576235803,
|
||||
1.5178910621476225,
|
||||
1.5097346239790443,
|
||||
1.502153039909686,
|
||||
1.495145456062699,
|
||||
1.488134243479226,
|
||||
1.48111939735681,
|
||||
1.474100442252211,
|
||||
1.4670307626366115,
|
||||
1.4599103316162523,
|
||||
1.45273959485914,
|
||||
1.445565137158368,
|
||||
1.4340878115214444,
|
||||
1.418273806730323,
|
||||
1.3981208704326855,
|
||||
1.3779439775587023,
|
||||
1.3598972673004606,
|
||||
1.3439818461440451,
|
||||
1.3301807335621048,
|
||||
1.316383926863083,
|
||||
1.3040618749785347,
|
||||
1.2932153453410835,
|
||||
1.2838336236692311,
|
||||
1.2744470198196236,
|
||||
1.2650555289898042,
|
||||
1.2556591482982988,
|
||||
1.2428104897182262,
|
||||
1.2264996957264114,
|
||||
1.2067249615595257,
|
||||
1.1869318618366975,
|
||||
1.1672278304018044,
|
||||
1.1476135933863398,
|
||||
1.1280891949729075,
|
||||
1.108555289615659,
|
||||
1.0895983485572227,
|
||||
1.0712204022764056,
|
||||
1.0534217504465226,
|
||||
1.0356155337864215,
|
||||
1.017807767853702,
|
||||
1.0
|
||||
],
|
||||
"gain_ripple": [
|
||||
0.1359703369791596,
|
||||
0.11822862697916037,
|
||||
0.09542181697916163,
|
||||
0.06245819697916133,
|
||||
0.02602813697916062,
|
||||
-0.0036199830208403228,
|
||||
-0.018326963020840026,
|
||||
-0.0246928330208398,
|
||||
-0.016792253020838643,
|
||||
-0.0028138630208403015,
|
||||
0.017572956979162058,
|
||||
0.038328296979159404,
|
||||
0.054956336979159914,
|
||||
0.0670723869791594,
|
||||
0.07091459697916136,
|
||||
0.07094413697916124,
|
||||
0.07114372697916238,
|
||||
0.07533675697916209,
|
||||
0.08731066697916035,
|
||||
0.10313984697916112,
|
||||
0.12276252697916235,
|
||||
0.14239527697916188,
|
||||
0.15945681697916214,
|
||||
0.1739275269791598,
|
||||
0.1767381569791624,
|
||||
0.17037189697916233,
|
||||
0.15216302697916007,
|
||||
0.13114358697916018,
|
||||
0.10802383697916085,
|
||||
0.08548825697916129,
|
||||
0.06916723697916183,
|
||||
0.05848224697916038,
|
||||
0.05447361697916264,
|
||||
0.05154489697916276,
|
||||
0.04946107697915991,
|
||||
0.04717897697916129,
|
||||
0.04551704697916037,
|
||||
0.04467697697916151,
|
||||
0.04072968697916224,
|
||||
0.03285456697916089,
|
||||
0.023488786979161347,
|
||||
0.01659282697915998,
|
||||
0.013321846979160057,
|
||||
0.011234826979162449,
|
||||
0.01030063697916006,
|
||||
0.00936596697916059,
|
||||
0.00874012697916271,
|
||||
0.00842583697916055,
|
||||
0.006965146979162284,
|
||||
0.0040435869791615175,
|
||||
0.0007104669791608842,
|
||||
-0.0015763130208377163,
|
||||
-0.006936193020838033,
|
||||
-0.016475303020840215,
|
||||
-0.028748483020837767,
|
||||
-0.039618433020837784,
|
||||
-0.051112303020840244,
|
||||
-0.06468462302083822,
|
||||
-0.07868024302083754,
|
||||
-0.09101254302083817,
|
||||
-0.10103437302083762,
|
||||
-0.11041488302083735,
|
||||
-0.11916081302083725,
|
||||
-0.12789859302083784,
|
||||
-0.1353792530208402,
|
||||
-0.14160178302083892,
|
||||
-0.1455411330208385,
|
||||
-0.1484450830208388,
|
||||
-0.14823350302084037,
|
||||
-0.14591937302083835,
|
||||
-0.1409032730208395,
|
||||
-0.13525493302083902,
|
||||
-0.1279646530208396,
|
||||
-0.11963431302083904,
|
||||
-0.11089282302084058,
|
||||
-0.1027863830208382,
|
||||
-0.09717347302083823,
|
||||
-0.09343261302083761,
|
||||
-0.0913487130208388,
|
||||
-0.08906007302083907,
|
||||
-0.0865687230208394,
|
||||
-0.08407607302083875,
|
||||
-0.07844600302084004,
|
||||
-0.06968090302083851,
|
||||
-0.05947139302083926,
|
||||
-0.05095282302083959,
|
||||
-0.042428283020839785,
|
||||
-0.03218106302083967,
|
||||
-0.01819858302084043,
|
||||
-0.0021726530208390216,
|
||||
0.01393231697916164,
|
||||
0.028098946979159933,
|
||||
0.040326236979161934,
|
||||
0.05257029697916238,
|
||||
0.06479749697916048,
|
||||
0.07704745697916238
|
||||
]
|
||||
}
|
||||
3384
tests/data/convert/testTopology_auto_design.json
Normal file
3384
tests/data/convert/testTopology_auto_design.json
Normal file
File diff suppressed because it is too large
Load Diff
3644
tests/data/convert/testTopology_auto_design_expected.json
Normal file
3644
tests/data/convert/testTopology_auto_design_expected.json
Normal file
File diff suppressed because it is too large
Load Diff
1685
tests/data/convert/testTopology_response.json
Normal file
1685
tests/data/convert/testTopology_response.json
Normal file
File diff suppressed because it is too large
Load Diff
515
tests/data/convert/testTopology_testservices.json
Normal file
515
tests/data/convert/testTopology_testservices.json
Normal file
@@ -0,0 +1,515 @@
|
||||
{
|
||||
"path-request": [
|
||||
{
|
||||
"request-id": "1",
|
||||
"source": "trx a",
|
||||
"destination": "trx g",
|
||||
"src-tp-id": "trx a",
|
||||
"dst-tp-id": "trx g",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager_16QAM",
|
||||
"trx_mode": "16QAM",
|
||||
"spacing": 50000000000.0,
|
||||
"max-nb-of-channel": 80,
|
||||
"output-power": 0.001,
|
||||
"path_bandwidth": 300000000000.0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "2a",
|
||||
"source": "trx a",
|
||||
"destination": "trx h",
|
||||
"src-tp-id": "trx a",
|
||||
"dst-tp-id": "trx h",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "vendorA_trx-type1",
|
||||
"trx_mode": "PS_SP64_1",
|
||||
"spacing": 50000000000.0,
|
||||
"max-nb-of-channel": 80,
|
||||
"output-power": 0.0012356,
|
||||
"path_bandwidth": 300000000000.0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "3",
|
||||
"source": "trx f",
|
||||
"destination": "trx b",
|
||||
"src-tp-id": "trx f",
|
||||
"dst-tp-id": "trx b",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "vendorA_trx-type1",
|
||||
"trx_mode": "PS_SP64_1",
|
||||
"spacing": 50000000000.0,
|
||||
"max-nb-of-channel": 80,
|
||||
"output-power": 0.001,
|
||||
"path_bandwidth": 300000000000.0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "ee",
|
||||
"source": "trx c",
|
||||
"destination": "trx f",
|
||||
"src-tp-id": "trx c",
|
||||
"dst-tp-id": "trx f",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "vendorA_trx-type1",
|
||||
"trx_mode": "PS_SP64_1",
|
||||
"spacing": 50000000000.0,
|
||||
"max-nb-of-channel": 80,
|
||||
"output-power": 0.001,
|
||||
"path_bandwidth": 300000000000.0
|
||||
}
|
||||
},
|
||||
"explicit-route-objects": {
|
||||
"route-object-include-exclude": [
|
||||
{
|
||||
"index": 0,
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"num-unnum-hop": {
|
||||
"node-id": "roadm e",
|
||||
"hop-type": "LOOSE"
|
||||
}
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"num-unnum-hop": {
|
||||
"node-id": "roadm g",
|
||||
"link-tp-id": "link-tp-id is not used",
|
||||
"hop-type": "LOOSE"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "ff",
|
||||
"source": "trx c",
|
||||
"destination": "trx f",
|
||||
"src-tp-id": "trx c",
|
||||
"dst-tp-id": "trx f",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": "mode 2 - fake",
|
||||
"spacing": 75000000000.0,
|
||||
"max-nb-of-channel": 63,
|
||||
"output-power": 0.001,
|
||||
"path_bandwidth": 300000000000.0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "10",
|
||||
"source": "trx a",
|
||||
"destination": "trx g",
|
||||
"src-tp-id": "trx a",
|
||||
"dst-tp-id": "trx g",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": "mode 2",
|
||||
"spacing": 75000000000.0,
|
||||
"max-nb-of-channel": 63,
|
||||
"output-power": 0.001,
|
||||
"path_bandwidth": 300000000000.0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "11",
|
||||
"source": "trx a",
|
||||
"destination": "trx h",
|
||||
"src-tp-id": "trx a",
|
||||
"dst-tp-id": "trx h",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "vendorA_trx-type1",
|
||||
"trx_mode": "PS_SP64_1",
|
||||
"spacing": 50000000000.0,
|
||||
"max-nb-of-channel": 80,
|
||||
"output-power": 0.001,
|
||||
"path_bandwidth": 300000000000.0
|
||||
}
|
||||
},
|
||||
"explicit-route-objects": {
|
||||
"route-object-include-exclude": [
|
||||
{
|
||||
"index": 0,
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"num-unnum-hop": {
|
||||
"node-id": "bb",
|
||||
"link-tp-id": "link-tp-id is not used",
|
||||
"hop-type": "LOOSE"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "12",
|
||||
"source": "trx f",
|
||||
"destination": "trx b",
|
||||
"src-tp-id": "trx f",
|
||||
"dst-tp-id": "trx b",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": "mode 3",
|
||||
"spacing": 62500000000.0,
|
||||
"max-nb-of-channel": 76,
|
||||
"output-power": 0.001,
|
||||
"path_bandwidth": 300000000000.0
|
||||
}
|
||||
},
|
||||
"explicit-route-objects": {
|
||||
"route-object-include-exclude": [
|
||||
{
|
||||
"index": 0,
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"num-unnum-hop": {
|
||||
"node-id": "trx b",
|
||||
"link-tp-id": "link-tp-id is not used",
|
||||
"hop-type": "LOOSE"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "13",
|
||||
"source": "trx c",
|
||||
"destination": "trx f",
|
||||
"src-tp-id": "trx c",
|
||||
"dst-tp-id": "trx f",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "vendorA_trx-type1",
|
||||
"trx_mode": "PS_SP64_1",
|
||||
"spacing": 50000000000.0,
|
||||
"max-nb-of-channel": 80,
|
||||
"output-power": 0.001,
|
||||
"path_bandwidth": 300000000000.0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "14",
|
||||
"source": "trx c",
|
||||
"destination": "trx f",
|
||||
"src-tp-id": "trx c",
|
||||
"dst-tp-id": "trx f",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "vendorA_trx-type1",
|
||||
"trx_mode": "PS_SP64_1",
|
||||
"spacing": 50000000000.0,
|
||||
"max-nb-of-channel": 80,
|
||||
"output-power": 0.001,
|
||||
"path_bandwidth": 300000000000.0
|
||||
}
|
||||
},
|
||||
"explicit-route-objects": {
|
||||
"route-object-include-exclude": [
|
||||
{
|
||||
"index": 0,
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"num-unnum-hop": {
|
||||
"node-id": "roadm e",
|
||||
"hop-type": "LOOSE"
|
||||
}
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"num-unnum-hop": {
|
||||
"node-id": "roadm g",
|
||||
"link-tp-id": "link-tp-id is not used",
|
||||
"hop-type": "LOOSE"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "e:1# /",
|
||||
"source": "trx a",
|
||||
"destination": "trx g",
|
||||
"src-tp-id": "trx a",
|
||||
"dst-tp-id": "trx g",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager_16QAM",
|
||||
"trx_mode": "16QAM",
|
||||
"spacing": 50000000000.0,
|
||||
"max-nb-of-channel": 80,
|
||||
"output-power": null,
|
||||
"path_bandwidth": 300000000000.0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "b-2a",
|
||||
"source": "trx a",
|
||||
"destination": "trx h",
|
||||
"src-tp-id": "trx a",
|
||||
"dst-tp-id": "trx h",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": "mode 1",
|
||||
"spacing": 50000000000.0,
|
||||
"max-nb-of-channel": null,
|
||||
"output-power": 0.001,
|
||||
"path_bandwidth": 300000000000.0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "3a;?",
|
||||
"source": "trx f",
|
||||
"destination": "trx b",
|
||||
"src-tp-id": "trx f",
|
||||
"dst-tp-id": "trx b",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "vendorA_trx-type1",
|
||||
"trx_mode": "PS_SP64_1",
|
||||
"spacing": 50000000000.0,
|
||||
"max-nb-of-channel": null,
|
||||
"output-power": null,
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"N": null,
|
||||
"M": null
|
||||
}
|
||||
],
|
||||
"path_bandwidth": 300000000000.0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "ee-s",
|
||||
"source": "trx c",
|
||||
"destination": "trx f",
|
||||
"src-tp-id": "trx c",
|
||||
"dst-tp-id": "trx f",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "vendorA_trx-type1",
|
||||
"trx_mode": null,
|
||||
"spacing": 50000000000.0,
|
||||
"max-nb-of-channel": 80,
|
||||
"output-power": 0.001,
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"N": 0,
|
||||
"M": 4
|
||||
}, {
|
||||
"N": 8,
|
||||
"M": 4
|
||||
}
|
||||
],
|
||||
"path_bandwidth": 300000000000.0
|
||||
}
|
||||
},
|
||||
"explicit-route-objects": {
|
||||
"route-object-include-exclude": [
|
||||
{
|
||||
"index": 0,
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"num-unnum-hop": {
|
||||
"node-id": "roadm e",
|
||||
"hop-type": "LOOSE"
|
||||
}
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"num-unnum-hop": {
|
||||
"node-id": "roadm g",
|
||||
"link-tp-id": "link-tp-id is not used",
|
||||
"hop-type": "LOOSE"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "ff-b",
|
||||
"source": "trx c",
|
||||
"destination": "trx f",
|
||||
"src-tp-id": "trx c",
|
||||
"dst-tp-id": "trx f",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": null,
|
||||
"spacing": 50000000000.0,
|
||||
"max-nb-of-channel": null,
|
||||
"output-power": 0.001,
|
||||
"path_bandwidth": 300000000000.0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "10-z",
|
||||
"source": "trx a",
|
||||
"destination": "trx g",
|
||||
"src-tp-id": "trx a",
|
||||
"dst-tp-id": "trx g",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": null,
|
||||
"spacing": 75000000000.0,
|
||||
"max-nb-of-channel": 63,
|
||||
"output-power": null,
|
||||
"path_bandwidth": 300000000000.0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "11 g",
|
||||
"source": "trx a",
|
||||
"destination": "trx h",
|
||||
"src-tp-id": "trx a",
|
||||
"dst-tp-id": "trx h",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": null,
|
||||
"spacing": 50000000000.0,
|
||||
"max-nb-of-channel": null,
|
||||
"output-power": null,
|
||||
"path_bandwidth": 300000000000.0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "12<",
|
||||
"source": "trx f",
|
||||
"destination": "trx b",
|
||||
"src-tp-id": "trx f",
|
||||
"dst-tp-id": "trx b",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": null,
|
||||
"spacing": 75000000000.0,
|
||||
"max-nb-of-channel": null,
|
||||
"output-power": null,
|
||||
"path_bandwidth": 300000000000.0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "12>",
|
||||
"source": "trx f",
|
||||
"destination": "trx b",
|
||||
"src-tp-id": "trx f",
|
||||
"dst-tp-id": "trx b",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": null,
|
||||
"spacing": 30000000000.0,
|
||||
"max-nb-of-channel": null,
|
||||
"output-power": null,
|
||||
"path_bandwidth": 300000000000.0
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"synchronization": [
|
||||
{
|
||||
"synchronization-id": "1",
|
||||
"svec": {
|
||||
"relaxable": false,
|
||||
"disjointness": "node link",
|
||||
"request-id-number": [
|
||||
"1",
|
||||
"2a"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"synchronization-id": "3",
|
||||
"svec": {
|
||||
"relaxable": false,
|
||||
"disjointness": "node link",
|
||||
"request-id-number": [
|
||||
"3",
|
||||
"1"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"synchronization-id": "ff",
|
||||
"svec": {
|
||||
"relaxable": false,
|
||||
"disjointness": "node link",
|
||||
"request-id-number": [
|
||||
"ff",
|
||||
"13"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"synchronization-id": "13",
|
||||
"svec": {
|
||||
"relaxable": false,
|
||||
"disjointness": "node link",
|
||||
"request-id-number": [
|
||||
"13",
|
||||
"14"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
558
tests/data/convert/testTopology_testservices_expected.json
Normal file
558
tests/data/convert/testTopology_testservices_expected.json
Normal file
@@ -0,0 +1,558 @@
|
||||
{
|
||||
"gnpy-path-computation:services": {
|
||||
"path-request": [
|
||||
{
|
||||
"request-id": "1",
|
||||
"source": "trx a",
|
||||
"destination": "trx g",
|
||||
"src-tp-id": "trx a",
|
||||
"dst-tp-id": "trx g",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager_16QAM",
|
||||
"trx_mode": "16QAM",
|
||||
"spacing": "50000000000.0",
|
||||
"max-nb-of-channel": 80,
|
||||
"output-power": "0.001",
|
||||
"path_bandwidth": "300000000000.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "2a",
|
||||
"source": "trx a",
|
||||
"destination": "trx h",
|
||||
"src-tp-id": "trx a",
|
||||
"dst-tp-id": "trx h",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "vendorA_trx-type1",
|
||||
"trx_mode": "PS_SP64_1",
|
||||
"spacing": "50000000000.0",
|
||||
"max-nb-of-channel": 80,
|
||||
"output-power": "0.0012356",
|
||||
"path_bandwidth": "300000000000.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "3",
|
||||
"source": "trx f",
|
||||
"destination": "trx b",
|
||||
"src-tp-id": "trx f",
|
||||
"dst-tp-id": "trx b",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "vendorA_trx-type1",
|
||||
"trx_mode": "PS_SP64_1",
|
||||
"spacing": "50000000000.0",
|
||||
"max-nb-of-channel": 80,
|
||||
"output-power": "0.001",
|
||||
"path_bandwidth": "300000000000.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "ee",
|
||||
"source": "trx c",
|
||||
"destination": "trx f",
|
||||
"src-tp-id": "trx c",
|
||||
"dst-tp-id": "trx f",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "vendorA_trx-type1",
|
||||
"trx_mode": "PS_SP64_1",
|
||||
"spacing": "50000000000.0",
|
||||
"max-nb-of-channel": 80,
|
||||
"output-power": "0.001",
|
||||
"path_bandwidth": "300000000000.0"
|
||||
}
|
||||
},
|
||||
"explicit-route-objects": {
|
||||
"route-object-include-exclude": [
|
||||
{
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"index": 0,
|
||||
"num-unnum-hop": {
|
||||
"node-id": "roadm e",
|
||||
"hop-type": "LOOSE"
|
||||
}
|
||||
},
|
||||
{
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"index": 1,
|
||||
"num-unnum-hop": {
|
||||
"node-id": "roadm g",
|
||||
"link-tp-id": "link-tp-id is not used",
|
||||
"hop-type": "LOOSE"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "ff",
|
||||
"source": "trx c",
|
||||
"destination": "trx f",
|
||||
"src-tp-id": "trx c",
|
||||
"dst-tp-id": "trx f",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": "mode 2 - fake",
|
||||
"spacing": "75000000000.0",
|
||||
"max-nb-of-channel": 63,
|
||||
"output-power": "0.001",
|
||||
"path_bandwidth": "300000000000.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "10",
|
||||
"source": "trx a",
|
||||
"destination": "trx g",
|
||||
"src-tp-id": "trx a",
|
||||
"dst-tp-id": "trx g",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": "mode 2",
|
||||
"spacing": "75000000000.0",
|
||||
"max-nb-of-channel": 63,
|
||||
"output-power": "0.001",
|
||||
"path_bandwidth": "300000000000.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "11",
|
||||
"source": "trx a",
|
||||
"destination": "trx h",
|
||||
"src-tp-id": "trx a",
|
||||
"dst-tp-id": "trx h",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "vendorA_trx-type1",
|
||||
"trx_mode": "PS_SP64_1",
|
||||
"spacing": "50000000000.0",
|
||||
"max-nb-of-channel": 80,
|
||||
"output-power": "0.001",
|
||||
"path_bandwidth": "300000000000.0"
|
||||
}
|
||||
},
|
||||
"explicit-route-objects": {
|
||||
"route-object-include-exclude": [
|
||||
{
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"index": 0,
|
||||
"num-unnum-hop": {
|
||||
"node-id": "bb",
|
||||
"link-tp-id": "link-tp-id is not used",
|
||||
"hop-type": "LOOSE"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "12",
|
||||
"source": "trx f",
|
||||
"destination": "trx b",
|
||||
"src-tp-id": "trx f",
|
||||
"dst-tp-id": "trx b",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": "mode 3",
|
||||
"spacing": "62500000000.0",
|
||||
"max-nb-of-channel": 76,
|
||||
"output-power": "0.001",
|
||||
"path_bandwidth": "300000000000.0"
|
||||
}
|
||||
},
|
||||
"explicit-route-objects": {
|
||||
"route-object-include-exclude": [
|
||||
{
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"index": 0,
|
||||
"num-unnum-hop": {
|
||||
"node-id": "trx b",
|
||||
"link-tp-id": "link-tp-id is not used",
|
||||
"hop-type": "LOOSE"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "13",
|
||||
"source": "trx c",
|
||||
"destination": "trx f",
|
||||
"src-tp-id": "trx c",
|
||||
"dst-tp-id": "trx f",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "vendorA_trx-type1",
|
||||
"trx_mode": "PS_SP64_1",
|
||||
"spacing": "50000000000.0",
|
||||
"max-nb-of-channel": 80,
|
||||
"output-power": "0.001",
|
||||
"path_bandwidth": "300000000000.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "14",
|
||||
"source": "trx c",
|
||||
"destination": "trx f",
|
||||
"src-tp-id": "trx c",
|
||||
"dst-tp-id": "trx f",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "vendorA_trx-type1",
|
||||
"trx_mode": "PS_SP64_1",
|
||||
"spacing": "50000000000.0",
|
||||
"max-nb-of-channel": 80,
|
||||
"output-power": "0.001",
|
||||
"path_bandwidth": "300000000000.0"
|
||||
}
|
||||
},
|
||||
"explicit-route-objects": {
|
||||
"route-object-include-exclude": [
|
||||
{
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"index": 0,
|
||||
"num-unnum-hop": {
|
||||
"node-id": "roadm e",
|
||||
"hop-type": "LOOSE"
|
||||
}
|
||||
},
|
||||
{
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"index": 1,
|
||||
"num-unnum-hop": {
|
||||
"node-id": "roadm g",
|
||||
"link-tp-id": "link-tp-id is not used",
|
||||
"hop-type": "LOOSE"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "e:1# /",
|
||||
"source": "trx a",
|
||||
"destination": "trx g",
|
||||
"src-tp-id": "trx a",
|
||||
"dst-tp-id": "trx g",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager_16QAM",
|
||||
"trx_mode": "16QAM",
|
||||
"spacing": "50000000000.0",
|
||||
"max-nb-of-channel": 80,
|
||||
"output-power": [
|
||||
null
|
||||
],
|
||||
"path_bandwidth": "300000000000.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "b-2a",
|
||||
"source": "trx a",
|
||||
"destination": "trx h",
|
||||
"src-tp-id": "trx a",
|
||||
"dst-tp-id": "trx h",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": "mode 1",
|
||||
"spacing": "50000000000.0",
|
||||
"max-nb-of-channel": [
|
||||
null
|
||||
],
|
||||
"output-power": "0.001",
|
||||
"path_bandwidth": "300000000000.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "3a;?",
|
||||
"source": "trx f",
|
||||
"destination": "trx b",
|
||||
"src-tp-id": "trx f",
|
||||
"dst-tp-id": "trx b",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "vendorA_trx-type1",
|
||||
"trx_mode": "PS_SP64_1",
|
||||
"spacing": "50000000000.0",
|
||||
"max-nb-of-channel": [
|
||||
null
|
||||
],
|
||||
"output-power": [
|
||||
null
|
||||
],
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"N": [
|
||||
null
|
||||
],
|
||||
"M": [
|
||||
null
|
||||
]
|
||||
}
|
||||
],
|
||||
"path_bandwidth": "300000000000.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "ee-s",
|
||||
"source": "trx c",
|
||||
"destination": "trx f",
|
||||
"src-tp-id": "trx c",
|
||||
"dst-tp-id": "trx f",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "vendorA_trx-type1",
|
||||
"trx_mode": [
|
||||
null
|
||||
],
|
||||
"spacing": "50000000000.0",
|
||||
"max-nb-of-channel": 80,
|
||||
"output-power": "0.001",
|
||||
"effective-freq-slot": [
|
||||
{
|
||||
"N": 0,
|
||||
"M": 4
|
||||
},
|
||||
{
|
||||
"N": 8,
|
||||
"M": 4
|
||||
}
|
||||
],
|
||||
"path_bandwidth": "300000000000.0"
|
||||
}
|
||||
},
|
||||
"explicit-route-objects": {
|
||||
"route-object-include-exclude": [
|
||||
{
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"index": 0,
|
||||
"num-unnum-hop": {
|
||||
"node-id": "roadm e",
|
||||
"hop-type": "LOOSE"
|
||||
}
|
||||
},
|
||||
{
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"index": 1,
|
||||
"num-unnum-hop": {
|
||||
"node-id": "roadm g",
|
||||
"link-tp-id": "link-tp-id is not used",
|
||||
"hop-type": "LOOSE"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "ff-b",
|
||||
"source": "trx c",
|
||||
"destination": "trx f",
|
||||
"src-tp-id": "trx c",
|
||||
"dst-tp-id": "trx f",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": [
|
||||
null
|
||||
],
|
||||
"spacing": "50000000000.0",
|
||||
"max-nb-of-channel": [
|
||||
null
|
||||
],
|
||||
"output-power": "0.001",
|
||||
"path_bandwidth": "300000000000.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "10-z",
|
||||
"source": "trx a",
|
||||
"destination": "trx g",
|
||||
"src-tp-id": "trx a",
|
||||
"dst-tp-id": "trx g",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": [
|
||||
null
|
||||
],
|
||||
"spacing": "75000000000.0",
|
||||
"max-nb-of-channel": 63,
|
||||
"output-power": [
|
||||
null
|
||||
],
|
||||
"path_bandwidth": "300000000000.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "11 g",
|
||||
"source": "trx a",
|
||||
"destination": "trx h",
|
||||
"src-tp-id": "trx a",
|
||||
"dst-tp-id": "trx h",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": [
|
||||
null
|
||||
],
|
||||
"spacing": "50000000000.0",
|
||||
"max-nb-of-channel": [
|
||||
null
|
||||
],
|
||||
"output-power": [
|
||||
null
|
||||
],
|
||||
"path_bandwidth": "300000000000.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "12<",
|
||||
"source": "trx f",
|
||||
"destination": "trx b",
|
||||
"src-tp-id": "trx f",
|
||||
"dst-tp-id": "trx b",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": [
|
||||
null
|
||||
],
|
||||
"spacing": "75000000000.0",
|
||||
"max-nb-of-channel": [
|
||||
null
|
||||
],
|
||||
"output-power": [
|
||||
null
|
||||
],
|
||||
"path_bandwidth": "300000000000.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"request-id": "12>",
|
||||
"source": "trx f",
|
||||
"destination": "trx b",
|
||||
"src-tp-id": "trx f",
|
||||
"dst-tp-id": "trx b",
|
||||
"bidirectional": false,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": [
|
||||
null
|
||||
],
|
||||
"spacing": "30000000000.0",
|
||||
"max-nb-of-channel": [
|
||||
null
|
||||
],
|
||||
"output-power": [
|
||||
null
|
||||
],
|
||||
"path_bandwidth": "300000000000.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"synchronization": [
|
||||
{
|
||||
"synchronization-id": "1",
|
||||
"svec": {
|
||||
"relaxable": false,
|
||||
"disjointness": "node link",
|
||||
"request-id-number": [
|
||||
"1",
|
||||
"2a"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"synchronization-id": "3",
|
||||
"svec": {
|
||||
"relaxable": false,
|
||||
"disjointness": "node link",
|
||||
"request-id-number": [
|
||||
"3",
|
||||
"1"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"synchronization-id": "ff",
|
||||
"svec": {
|
||||
"relaxable": false,
|
||||
"disjointness": "node link",
|
||||
"request-id-number": [
|
||||
"ff",
|
||||
"13"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"synchronization-id": "13",
|
||||
"svec": {
|
||||
"relaxable": false,
|
||||
"disjointness": "node link",
|
||||
"request-id-number": [
|
||||
"13",
|
||||
"14"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
3644
tests/data/convert/toto.json
Normal file
3644
tests/data/convert/toto.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -29,7 +29,7 @@
|
||||
"p_max": 21,
|
||||
"nf_min": 6,
|
||||
"nf_max": 10,
|
||||
"advanced_config_from_json": "default_edfa_config.json",
|
||||
"default_config_from_json": "user_edfa_config.json",
|
||||
"out_voa_auto": false,
|
||||
"allowed_for_design": false
|
||||
}
|
||||
|
||||
480
tests/test_legacy_yang.py
Normal file
480
tests/test_legacy_yang.py
Normal file
@@ -0,0 +1,480 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# test_legacy_yang
|
||||
# Copyright (C) 2025 Telecom Infra Project and GNPy contributors
|
||||
# see AUTHORS.rst for a list of contributors
|
||||
|
||||
"""
|
||||
Test conversion legacy to yang utils
|
||||
====================================
|
||||
check that combinations of inputs are correctly converted
|
||||
"""
|
||||
from pathlib import Path
|
||||
import json
|
||||
import subprocess # nosec
|
||||
import os
|
||||
import pytest
|
||||
|
||||
from gnpy.tools.json_io import load_gnpy_json
|
||||
from gnpy.tools.cli_examples import transmission_main_example, path_requests_run
|
||||
from gnpy.tools.convert_legacy_yang import legacy_to_yang, yang_to_legacy
|
||||
from gnpy.tools.yang_convert_utils import convert_delta_power_range
|
||||
|
||||
|
||||
SRC_ROOT = Path(__file__).parent.parent
|
||||
TEST_DIR = Path(__file__).parent
|
||||
DATA_DIR = TEST_DIR / 'data' / 'convert'
|
||||
EXAMPLE_DIR = SRC_ROOT / 'gnpy' / 'example-data'
|
||||
|
||||
|
||||
@pytest.mark.parametrize('yang_input, expected_output, expected_autodesign, eqpt', [
|
||||
('GNPy_yang_formatted-edfa_example_network.json', 'GNPy_legacy_formatted-edfa_example_network_expected.json',
|
||||
'edfa_example_network_autodesign_expected.json', None),
|
||||
('GNPy_yang_formatted-testTopology_auto_design_expected.json',
|
||||
'GNPy_legacy_formatted-testTopology_auto_design_expected.json',
|
||||
'testTopology_auto_design_expected.json',
|
||||
'eqpt_config.json')])
|
||||
def test_gnpy(tmpdir, yang_input, expected_output, expected_autodesign, eqpt):
|
||||
"""Convert back from yang to legacy format, and checks that GNPy can run on the converted file
|
||||
"""
|
||||
with open(DATA_DIR / yang_input, 'r', encoding='utf-8') as f:
|
||||
json_data = json.load(f)
|
||||
converted = yang_to_legacy(json_data)
|
||||
with open(DATA_DIR / expected_output, 'r', encoding='utf-8') as f:
|
||||
expected = json.load(f)
|
||||
assert converted == expected
|
||||
with open(tmpdir / 'essaitopo.json', 'w', encoding='utf-8') as f:
|
||||
json.dump(converted, f, indent=2, ensure_ascii=False)
|
||||
args = [str(tmpdir / 'essaitopo.json'), '--save-network', str(tmpdir / 'autodesign.json')]
|
||||
if eqpt is not None:
|
||||
args.append('-e')
|
||||
args.append(str(DATA_DIR / eqpt))
|
||||
transmission_main_example(args)
|
||||
expected = load_gnpy_json(DATA_DIR / expected_autodesign)
|
||||
actual = load_gnpy_json(tmpdir / 'autodesign.json')
|
||||
assert actual == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize('topo_input, service_input, expected_autodesign, eqpt', [
|
||||
('testTopology_auto_design.json', 'testTopology_testservices.json',
|
||||
'testTopology_auto_design_expected.json', 'eqpt_config.json')])
|
||||
def test_gnpy_path_requests_run(tmpdir, topo_input, service_input, expected_autodesign, eqpt):
|
||||
"""Convert to and back from legacy- to yang to legacy format and checks that conversion runs with gnpy
|
||||
"""
|
||||
with open(DATA_DIR / topo_input, 'r', encoding='utf-8') as f:
|
||||
json_data = json.load(f)
|
||||
converted = yang_to_legacy(legacy_to_yang(json_data))
|
||||
with open(tmpdir / 'essaitopo.json', 'w', encoding='utf-8') as f:
|
||||
json.dump(converted, f, indent=2, ensure_ascii=False)
|
||||
with open(DATA_DIR / service_input, 'r', encoding='utf-8') as f:
|
||||
json_data = json.load(f)
|
||||
converted = yang_to_legacy(legacy_to_yang(json_data))
|
||||
with open(tmpdir / 'essaiservice.json', 'w', encoding='utf-8') as f:
|
||||
json.dump(converted, f, indent=2, ensure_ascii=False)
|
||||
with open(DATA_DIR / eqpt, 'r', encoding='utf-8') as f:
|
||||
json_data = json.load(f)
|
||||
converted = yang_to_legacy(legacy_to_yang(json_data))
|
||||
with open(tmpdir / 'essaieqpt.json', 'w', encoding='utf-8') as f:
|
||||
json.dump(converted, f, indent=2, ensure_ascii=False)
|
||||
args = [str(tmpdir / 'essaitopo.json'), str(tmpdir / 'essaiservice.json'),
|
||||
'-e', str(tmpdir / 'essaieqpt.json'), '--save-network', str(tmpdir / 'autodesign.json')]
|
||||
path_requests_run(args)
|
||||
expected = load_gnpy_json(DATA_DIR / expected_autodesign)
|
||||
actual = load_gnpy_json(tmpdir / 'autodesign.json')
|
||||
assert actual == expected
|
||||
|
||||
|
||||
def test_gnpy_eqpt():
|
||||
"""Convert back from yang to legacy format and checks that conversion runs with gnpy
|
||||
"""
|
||||
json_data = {
|
||||
"Edfa": [{
|
||||
"type_variety": "std_medium_gain",
|
||||
"type_def": "gnpy-eqpt-config:variable_gain",
|
||||
"gain_flatmax": "26.0",
|
||||
"gain_min": "15",
|
||||
"p_max": "21",
|
||||
"nf_min": "6",
|
||||
"nf_max": "10",
|
||||
"out_voa_auto": False,
|
||||
"allowed_for_design": True}],
|
||||
"Fiber": [{
|
||||
"type_variety": "SSMF",
|
||||
"dispersion": "0.0000167",
|
||||
"effective_area": "0.0000000000830",
|
||||
"pmd_coef": "0.000000000000001265"}],
|
||||
"Span": [{
|
||||
"power_mode": False,
|
||||
"delta_power_range_dict_db": {"min_value": "0.0", "max_value": "0.0", "step": "0.5"},
|
||||
"max_fiber_lineic_loss_for_raman": "0.25",
|
||||
"target_extended_gain": "2.5",
|
||||
"max_length": "150",
|
||||
"length_units": "km",
|
||||
"max_loss": "28",
|
||||
"padding": "10",
|
||||
"EOL": "0",
|
||||
"con_in": "0",
|
||||
"con_out": "0"}],
|
||||
"Roadm": [{
|
||||
"type_variety": "example_test",
|
||||
"target_pch_out_db": "-18.0",
|
||||
"add_drop_osnr": "35.0",
|
||||
"pmd": "0.000000000001",
|
||||
"pdl": "0.5",
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
},
|
||||
"roadm-path-impairments": []}],
|
||||
"SI": [{
|
||||
"f_min": "191300000000000.0",
|
||||
"f_max": "196100000000000.0",
|
||||
"baud_rate": "32000000000.0",
|
||||
"spacing": "50000000000.0",
|
||||
"power_dbm": "0.0",
|
||||
"power_range_dict_db": {"min_value": "0.0", "max_value": "0.0", "step": "0.5"},
|
||||
"roll_off": "0.15",
|
||||
"tx_osnr": "100.0",
|
||||
"sys_margins": "0.0"}],
|
||||
"Transceiver": [{
|
||||
"type_variety": "vendorA_trx-type1",
|
||||
"frequency": {
|
||||
"min": "191350000000000",
|
||||
"max": "196100000000000"
|
||||
},
|
||||
"mode": [{
|
||||
"format": "PS_SP64_1",
|
||||
"baud_rate": "32000000000",
|
||||
"OSNR": "11",
|
||||
"bit_rate": "100000000000.0",
|
||||
"roll_off": "0.15",
|
||||
"tx_osnr": "100",
|
||||
"min_spacing": "50000000000",
|
||||
"cost": "1"
|
||||
}, {
|
||||
"format": "PS_SP64_2",
|
||||
"baud_rate": "64000000000",
|
||||
"OSNR": "15",
|
||||
"bit_rate": "200000000000",
|
||||
"roll_off": "0.15",
|
||||
"tx_osnr": "100",
|
||||
"min_spacing": "75000000000",
|
||||
"cost": "1"
|
||||
}
|
||||
]}]}
|
||||
|
||||
expected_data = {
|
||||
"Edfa": [{
|
||||
"type_variety": "std_medium_gain",
|
||||
"type_def": "variable_gain",
|
||||
"gain_flatmax": 26.0,
|
||||
"gain_min": 15.0,
|
||||
"p_max": 21.0,
|
||||
"nf_min": 6.0,
|
||||
"nf_max": 10.0,
|
||||
"out_voa_auto": False,
|
||||
"allowed_for_design": True}],
|
||||
"Fiber": [{
|
||||
"type_variety": "SSMF",
|
||||
"dispersion": 1.67e-05,
|
||||
"effective_area": 83e-12,
|
||||
"pmd_coef": 1.265e-15}],
|
||||
"Span": [{
|
||||
"power_mode": False,
|
||||
"delta_power_range_db": [0.0, 0.0, 0.5],
|
||||
"max_fiber_lineic_loss_for_raman": 0.25,
|
||||
"target_extended_gain": 2.5,
|
||||
"max_length": 150.0,
|
||||
"length_units": "km",
|
||||
"max_loss": 28.0,
|
||||
"padding": 10.0,
|
||||
"EOL": 0.0,
|
||||
"con_in": 0.0,
|
||||
"con_out": 0.0}],
|
||||
"Roadm": [{
|
||||
"type_variety": "example_test",
|
||||
"target_pch_out_db": -18.0,
|
||||
"add_drop_osnr": 35.0,
|
||||
"pmd": 1e-12,
|
||||
"pdl": 0.5,
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
},
|
||||
"roadm-path-impairments": []}],
|
||||
"SI": [{
|
||||
"f_min": 191.3e12,
|
||||
"f_max": 196.1e12,
|
||||
"baud_rate": 32e9,
|
||||
"spacing": 50e9,
|
||||
"power_dbm": 0.0,
|
||||
"power_range_db": [0.0, 0.0, 0.5],
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100.0,
|
||||
"sys_margins": 0.0}],
|
||||
"Transceiver": [{
|
||||
"type_variety": "vendorA_trx-type1",
|
||||
"frequency": {
|
||||
"min": 191.35e12,
|
||||
"max": 196.1e12
|
||||
},
|
||||
"mode": [{
|
||||
"format": "PS_SP64_1",
|
||||
"baud_rate": 32e9,
|
||||
"OSNR": 11,
|
||||
"bit_rate": 100e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 50e9,
|
||||
"cost": 1
|
||||
}, {
|
||||
"format": "PS_SP64_2",
|
||||
"baud_rate": 64e9,
|
||||
"OSNR": 15,
|
||||
"bit_rate": 200e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"min_spacing": 75e9,
|
||||
"cost": 1
|
||||
}]
|
||||
}]
|
||||
}
|
||||
|
||||
converted = yang_to_legacy(json_data)
|
||||
assert converted == expected_data
|
||||
|
||||
|
||||
@pytest.mark.parametrize('input, expected_output', [
|
||||
('edfa_example_network.json', 'GNPy_yang_formatted-edfa_example_network_expected.json'),
|
||||
('testTopology_auto_design.json', 'GNPy_yang_formatted-testTopology_auto_design_expected.json'),
|
||||
('GNPy_yang_formatted-testTopology_auto_design_expected.json',
|
||||
'GNPy_yang_formatted-testTopology_auto_design_expected.json'),
|
||||
('testTopology_testservices.json', 'testTopology_testservices_expected.json'),
|
||||
('testTopology_testservices_expected.json', 'testTopology_testservices_expected.json'),
|
||||
('eqpt_config.json', 'GNPy_yang_formatted-eqpt_config_expected.json'),
|
||||
('extra_eqpt_config.json', 'GNPy_yang_formatted-extra_eqpt_config_expected.json'),
|
||||
('GNPy_yang_formatted-eqpt_config_expected.json', 'GNPy_yang_formatted-eqpt_config_expected.json'),
|
||||
('sim_params.json', 'GNPy_yang_formatted-sim_params_expected.json'),
|
||||
('GNPy_yang_formatted-sim_params_expected.json', 'GNPy_yang_formatted-sim_params_expected.json'),
|
||||
('spectrum.json', 'GNPy_yang_formatted-spectrum_expected.json'),
|
||||
('GNPy_yang_formatted-spectrum_expected.json', 'GNPy_yang_formatted-spectrum_expected.json'),
|
||||
('testTopology_response.json', 'GNPy_yang_formatted-testTopology_response.json'),
|
||||
('std_medium_gain_advanced_config.json', 'GNPy_yang_formatted-edfa-config_expected.json')])
|
||||
def test_gnpy_convert(input, expected_output):
|
||||
"""Convert legacy gnpy format to yang format and checks that conversion is as expected
|
||||
"""
|
||||
with open(DATA_DIR / input, 'r', encoding='utf-8') as f:
|
||||
json_data = json.load(f)
|
||||
actual = legacy_to_yang(json_data)
|
||||
with open(DATA_DIR / expected_output, 'r', encoding='utf-8') as f:
|
||||
expected = json.load(f)
|
||||
assert actual == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize("args, fileout", (
|
||||
[['--legacy-to-yang', EXAMPLE_DIR / 'edfa_example_network.json', '-o'], 'essaitopo.json'],
|
||||
[['--legacy-to-yang', DATA_DIR / 'testTopology_auto_design.json', '-o'], 'essaitopo2.json'],
|
||||
[['--legacy-to-yang', DATA_DIR / 'eqpt_config.json', '-o'], 'essaieqpt.json'],
|
||||
[['--legacy-to-yang', DATA_DIR / 'testTopology_testservices.json', '-o'], 'essaireq.json']))
|
||||
def test_example_invocation(tmpdir, args, fileout):
|
||||
"""test the main function of converter"""
|
||||
os.environ['PYTHONPATH'] = str(SRC_ROOT)
|
||||
proc = subprocess.run(
|
||||
('python', SRC_ROOT / 'gnpy' / 'tools' / 'convert_legacy_yang.py', *args, tmpdir / fileout),
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True, universal_newlines=True) # nosec
|
||||
assert proc.stderr == ''
|
||||
|
||||
|
||||
@pytest.mark.parametrize("args", (
|
||||
[['--validate', DATA_DIR / 'GNPy_api_example.json']]))
|
||||
def test_example_invocation2(args):
|
||||
"""test the main function of converter"""
|
||||
os.environ['PYTHONPATH'] = str(SRC_ROOT)
|
||||
proc = subprocess.run(
|
||||
('python', SRC_ROOT / 'gnpy' / 'tools' / 'convert_legacy_yang.py', *args),
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True, universal_newlines=True) # nosec
|
||||
assert proc.stderr == ''
|
||||
|
||||
|
||||
def test_span_with_delta_power_range_dict_db():
|
||||
"""Test when span already has delta_power_range_dict_db"""
|
||||
input_data = {
|
||||
'Span': [{
|
||||
"power_mode": False,
|
||||
"max_fiber_lineic_loss_for_raman": 0.25,
|
||||
"target_extended_gain": 2.5,
|
||||
"max_length": 150,
|
||||
"length_units": "km",
|
||||
"max_loss": 28,
|
||||
"padding": 10,
|
||||
"EOL": 0,
|
||||
"con_in": 0,
|
||||
"con_out": 0,
|
||||
'delta_power_range_dict_db': {
|
||||
'min_value': -5,
|
||||
'max_value': 5,
|
||||
'step': 0.1
|
||||
}
|
||||
}]
|
||||
}
|
||||
result = convert_delta_power_range(input_data)
|
||||
assert result == input_data
|
||||
|
||||
|
||||
def test_span_missing_both_power_ranges():
|
||||
"""Test when span is missing both power range formats"""
|
||||
input_data = {
|
||||
'Span': [{
|
||||
"power_mode": False,
|
||||
"max_fiber_lineic_loss_for_raman": 0.25,
|
||||
"target_extended_gain": 2.5,
|
||||
"max_length": 150,
|
||||
"length_units": "km",
|
||||
"max_loss": 28,
|
||||
"padding": 10,
|
||||
"EOL": 0,
|
||||
"con_in": 0,
|
||||
"con_out": 0
|
||||
}]
|
||||
}
|
||||
with pytest.raises(KeyError) as exc:
|
||||
convert_delta_power_range(input_data)
|
||||
assert 'delta_power_range or delta_power_range_dict_db missing' in str(exc.value)
|
||||
|
||||
|
||||
def test_si_with_power_range_dict_db():
|
||||
"""Test when SI already has power_range_dict_db"""
|
||||
input_data = {
|
||||
'SI': [{
|
||||
"f_min": 191.3e12,
|
||||
"f_max": 196.1e12,
|
||||
"baud_rate": 32e9,
|
||||
"spacing": 50e9,
|
||||
"power_dbm": 0,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"sys_margins": 0,
|
||||
'power_range_dict_db': {
|
||||
'min_value': -10,
|
||||
'max_value': 10,
|
||||
'step': 0.5
|
||||
}
|
||||
}]
|
||||
}
|
||||
result = convert_delta_power_range(input_data)
|
||||
assert result == input_data
|
||||
|
||||
|
||||
def test_si_missing_both_power_ranges():
|
||||
"""Test when SI is missing both power range formats"""
|
||||
input_data = {
|
||||
'SI': [{
|
||||
"f_min": 191.3e12,
|
||||
"f_max": 196.1e12,
|
||||
"baud_rate": 32e9,
|
||||
"spacing": 50e9,
|
||||
"power_dbm": 0,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"sys_margins": 0
|
||||
}]
|
||||
}
|
||||
with pytest.raises(KeyError) as exc:
|
||||
convert_delta_power_range(input_data)
|
||||
assert 'power_range_db or power_range_dict_db missing' in str(exc.value)
|
||||
|
||||
|
||||
def test_successful_conversion():
|
||||
"""Test successful conversion of both Span and SI"""
|
||||
input_data = {
|
||||
'Span': [{
|
||||
"power_mode": False,
|
||||
'delta_power_range_db': [-5, 5, 0.1],
|
||||
"max_fiber_lineic_loss_for_raman": 0.25,
|
||||
"target_extended_gain": 2.5,
|
||||
"max_length": 150,
|
||||
"length_units": "km",
|
||||
"max_loss": 28,
|
||||
"padding": 10,
|
||||
"EOL": 0,
|
||||
"con_in": 0,
|
||||
"con_out": 0
|
||||
}],
|
||||
'SI': [{
|
||||
"f_min": 191.3e12,
|
||||
"f_max": 196.1e12,
|
||||
"baud_rate": 32e9,
|
||||
"spacing": 50e9,
|
||||
"power_dbm": 0,
|
||||
'power_range_db': [-10, 10, 0.5],
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"sys_margins": 0
|
||||
}, {
|
||||
"type_variety": "LBAND",
|
||||
"f_min": 186.0e12,
|
||||
"f_max": 190.0e12,
|
||||
"baud_rate": 32e9,
|
||||
"spacing": 50e9,
|
||||
"power_dbm": 0,
|
||||
'power_range_db': [0, 0, 0.5],
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"sys_margins": 0
|
||||
}]
|
||||
}
|
||||
|
||||
expected_output = {
|
||||
'Span': [{
|
||||
"power_mode": False,
|
||||
"max_fiber_lineic_loss_for_raman": 0.25,
|
||||
"target_extended_gain": 2.5,
|
||||
"max_length": 150,
|
||||
"length_units": "km",
|
||||
"max_loss": 28,
|
||||
"padding": 10,
|
||||
"EOL": 0,
|
||||
"con_in": 0,
|
||||
"con_out": 0,
|
||||
'delta_power_range_dict_db': {
|
||||
'min_value': -5,
|
||||
'max_value': 5,
|
||||
'step': 0.1
|
||||
}
|
||||
}],
|
||||
'SI': [{
|
||||
"f_min": 191.3e12,
|
||||
"f_max": 196.1e12,
|
||||
"baud_rate": 32e9,
|
||||
"spacing": 50e9,
|
||||
"power_dbm": 0,
|
||||
'power_range_dict_db': {
|
||||
'min_value': -10,
|
||||
'max_value': 10,
|
||||
'step': 0.5
|
||||
},
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"sys_margins": 0
|
||||
}, {
|
||||
"type_variety": "LBAND",
|
||||
"f_min": 186.0e12,
|
||||
"f_max": 190.0e12,
|
||||
"baud_rate": 32e9,
|
||||
"spacing": 50e9,
|
||||
"power_dbm": 0,
|
||||
'power_range_dict_db': {
|
||||
'min_value': 0,
|
||||
'max_value': 0,
|
||||
'step': 0.5
|
||||
},
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 100,
|
||||
"sys_margins": 0
|
||||
}]
|
||||
}
|
||||
|
||||
result = convert_delta_power_range(input_data)
|
||||
assert result == expected_output
|
||||
Reference in New Issue
Block a user