mirror of
https://github.com/Telecominfraproject/oopt-gnpy.git
synced 2026-01-27 10:21:48 +00:00
Here the Fiber behaviour change because pch = signal + ase + nli is considered instead of just signal. This slightly changes the propagation results as more power is considered to be injected in the fiber span. All differences in tests are below 0.1 dB, with a few exceptions slightly higher. Change-Id: I5b2227ee036a26a11e13f3169e16868d70f0c457
175 lines
8.2 KiB
Python
175 lines
8.2 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
# test_science_utils
|
|
# Copyright (C) 2025 Telecom Infra Project and GNPy contributors
|
|
# see AUTHORS.rst for a list of contributors
|
|
|
|
"""
|
|
Checks that RamanFiber propagates properly the spectral information. In this way, also the RamanSolver and the NliSolver
|
|
are tested.
|
|
"""
|
|
|
|
from pathlib import Path
|
|
from pandas import read_csv
|
|
from numpy.testing import assert_allclose
|
|
from numpy import array
|
|
from copy import deepcopy
|
|
import pytest
|
|
|
|
from gnpy.core.info import create_input_spectral_information, create_arbitrary_spectral_information
|
|
from gnpy.core.elements import Fiber, RamanFiber
|
|
from gnpy.core.parameters import SimParams
|
|
from gnpy.tools.json_io import load_json
|
|
from gnpy.core.exceptions import NetworkTopologyError
|
|
from gnpy.core.science_utils import RamanSolver
|
|
|
|
TEST_DIR = Path(__file__).parent
|
|
|
|
|
|
@pytest.mark.usefixtures('set_sim_params')
|
|
def test_fiber():
|
|
"""Test the accuracy of propagating the Fiber."""
|
|
fiber = Fiber(**load_json(TEST_DIR / 'data' / 'test_science_utils_fiber_config.json'))
|
|
fiber.ref_pch_in_dbm = 0.0
|
|
# fix grid spectral information generation
|
|
spectral_info_input = create_input_spectral_information(f_min=191.3e12, f_max=196.1e12, roll_off=0.15,
|
|
baud_rate=32e9, spacing=50e9, tx_osnr=40.0,
|
|
tx_power=1e-3)
|
|
# propagation
|
|
spectral_info_out = fiber(spectral_info_input)
|
|
|
|
p_signal = spectral_info_out.signal
|
|
p_nli = spectral_info_out.nli
|
|
|
|
expected_results = read_csv(TEST_DIR / 'data' / 'test_fiber_fix_expected_results.csv')
|
|
assert_allclose(p_signal, expected_results['signal'], rtol=1e-3)
|
|
assert_allclose(p_nli, expected_results['nli'], rtol=1e-3)
|
|
|
|
# flex grid spectral information generation
|
|
frequency = 191e12 + array([0, 50e9, 150e9, 225e9, 275e9])
|
|
slot_width = array([37.5e9, 50e9, 75e9, 50e9, 37.5e9])
|
|
baud_rate = array([32e9, 42e9, 64e9, 42e9, 32e9])
|
|
pch = 1e-3 + array([0, -1e-4, 3e-4, -2e-4, +2e-4])
|
|
delta_pdb_per_channel = [0, 0, 0, 0, 0]
|
|
spectral_info_input = create_arbitrary_spectral_information(frequency=frequency, slot_width=slot_width,
|
|
pch=pch, baud_rate=baud_rate, roll_off=0.15,
|
|
delta_pdb_per_channel=delta_pdb_per_channel,
|
|
tx_osnr=40.0, tx_power=1e-3)
|
|
# propagation without Raman
|
|
spectral_info_out = fiber(spectral_info_input)
|
|
|
|
p_signal = spectral_info_out.signal
|
|
p_nli = spectral_info_out.nli
|
|
|
|
expected_results = read_csv(TEST_DIR / 'data' / 'test_fiber_flex_expected_results.csv')
|
|
assert_allclose(p_signal, expected_results['signal'], rtol=1e-3)
|
|
assert_allclose(p_nli, expected_results['nli'], rtol=1e-3)
|
|
|
|
# propagation with Raman
|
|
SimParams.set_params({'raman_params': {'flag': True}})
|
|
spectral_info_out = fiber(spectral_info_input)
|
|
|
|
p_signal = spectral_info_out.signal
|
|
p_nli = spectral_info_out.nli
|
|
|
|
expected_results = read_csv(TEST_DIR / 'data' / 'test_fiber_flex_expected_with_raman_results.csv')
|
|
assert_allclose(p_signal, expected_results['signal'], rtol=1e-3)
|
|
assert_allclose(p_nli, expected_results['nli'], rtol=1e-3)
|
|
|
|
|
|
@pytest.mark.usefixtures('set_sim_params')
|
|
def test_raman_fiber():
|
|
"""Test the accuracy of propagating the RamanFiber."""
|
|
# spectral information generation
|
|
spectral_info_input = create_input_spectral_information(f_min=191.3e12, f_max=196.1e12, roll_off=0.15,
|
|
baud_rate=32e9, spacing=50e9, tx_osnr=40.0,
|
|
tx_power=1e-3)
|
|
SimParams.set_params(load_json(TEST_DIR / 'data' / 'sim_params.json'))
|
|
SimParams().raman_params.solver_spatial_resolution = 5
|
|
fiber = RamanFiber(**load_json(TEST_DIR / 'data' / 'test_science_utils_fiber_config.json'))
|
|
fiber.ref_pch_in_dbm = 0.0
|
|
# propagation
|
|
spectral_info_out = fiber(spectral_info_input)
|
|
|
|
p_signal = spectral_info_out.signal
|
|
p_ase = spectral_info_out.ase
|
|
p_nli = spectral_info_out.nli
|
|
|
|
expected_results = read_csv(TEST_DIR / 'data' / 'test_raman_fiber_expected_results.csv')
|
|
|
|
assert_allclose(p_signal, expected_results['signal'], rtol=1e-3)
|
|
assert_allclose(p_ase, expected_results['ase'], rtol=1e-3)
|
|
assert_allclose(p_nli, expected_results['nli'], rtol=1e-3)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"loss, position, errmsg",
|
|
((0.5, -2, "Lumped loss positions must be between 0 and the fiber length (80.0 km), boundaries excluded."),
|
|
(0.5, 81, "Lumped loss positions must be between 0 and the fiber length (80.0 km), boundaries excluded.")))
|
|
@pytest.mark.usefixtures('set_sim_params')
|
|
def test_fiber_lumped_losses(loss, position, errmsg, set_sim_params):
|
|
"""Lumped losses length sanity checking."""
|
|
SimParams.set_params(load_json(TEST_DIR / 'data' / 'sim_params.json'))
|
|
fiber_dict = load_json(TEST_DIR / 'data' / 'test_lumped_losses_raman_fiber_config.json')
|
|
fiber_dict['params']['lumped_losses'] = [{'position': position, 'loss': loss}]
|
|
with pytest.raises(NetworkTopologyError) as e:
|
|
Fiber(**fiber_dict)
|
|
assert str(e.value) == errmsg
|
|
|
|
|
|
@pytest.mark.usefixtures('set_sim_params')
|
|
def test_fiber_lumped_losses_srs(set_sim_params):
|
|
"""Test the accuracy of Fiber with lumped losses propagation."""
|
|
# spectral information generation
|
|
spectral_info_input = create_input_spectral_information(f_min=191.3e12, f_max=196.1e12, roll_off=0.15,
|
|
baud_rate=32e9, spacing=50e9, tx_osnr=40.0,
|
|
tx_power=1e-3)
|
|
|
|
fiber = Fiber(**load_json(TEST_DIR / 'data' / 'test_lumped_losses_raman_fiber_config.json'))
|
|
raman_fiber = RamanFiber(**load_json(TEST_DIR / 'data' / 'test_lumped_losses_raman_fiber_config.json'))
|
|
|
|
# propagation
|
|
# without Raman pumps
|
|
SimParams.set_params({'raman_params': {'flag': True, 'order': 2}})
|
|
stimulated_raman_scattering = RamanSolver.calculate_stimulated_raman_scattering(spectral_info_input, fiber)
|
|
power_profile = stimulated_raman_scattering.power_profile
|
|
expected_power_profile = read_csv(TEST_DIR / 'data' / 'test_lumped_losses_fiber_no_pumps.csv').values
|
|
assert_allclose(power_profile, expected_power_profile, rtol=1e-3)
|
|
|
|
# with Raman pumps
|
|
SimParams.set_params({'raman_params': {'flag': True, 'order': 1, 'solver_spatial_resolution': 5}})
|
|
stimulated_raman_scattering = RamanSolver.calculate_stimulated_raman_scattering(spectral_info_input, raman_fiber)
|
|
power_profile = stimulated_raman_scattering.power_profile
|
|
expected_power_profile = read_csv(TEST_DIR / 'data' / 'test_lumped_losses_raman_fiber.csv').values
|
|
assert_allclose(power_profile, expected_power_profile, rtol=1e-3)
|
|
|
|
# without Stimulated Raman Scattering
|
|
expected_power_profile = read_csv(TEST_DIR / 'data' / 'test_lumped_losses_fiber_no_raman.csv', header=None)
|
|
stimulated_raman_scattering = RamanSolver.calculate_attenuation_profile(spectral_info_input, fiber)
|
|
power_profile = stimulated_raman_scattering.power_profile
|
|
assert_allclose(power_profile, expected_power_profile, rtol=1e-3)
|
|
|
|
|
|
@pytest.mark.usefixtures('set_sim_params')
|
|
def test_nli_solver():
|
|
"""Test the accuracy of NLI solver."""
|
|
fiber = Fiber(**load_json(TEST_DIR / 'data' / 'test_science_utils_fiber_config.json'))
|
|
fiber.ref_pch_in_dbm = 0.0
|
|
# fix grid spectral information generation
|
|
spectral_info_input = create_input_spectral_information(f_min=191.3e12, f_max=196.1e12, roll_off=0.15,
|
|
baud_rate=32e9, spacing=50e9, tx_osnr=40.0,
|
|
tx_power=1e-3)
|
|
|
|
SimParams.set_params(load_json(TEST_DIR / 'data' / 'sim_params.json'))
|
|
sim_params = SimParams()
|
|
|
|
spectral_info_output = fiber(deepcopy(spectral_info_input))
|
|
|
|
sim_params.nli_params.method = 'ggn_approx'
|
|
sim_params.raman_params.result_spatial_resolution = 10e3
|
|
spectral_info_output_approx = fiber(deepcopy(spectral_info_input))
|
|
|
|
assert_allclose(spectral_info_output.nli, spectral_info_output_approx.nli, rtol=1e-1)
|