mirror of
https://github.com/Telecominfraproject/oopt-gnpy.git
synced 2025-11-01 18:47:48 +00:00
Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f9cf8ccc7 | ||
|
|
0c797a254c | ||
|
|
2cdeeabfa6 | ||
|
|
5e874798cb | ||
|
|
ff8f044064 | ||
|
|
d84ee4e76c | ||
|
|
521d27ffac | ||
|
|
35e759212e | ||
|
|
f6dede2b5f | ||
|
|
0d0019f627 | ||
|
|
06fe1c2f63 | ||
|
|
092316a9d7 | ||
|
|
48e3f96967 | ||
|
|
e9e8956caf | ||
|
|
0ae341c2a5 | ||
|
|
0c2f6372f8 | ||
|
|
97e80b4445 | ||
|
|
5e4c9b7d73 | ||
|
|
e96f821cce | ||
|
|
5f7e61e255 | ||
|
|
682b5c5691 | ||
|
|
11e5117505 | ||
|
|
50603420fc | ||
|
|
125264f265 | ||
|
|
b1067a6266 | ||
|
|
50d4ecd700 | ||
|
|
9f37e0371e | ||
|
|
9bd303db05 | ||
|
|
1bcb3ce25c | ||
|
|
e381138320 | ||
|
|
b450677709 | ||
|
|
54a3725e17 | ||
|
|
8889c2437a | ||
|
|
8bf8b2947b | ||
|
|
cb85b8fe2b | ||
|
|
18610fb7a9 | ||
|
|
bd6b278dd1 | ||
|
|
e143d25339 | ||
|
|
ffc7dbc241 | ||
|
|
b842898baf | ||
|
|
7ea9e3b341 | ||
|
|
fcf168b361 | ||
|
|
74be14562a | ||
|
|
16694d0a09 |
23
.github/workflows/main.yml
vendored
23
.github/workflows/main.yml
vendored
@@ -11,14 +11,14 @@ jobs:
|
||||
name: Tox test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: fedora-python/tox-github-action@v0.4
|
||||
with:
|
||||
tox_env: ${{ matrix.tox_env }}
|
||||
dnf_install: ${{ matrix.dnf_install }}
|
||||
- uses: codecov/codecov-action@29386c70ef20e286228c72b668a06fd0e8399192
|
||||
- uses: codecov/codecov-action@v3.1.1
|
||||
if: ${{ endswith(matrix.tox_env, '-cover') }}
|
||||
with:
|
||||
files: ${{ github.workspace }}/cover/coverage.xml
|
||||
@@ -28,7 +28,8 @@ jobs:
|
||||
tox_env:
|
||||
- py38
|
||||
- py39
|
||||
- py310-cover
|
||||
- py310
|
||||
- py311-cover
|
||||
include:
|
||||
- tox_env: docs
|
||||
dnf_install: graphviz
|
||||
@@ -39,13 +40,13 @@ jobs:
|
||||
name: PyPI packaging
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/setup-python@v4
|
||||
name: Install Python
|
||||
with:
|
||||
python-version: '3.10'
|
||||
python-version: '3.11'
|
||||
- uses: casperdcl/deploy-pypi@bb869aafd89f657ceaafe9561d3b5584766c0f95
|
||||
with:
|
||||
password: ${{ secrets.PYPI_API_TOKEN }}
|
||||
@@ -63,7 +64,7 @@ jobs:
|
||||
with:
|
||||
username: jktjkt
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Extract tag name
|
||||
@@ -97,10 +98,10 @@ jobs:
|
||||
name: Tests on other platforms
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python_version }}
|
||||
- run: |
|
||||
@@ -113,5 +114,7 @@ jobs:
|
||||
include:
|
||||
- os: windows-2019
|
||||
python_version: "3.10"
|
||||
- os: windows-2022
|
||||
python_version: "3.11"
|
||||
- os: macos-12
|
||||
python_version: "3.10"
|
||||
python_version: "3.11"
|
||||
|
||||
22
.zuul.yaml
22
.zuul.yaml
@@ -2,10 +2,18 @@
|
||||
- project:
|
||||
check:
|
||||
jobs:
|
||||
- tox-py38
|
||||
- tox-py39
|
||||
- tox-py310-cover
|
||||
- tox-docs-f35
|
||||
- tox-py38:
|
||||
vars:
|
||||
ensure_tox_version: '<4'
|
||||
- tox-py39:
|
||||
vars:
|
||||
ensure_tox_version: '<4'
|
||||
- tox-py310-cover:
|
||||
vars:
|
||||
ensure_tox_version: '<4'
|
||||
- tox-docs-f36:
|
||||
vars:
|
||||
ensure_tox_version: '<4'
|
||||
- coverage-diff:
|
||||
voting: false
|
||||
dependencies:
|
||||
@@ -16,7 +24,11 @@
|
||||
coverage_job_name_current: tox-py310-cover
|
||||
- tox-linters-diff-n-report:
|
||||
voting: false
|
||||
- tox-py310-cover-previous
|
||||
vars:
|
||||
ensure_tox_version: '<4'
|
||||
- tox-py310-cover-previous:
|
||||
vars:
|
||||
ensure_tox_version: '<4'
|
||||
tag:
|
||||
jobs:
|
||||
- oopt-release-python:
|
||||
|
||||
@@ -11,18 +11,21 @@ To learn how to contribute, please see CONTRIBUTING.md
|
||||
- Brian Taylor (Facebook) <briantaylor@fb.com>
|
||||
- David Boertjes (Ciena) <dboertje@ciena.com>
|
||||
- Diego Landa (Facebook) <dlanda@fb.com>
|
||||
- Emmanuelle Delfour (Orange) <WEDE7391@orange.com>
|
||||
- Esther Le Rouzic (Orange) <esther.lerouzic@orange.com>
|
||||
- Gabriele Galimberti (Cisco) <ggalimbe@cisco.com>
|
||||
- Gert Grammel (Juniper Networks) <ggrammel@juniper.net>
|
||||
- Giacomo Borraccini (Politecnico di Torino) <giacomo.borraccini@polito.it>
|
||||
- Gilad Goldfarb (Facebook) <giladg@fb.com>
|
||||
- James Powell (Telecom Infra Project) <james.powell@telecominfraproject.com>
|
||||
- Jan Kundrát (Telecom Infra Project) <jan.kundrat@telecominfraproject.com>
|
||||
- Jan Kundrát (Telecom Infra Project) <jkt@jankundrat.com>
|
||||
- Jeanluc Augé (Orange) <jeanluc.auge@orange.com>
|
||||
- Jonas Mårtensson (RISE) <jonas.martensson@ri.se>
|
||||
- Mattia Cantono (Politecnico di Torino) <mattia.cantono@polito.it>
|
||||
- Miguel Garrich (University Catalunya) <miquel.garrich@upct.es>
|
||||
- Raj Nagarajan (Lumentum) <raj.nagarajan@lumentum.com>
|
||||
- Roberts Miculens (Lattelecom) <roberts.miculens@lattelecom.lv>
|
||||
- Sami Alavi (NUST) <sami.mansooralavi1999@gmail.com>
|
||||
- Shengxiang Zhu (University of Arizona) <szhu@email.arizona.edu>
|
||||
- Stefan Melin (Telia Company) <Stefan.Melin@teliacompany.com>
|
||||
- Vittorio Curri (Politecnico di Torino) <vittorio.curri@polito.it>
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
[](https://pypi.org/project/gnpy/)
|
||||
[](https://pypi.org/project/gnpy/)
|
||||
[](http://gnpy.readthedocs.io/en/master/?badge=master)
|
||||
[](https://github.com/Telecominfraproject/oopt-gnpy/actions/workflows/main.yml)
|
||||
[](https://github.com/Telecominfraproject/oopt-gnpy/actions/workflows/main.yml)
|
||||
[](https://review.gerrithub.io/q/project:Telecominfraproject/oopt-gnpy+is:open)
|
||||
[](https://github.com/Telecominfraproject/oopt-gnpy/graphs/contributors)
|
||||
[](https://lgtm.com/projects/g/Telecominfraproject/oopt-gnpy/)
|
||||
[](https://codecov.io/gh/Telecominfraproject/oopt-gnpy)
|
||||
[](https://doi.org/10.5281/zenodo.3458319)
|
||||
[](https://matrix.to/#/%23oopt-gnpy%3Afoss.wtf?via=matrix.org&via=foss.wtf)
|
||||
|
||||
GNPy is an open-source, community-developed library for building route planning and optimization tools in real-world mesh optical networks.
|
||||
We are a consortium of operators, vendors, and academic researchers sponsored via the [Telecom Infra Project](http://telecominfraproject.com)'s [OOPT/PSE](https://telecominfraproject.com/open-optical-packet-transport) working group.
|
||||
|
||||
@@ -12,7 +12,7 @@ We encourage all interested people outside the TIP to [join the project](https:/
|
||||
|
||||
`gnpy` is looking for additional contributors, especially those with experience planning and maintaining large-scale, real-world mesh optical networks.
|
||||
|
||||
To get involved, please contact [Jan Kundrát](mailto:jan.kundrat@telecominfraproject.com) or [Gert Grammel](mailto:ggrammel@juniper.net).
|
||||
To get involved, please contact [Jan Kundrát](mailto:jkt@jankundrat.com) or [Gert Grammel](mailto:ggrammel@juniper.net).
|
||||
|
||||
`gnpy` contributions are currently limited to members of [TIP](http://telecominfraproject.com).
|
||||
Membership is free and open to all.
|
||||
|
||||
@@ -10,7 +10,7 @@ fully-functional programs.
|
||||
|
||||
**Note**: *If you are a network operator or involved in route planning and
|
||||
optimization for your organization, please contact project maintainer Jan
|
||||
Kundrát <jan.kundrat@telecominfraproject.com>. gnpy is looking for users with
|
||||
Kundrát <jkt@jankundrat.com>. gnpy is looking for users with
|
||||
specific, delineated use cases to drive requirements for future
|
||||
development.*
|
||||
|
||||
|
||||
288
docs/json.rst
288
docs/json.rst
@@ -44,7 +44,7 @@ For all amplifier models:
|
||||
| ``type_variety`` | (string) | a unique name to ID the amplifier in the|
|
||||
| | | JSON/Excel template topology input file |
|
||||
+------------------------+-----------+-----------------------------------------+
|
||||
| ``out_voa_auto`` | (boolean) | auto_design feature to optimize the |
|
||||
| ``out_voa_auto`` | (boolean) | auto-design feature to optimize the |
|
||||
| | | amplifier output VOA. If true, output |
|
||||
| | | VOA is present and will be used to push |
|
||||
| | | amplifier gain to its maximum, within |
|
||||
@@ -176,36 +176,36 @@ ROADM
|
||||
|
||||
The user can only modify the value of existing parameters:
|
||||
|
||||
+--------------------------+-----------+---------------------------------------------+
|
||||
| field | type | description |
|
||||
+==========================+===========+=============================================+
|
||||
| ``target_pch_out_db`` | (number) | Auto-design sets the ROADM egress channel |
|
||||
| | | power. This reflects typical control loop |
|
||||
| | | algorithms that adjust ROADM losses to |
|
||||
| | | equalize channels (eg coming from different |
|
||||
| | | ingress direction or add ports) |
|
||||
| | | This is the default value |
|
||||
| | | Roadm/params/target_pch_out_db if no value |
|
||||
| | | is given in the ``Roadm`` element in the |
|
||||
| | | topology input description. |
|
||||
| | | This default value is ignored if a |
|
||||
| | | params/target_pch_out_db value is input in |
|
||||
| | | the topology for a given ROADM. |
|
||||
+--------------------------+-----------+---------------------------------------------+
|
||||
| ``add_drop_osnr`` | (number) | OSNR contribution from the add/drop ports |
|
||||
+--------------------------+-----------+---------------------------------------------+
|
||||
| ``pmd`` | (number) | Polarization mode dispersion (PMD). (s) |
|
||||
+--------------------------+-----------+---------------------------------------------+
|
||||
| ``restrictions`` | (dict of | If non-empty, keys ``preamp_variety_list`` |
|
||||
| | strings) | and ``booster_variety_list`` represent |
|
||||
| | | list of ``type_variety`` amplifiers which |
|
||||
| | | are allowed for auto-design within ROADM's |
|
||||
| | | line degrees. |
|
||||
| | | |
|
||||
| | | If no booster should be placed on a degree, |
|
||||
| | | insert a ``Fused`` node on the degree |
|
||||
| | | output. |
|
||||
+--------------------------+-----------+---------------------------------------------+
|
||||
+-------------------------------+-----------+----------------------------------------------------+
|
||||
| field | type | description |
|
||||
+===============================+===========+====================================================+
|
||||
| ``target_pch_out_db`` | (number) | Default :ref:`equalization strategy<equalization>` |
|
||||
| or | | for this ROADM type. |
|
||||
| ``target_psd_out_mWperGHz`` | | |
|
||||
| or | | Auto-design sets the ROADM egress channel |
|
||||
| ``target_out_mWperSlotWidth`` | | power. This reflects typical control loop |
|
||||
| (mutually exclusive) | | algorithms that adjust ROADM losses to |
|
||||
| | | equalize channels (e.g., coming from |
|
||||
| | | different ingress direction or add ports). |
|
||||
| | | |
|
||||
| | | These values are used as defaults when no |
|
||||
| | | overrides are set per each ``Roadm`` |
|
||||
| | | element in the network topology. |
|
||||
+-------------------------------+-----------+----------------------------------------------------+
|
||||
| ``add_drop_osnr`` | (number) | OSNR contribution from the add/drop ports |
|
||||
+-------------------------------+-----------+----------------------------------------------------+
|
||||
| ``pmd`` | (number) | Polarization mode dispersion (PMD). (s) |
|
||||
+-------------------------------+-----------+----------------------------------------------------+
|
||||
| ``restrictions`` | (dict of | If non-empty, keys ``preamp_variety_list`` |
|
||||
| | strings) | and ``booster_variety_list`` represent |
|
||||
| | | list of ``type_variety`` amplifiers which |
|
||||
| | | are allowed for auto-design within ROADM's |
|
||||
| | | line degrees. |
|
||||
| | | |
|
||||
| | | If no booster should be placed on a degree, |
|
||||
| | | insert a ``Fused`` node on the degree |
|
||||
| | | output. |
|
||||
+-------------------------------+-----------+----------------------------------------------------+
|
||||
|
||||
Global parameters
|
||||
-----------------
|
||||
@@ -223,6 +223,9 @@ For amplifiers defined in the topology JSON input but whose ``gain = 0`` (placeh
|
||||
The file ``sim_params.json`` contains the tuning parameters used within both the ``gnpy.science_utils.RamanSolver`` and
|
||||
the ``gnpy.science_utils.NliSolver`` for the evaluation of the Raman profile and the NLI generation, respectively.
|
||||
|
||||
If amplifiers don't have settings, auto-design also sets amplifiers gain, output VOA and target powers according to [J. -L. Auge, V. Curri and E. Le Rouzic, Open Design for Multi-Vendor Optical Networks, OFC 2019](https://ieeexplore.ieee.org/document/8696699), equation 4.
|
||||
See ``delta_power_range_db`` for more explaination.
|
||||
|
||||
+---------------------------------------------+-----------+---------------------------------------------+
|
||||
| field | type | description |
|
||||
+=============================================+===========+=============================================+
|
||||
@@ -283,23 +286,27 @@ Span configuration is not a list (which may change in later releases) and the us
|
||||
+-------------------------------------+-----------+---------------------------------------------+
|
||||
| field | type | description |
|
||||
+=====================================+===========+=============================================+
|
||||
| ``power_mode`` | (boolean) | If false, gain mode. Auto-design sets |
|
||||
| | | amplifier gain = preceding span loss, |
|
||||
| | | unless the amplifier exists and its |
|
||||
| | | gain > 0 in the topology input JSON. |
|
||||
| | | If true, power mode (recommended for |
|
||||
| | | auto-design and power sweep.) |
|
||||
| | | Auto-design sets amplifier power |
|
||||
| | | according to delta_power_range. If the |
|
||||
| | | amplifier exists with gain > 0 in the |
|
||||
| | | topology JSON input, then its gain is |
|
||||
| | | translated into a power target/channel. |
|
||||
| | | Moreover, when performing a power sweep |
|
||||
| | | (see ``power_range_db`` in the SI |
|
||||
| | | configuration library) the power sweep |
|
||||
| | | is performed w/r/t this power target, |
|
||||
| | | regardless of preceding amplifiers |
|
||||
| | | power saturation/limitations. |
|
||||
| ``power_mode`` | (boolean) | If false, **gain mode**. In the gain mode, |
|
||||
| | | only gain settings are used for |
|
||||
| | | propagation, and ``delta_p`` is ignored. |
|
||||
| | | If no ``gain_target`` is set in an |
|
||||
| | | amplifier, auto-design computes one |
|
||||
| | | according to the ``delta_power_range`` |
|
||||
| | | optimisation range. |
|
||||
| | | The gain mode |
|
||||
| | | is recommended if all the amplifiers |
|
||||
| | | have already consistent gain settings in |
|
||||
| | | the topology input file. |
|
||||
| | | |
|
||||
| | | If true, **power mode**. In the power mode, |
|
||||
| | | only the ``delta_p`` is used for |
|
||||
| | | propagation, and ``gain_target`` is |
|
||||
| | | ignored. |
|
||||
| | | The power mode is recommended for |
|
||||
| | | auto-design and power sweep. |
|
||||
| | | If no ``delta_p`` is set, |
|
||||
| | | auto-design sets an amplifier power target |
|
||||
| | | according to delta_power_range_db. |
|
||||
+-------------------------------------+-----------+---------------------------------------------+
|
||||
| ``delta_power_range_db`` | (number) | Auto-design only, power-mode |
|
||||
| | | only. Specifies the [min, max, step] |
|
||||
@@ -404,9 +411,9 @@ Span configuration is not a list (which may change in later releases) and the us
|
||||
SpectralInformation
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The user can only modify the value of existing parameters.
|
||||
It defines a spectrum of N identical carriers.
|
||||
While the code libraries allow for different carriers and power levels, the current user parametrization only allows one carrier type and one power/channel definition.
|
||||
GNPy requires a description of all channels that are propagated through the network.
|
||||
Flexgrid channel partitioning is available since the 2.7 release via the extra ``--spectrum`` option.
|
||||
In the simplest case, homogeneous channel allocation can be defined via the ``SpectralInformation`` construct which defines a spectrum of N identical carriers:
|
||||
|
||||
+----------------------+-----------+-------------------------------------------+
|
||||
| field | type | description |
|
||||
@@ -427,11 +434,20 @@ While the code libraries allow for different carriers and power levels, the curr
|
||||
+----------------------+-----------+-------------------------------------------+
|
||||
| ``tx_osnr`` | (number) | In dB. OSNR out from transponder. |
|
||||
+----------------------+-----------+-------------------------------------------+
|
||||
| ``power_dbm`` | (number) | Reference channel power. In gain mode |
|
||||
| | | (see spans/power_mode = false), all gain |
|
||||
| | | settings are offset w/r/t this reference |
|
||||
| | | power. In power mode, it is the |
|
||||
| | | reference power for |
|
||||
| ``power_dbm`` | (number) | Reference channel power, in dBm. |
|
||||
| | | In gain mode |
|
||||
| | | (see spans/power_mode = false), if no |
|
||||
| | | gain is set in an amplifier, auto-design |
|
||||
| | | sets gain to meet this reference |
|
||||
| | | power. If amplifiers gain is set, |
|
||||
| | | ``power_dbm`` is |
|
||||
| | | ignored. |
|
||||
| | | |
|
||||
| | | In power mode, the ``power_dbm`` |
|
||||
| | | is the reference power for |
|
||||
| | | the ``delta_p`` settings in amplifiers. |
|
||||
| | | It is also the reference power for |
|
||||
| | | auto-design power optimisation range |
|
||||
| | | Spans/delta_power_range_db. For example, |
|
||||
| | | if delta_power_range_db = `[0,0,0]`, the |
|
||||
| | | same power=power_dbm is launched in every |
|
||||
@@ -439,12 +455,166 @@ While the code libraries allow for different carriers and power levels, the curr
|
||||
| | | with the power_dbm value: even if a |
|
||||
| | | power sweep is defined (see after) the |
|
||||
| | | design is not repeated. |
|
||||
| | | |
|
||||
| | | If the ``--power`` CLI option is used, |
|
||||
| | | its value replaces this parameter. |
|
||||
+----------------------+-----------+-------------------------------------------+
|
||||
| ``power_range_db`` | (number) | Power sweep excursion around power_dbm. |
|
||||
| | | It is not the min and max channel power |
|
||||
| | | values! The reference power becomes: |
|
||||
| ``power_range_db`` | (number) | Power sweep excursion around |
|
||||
| | | ``power_dbm``. |
|
||||
| | | This defines a list of reference powers |
|
||||
| | | to run the propagation, in the range |
|
||||
| | | power_range_db + power_dbm. |
|
||||
| | | Power sweep uses the ``delta_p`` targets |
|
||||
| | | or, if they have not been set, the ones |
|
||||
| | | computed by auto-design, regardless of |
|
||||
| | | of preceding amplifiers' power |
|
||||
| | | saturation. |
|
||||
| | | |
|
||||
| | | Power sweep is an easy way to find the |
|
||||
| | | optimal reference power. |
|
||||
| | | |
|
||||
| | | Power sweep excursion is ignored in case |
|
||||
| | | of gain mode. |
|
||||
+----------------------+-----------+-------------------------------------------+
|
||||
| ``sys_margins`` | (number) | In dB. Added margin on min required |
|
||||
| | | transceiver OSNR. |
|
||||
+----------------------+-----------+-------------------------------------------+
|
||||
|
||||
.. _mixed-rate:
|
||||
|
||||
Arbitrary channel definition
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Non-uniform channels are defined via a list of spectrum "partitions" which are defined in an extra JSON file via the ``--spectrum`` option.
|
||||
In this approach, each partition is internally homogeneous, but different partitions might use different channel widths, power targets, modulation rates, etc.
|
||||
|
||||
+----------------------+-----------+-------------------------------------------+
|
||||
| field | type | description |
|
||||
+======================+===========+===========================================+
|
||||
| ``f_min``, | (number) | In Hz. Mandatory. |
|
||||
| ``f_max`` | | Define partition :math:`f_{min}` is |
|
||||
| | | the first carrier central frequency |
|
||||
| | | :math:`f_{max}` is the last one. |
|
||||
| | | :math:`f_{min}` -:math:`f_{max}` |
|
||||
| | | partitions must not overlap. |
|
||||
| | | |
|
||||
| | | Note that the meaning of ``f_min`` and |
|
||||
| | | ``f_max`` is different than the one in |
|
||||
| | | ``SpectralInformation``. |
|
||||
+----------------------+-----------+-------------------------------------------+
|
||||
| ``baud_rate`` | (number) | In Hz. Mandatory. Simulated baud rate. |
|
||||
+----------------------+-----------+-------------------------------------------+
|
||||
| ``slot_width`` | (number) | In Hz. Carrier spectrum occupation. |
|
||||
| | | Carriers of this partition are spaced at |
|
||||
| | | ``slot_width`` offsets. |
|
||||
+----------------------+-----------+-------------------------------------------+
|
||||
| ``roll_off`` | (number) | Pure number between 0 and 1. Mandatory |
|
||||
| | | TX signal roll-off shape. Used by |
|
||||
| | | Raman-aware simulation code. |
|
||||
+----------------------+-----------+-------------------------------------------+
|
||||
| ``tx_osnr`` | (number) | In dB. Optional. OSNR out from |
|
||||
| | | transponder. Default value is 40 dB. |
|
||||
+----------------------+-----------+-------------------------------------------+
|
||||
| ``delta_pdb`` | (number) | In dB. Optional. Power offset compared to |
|
||||
| | | the reference power used for design |
|
||||
| | | (SI block in equipment library) to be |
|
||||
| | | applied by ROADM to equalize the carriers |
|
||||
| | | in this partition. Default value is 0 dB. |
|
||||
+----------------------+-----------+-------------------------------------------+
|
||||
|
||||
For example this example:
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"SI":[
|
||||
{
|
||||
"f_min": 191.4e12,
|
||||
"f_max":193.1e12,
|
||||
"baud_rate": 32e9,
|
||||
"slot_width": 50e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40
|
||||
},
|
||||
{
|
||||
"f_min": 193.1625e12,
|
||||
"f_max":195e12,
|
||||
"baud_rate": 64e9,
|
||||
"delta_pdb": 3,
|
||||
"slot_width": 75e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
...defines a spectrum split into two parts.
|
||||
Carriers with central frequencies ranging from 191.4 THz to 193.1 THz will have 32 GBaud rate and will be spaced by 50 Ghz.
|
||||
Carriers with central frequencies ranging from 193.1625 THz to 195 THz will have 64 GBaud rate and will be spaced by 75 GHz with 3 dB power offset.
|
||||
|
||||
If the SI reference carrier is set to ``power_dbm`` = 0dBm, and the ROADM has ``target_pch_out_db`` set to -20 dBm, then all channels ranging from 191.4 THz to 193.1 THz will have their power equalized to -20 + 0 dBm (due to the 0 dB power offset).
|
||||
All channels ranging from 193.1625 THz to 195 THz will have their power equalized to -20 + 3 = -17 dBm (total power signal + noise).
|
||||
|
||||
Note that first carrier of the second partition has center frequency 193.1625 THz (its spectrum occupation ranges from 193.125 THz to 193.2 THz).
|
||||
The last carrier of the second partition has center frequency 193.1 THz and spectrum occupation ranges from 193.075 THz to 193.125 THz.
|
||||
There is no overlap of the occupation and both share the same boundary.
|
||||
|
||||
.. _equalization:
|
||||
|
||||
Equalization choices
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
ROADMs typically equalize the optical power across multiple channels using one of the available equalization strategies — either targeting a specific output power, or a specific power spectral density (PSD), or a spectfic power spectral density using slot_width as spectrum width reference (PSW).
|
||||
All of these strategies can be adjusted by a per-channel power offset.
|
||||
The equalization strategy can be defined globally per a ROADM model, or per each ROADM instance in the topology, and within a ROADM also on a per-degree basis.
|
||||
|
||||
Let's consider some example for the equalization. Suppose that the types of signal to be propagated are the following:
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"baud_rate": 32e9,
|
||||
"f_min":191.3e12,
|
||||
"f_max":192.3e12,
|
||||
"spacing": 50e9,
|
||||
"label": 1
|
||||
},
|
||||
{
|
||||
"baud_rate": 64e9,
|
||||
"f_min":193.3e12,
|
||||
"f_max":194.3e12,
|
||||
"spacing": 75e9,
|
||||
"label": 2
|
||||
}
|
||||
|
||||
|
||||
with the PSD equalization in a ROADM:
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"uid": "roadm A",
|
||||
"type": "Roadm",
|
||||
"params": {
|
||||
"target_psd_out_mWperGHz": 3.125e-4,
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
This means that power out of the ROADM will be computed as 3.125e-4 * 32 = 0.01 mW ie -20 dBm for label 1 types of carriers
|
||||
and 3.125e4 * 64 = 0.02 mW ie -16.99 dBm for label2 channels. So a ratio of ~ 3 dB between target powers for these carriers.
|
||||
|
||||
With the PSW equalization:
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"uid": "roadm A",
|
||||
"type": "Roadm",
|
||||
"params": {
|
||||
"target_out_mWperSlotWidth": 2.0e-4,
|
||||
}
|
||||
},
|
||||
|
||||
the power out of the ROADM will be computed as 2.0e-4 * 50 = 0.01 mW ie -20 dBm for label 1 types of carriers
|
||||
and 2.0e4 * 75 = 0.015 mW ie -18.24 dBm for label2 channels. So a ratio of ~ 1.76 dB between target powers for these carriers.
|
||||
|
||||
@@ -21,16 +21,19 @@ instance as a result.
|
||||
"""
|
||||
|
||||
from numpy import abs, array, errstate, ones, interp, mean, pi, polyfit, polyval, sum, sqrt, log10, exp, asarray, full,\
|
||||
squeeze, zeros, append, flip, outer
|
||||
squeeze, zeros, append, flip, outer, ndarray
|
||||
from scipy.constants import h, c
|
||||
from scipy.interpolate import interp1d
|
||||
from collections import namedtuple
|
||||
from typing import Union
|
||||
|
||||
from gnpy.core.utils import lin2db, db2lin, arrange_frequencies, snr_sum, watt2dbm
|
||||
|
||||
from gnpy.core.utils import lin2db, db2lin, arrange_frequencies, snr_sum, per_label_average, pretty_summary_print, \
|
||||
watt2dbm, psd2powerdbm
|
||||
from gnpy.core.parameters import RoadmParams, FusedParams, FiberParams, PumpParams, EdfaParams, EdfaOperational
|
||||
from gnpy.core.science_utils import NliSolver, RamanSolver
|
||||
from gnpy.core.info import SpectralInformation
|
||||
from gnpy.core.exceptions import NetworkTopologyError, SpectrumError
|
||||
from gnpy.core.info import SpectralInformation, ReferenceCarrier
|
||||
from gnpy.core.exceptions import NetworkTopologyError, SpectrumError, ParametersError
|
||||
|
||||
|
||||
class Location(namedtuple('Location', 'latitude longitude city region')):
|
||||
@@ -86,6 +89,7 @@ class Transceiver(_Node):
|
||||
self.pdl = None
|
||||
self.penalties = {}
|
||||
self.total_penalty = 0
|
||||
self.propagated_labels = [""]
|
||||
|
||||
def _calc_cd(self, spectral_info):
|
||||
""" Updates the Transceiver property with the CD of the received channels. CD in ps/nm.
|
||||
@@ -116,6 +120,7 @@ class Transceiver(_Node):
|
||||
|
||||
def _calc_snr(self, spectral_info):
|
||||
with errstate(divide='ignore'):
|
||||
self.propagated_labels = spectral_info.label
|
||||
self.baud_rate = spectral_info.baud_rate
|
||||
ratio_01nm = lin2db(12.5e9 / self.baud_rate)
|
||||
# set raw values to record original calculation, before update_snr()
|
||||
@@ -173,23 +178,22 @@ class Transceiver(_Node):
|
||||
if self.snr is None or self.osnr_ase is None:
|
||||
return f'{type(self).__name__} {self.uid}'
|
||||
|
||||
snr = round(mean(self.snr), 2)
|
||||
osnr_ase = round(mean(self.osnr_ase), 2)
|
||||
osnr_ase_01nm = round(mean(self.osnr_ase_01nm), 2)
|
||||
snr_01nm = round(mean(self.snr_01nm), 2)
|
||||
snr = per_label_average(self.snr, self.propagated_labels)
|
||||
osnr_ase = per_label_average(self.osnr_ase, self.propagated_labels)
|
||||
osnr_ase_01nm = per_label_average(self.osnr_ase_01nm, self.propagated_labels)
|
||||
snr_01nm = per_label_average(self.snr_01nm, self.propagated_labels)
|
||||
cd = mean(self.chromatic_dispersion)
|
||||
pmd = mean(self.pmd)
|
||||
pdl = mean(self.pdl)
|
||||
|
||||
result = '\n'.join([f'{type(self).__name__} {self.uid}',
|
||||
|
||||
f' GSNR (0.1nm, dB): {snr_01nm:.2f}',
|
||||
f' GSNR (signal bw, dB): {snr:.2f}',
|
||||
f' OSNR ASE (0.1nm, dB): {osnr_ase_01nm:.2f}',
|
||||
f' OSNR ASE (signal bw, dB): {osnr_ase:.2f}',
|
||||
f' CD (ps/nm): {cd:.2f}',
|
||||
f' PMD (ps): {pmd:.2f}',
|
||||
f' PDL (dB): {pdl:.2f}'])
|
||||
f' GSNR (0.1nm, dB): {pretty_summary_print(snr_01nm)}',
|
||||
f' GSNR (signal bw, dB): {pretty_summary_print(snr)}',
|
||||
f' OSNR ASE (0.1nm, dB): {pretty_summary_print(osnr_ase_01nm)}',
|
||||
f' OSNR ASE (signal bw, dB): {pretty_summary_print(osnr_ase)}',
|
||||
f' CD (ps/nm): {cd:.2f}',
|
||||
f' PMD (ps): {pmd:.2f}',
|
||||
f' PDL (dB): {pdl:.2f}'])
|
||||
|
||||
cd_penalty = self.penalties.get('chromatic_dispersion')
|
||||
if cd_penalty is not None:
|
||||
@@ -215,71 +219,185 @@ class Roadm(_Node):
|
||||
def __init__(self, *args, params=None, **kwargs):
|
||||
if not params:
|
||||
params = {}
|
||||
super().__init__(*args, params=RoadmParams(**params), **kwargs)
|
||||
self.ref_pch_out_dbm = self.params.target_pch_out_db
|
||||
try:
|
||||
super().__init__(*args, params=RoadmParams(**params), **kwargs)
|
||||
except ParametersError as e:
|
||||
raise ParametersError(f'Config error in {kwargs["uid"]}: {e}') from e
|
||||
|
||||
# Target output power for the reference carrier, can only be computed on the fly, because it depends
|
||||
# on the path, since it depends on the equalization definition on the degree.
|
||||
self.ref_pch_out_dbm = None
|
||||
self.loss = 0 # auto-design interest
|
||||
self.effective_loss = None
|
||||
|
||||
# Optical power of carriers are equalized by the ROADM, so that the experienced loss is not the same for
|
||||
# different carriers. The ref_effective_loss records the loss for a reference carrier.
|
||||
self.ref_effective_loss = None
|
||||
|
||||
self.passive = True
|
||||
self.restrictions = self.params.restrictions
|
||||
self.propagated_labels = [""]
|
||||
# element contains the two types of equalisation parameters, but only one is not None or empty
|
||||
# target for equalization for the ROADM only one must be not None
|
||||
self.target_pch_out_dbm = self.params.target_pch_out_db
|
||||
self.target_psd_out_mWperGHz = self.params.target_psd_out_mWperGHz
|
||||
self.target_out_mWperSlotWidth = self.params.target_out_mWperSlotWidth
|
||||
self.per_degree_pch_out_dbm = self.params.per_degree_pch_out_db
|
||||
self.per_degree_pch_psd = self.params.per_degree_pch_psd
|
||||
self.per_degree_pch_psw = self.params.per_degree_pch_psw
|
||||
|
||||
@property
|
||||
def to_json(self):
|
||||
return {'uid': self.uid,
|
||||
'type': type(self).__name__,
|
||||
'params': {
|
||||
'target_pch_out_db': self.ref_pch_out_dbm,
|
||||
'restrictions': self.restrictions,
|
||||
'per_degree_pch_out_db': self.per_degree_pch_out_dbm
|
||||
},
|
||||
'metadata': {
|
||||
'location': self.metadata['location']._asdict()
|
||||
}
|
||||
}
|
||||
if self.target_pch_out_dbm is not None:
|
||||
equalisation, value = 'target_pch_out_db', self.target_pch_out_dbm
|
||||
elif self.target_psd_out_mWperGHz is not None:
|
||||
equalisation, value = 'target_psd_out_mWperGHz', self.target_psd_out_mWperGHz
|
||||
elif self.target_out_mWperSlotWidth is not None:
|
||||
equalisation, value = 'target_out_mWperSlotWidth', self.target_out_mWperSlotWidth
|
||||
else:
|
||||
assert False, 'There must be one default equalization defined in ROADM'
|
||||
to_json = {
|
||||
'uid': self.uid,
|
||||
'type': type(self).__name__,
|
||||
'params': {
|
||||
equalisation: value,
|
||||
'restrictions': self.restrictions,
|
||||
},
|
||||
'metadata': {
|
||||
'location': self.metadata['location']._asdict()
|
||||
}
|
||||
}
|
||||
# several per_degree equalization may coexist on different degrees
|
||||
if self.per_degree_pch_out_dbm:
|
||||
to_json['params']['per_degree_pch_out_db'] = self.per_degree_pch_out_dbm
|
||||
if self.per_degree_pch_psd:
|
||||
to_json['params']['per_degree_psd_out_mWperGHz'] = self.per_degree_pch_psd
|
||||
if self.per_degree_pch_psw:
|
||||
to_json['params']['per_degree_psd_out_mWperSlotWidth'] = self.per_degree_pch_psw
|
||||
return to_json
|
||||
|
||||
def __repr__(self):
|
||||
return f'{type(self).__name__}(uid={self.uid!r}, loss={self.loss!r})'
|
||||
|
||||
def __str__(self):
|
||||
if self.effective_loss is None:
|
||||
if self.ref_effective_loss is None:
|
||||
return f'{type(self).__name__} {self.uid}'
|
||||
|
||||
total_pch = pretty_summary_print(per_label_average(self.pch_out_dbm, self.propagated_labels))
|
||||
return '\n'.join([f'{type(self).__name__} {self.uid}',
|
||||
f' effective loss (dB): {self.effective_loss:.2f}',
|
||||
f' pch out (dBm): {self.ref_pch_out_dbm:.2f}'])
|
||||
f' effective loss (dB): {self.ref_effective_loss:.2f}',
|
||||
f' reference pch out (dBm): {self.ref_pch_out_dbm:.2f}',
|
||||
f' actual pch out (dBm): {total_pch}'])
|
||||
|
||||
def get_roadm_target_power(self, ref_carrier: ReferenceCarrier = None,
|
||||
spectral_info: SpectralInformation = None) -> Union[float, ndarray]:
|
||||
"""Computes the power in dBm for a reference carrier or for a spectral information.
|
||||
power is computed based on equalization target.
|
||||
if spectral_info baud_rate is baud_rate = [32e9, 42e9, 64e9, 42e9, 32e9], and
|
||||
target_pch_out_dbm is defined to -20 dbm, then the function returns an array of powers
|
||||
[-20, -20, -20, -20, -20]
|
||||
if target_psd_out_mWperGHz is defined instead with 3.125e-4mW/GHz then it returns
|
||||
[-20, -18.819, -16.9897, -18.819, -20]
|
||||
if instead a reference_baud_rate is defined, the functions computes the result for a
|
||||
single reference carrier whose baud_rate is reference_baudrate
|
||||
"""
|
||||
if spectral_info:
|
||||
if self.target_pch_out_dbm is not None:
|
||||
return full(len(spectral_info.channel_number), self.target_pch_out_dbm)
|
||||
if self.target_psd_out_mWperGHz is not None:
|
||||
return psd2powerdbm(self.target_psd_out_mWperGHz, spectral_info.baud_rate)
|
||||
if self.target_out_mWperSlotWidth is not None:
|
||||
return psd2powerdbm(self.target_out_mWperSlotWidth, spectral_info.slot_width)
|
||||
else:
|
||||
if self.target_pch_out_dbm is not None:
|
||||
return self.target_pch_out_dbm
|
||||
if self.target_psd_out_mWperGHz is not None:
|
||||
return psd2powerdbm(self.target_psd_out_mWperGHz, ref_carrier.baud_rate)
|
||||
if self.target_out_mWperSlotWidth is not None:
|
||||
return psd2powerdbm(self.target_out_mWperSlotWidth, ref_carrier.slot_width)
|
||||
return None
|
||||
|
||||
def get_per_degree_ref_power(self, degree, ref_carrier):
|
||||
"""Get the target power in dBm out of ROADM degree for the reference bandwidth
|
||||
If no equalization is defined on this degree use the ROADM level one.
|
||||
"""
|
||||
if degree in self.per_degree_pch_out_dbm:
|
||||
return self.per_degree_pch_out_dbm[degree]
|
||||
elif degree in self.per_degree_pch_psd:
|
||||
return psd2powerdbm(self.per_degree_pch_psd[degree], ref_carrier.baud_rate)
|
||||
elif degree in self.per_degree_pch_psw:
|
||||
return psd2powerdbm(self.per_degree_pch_psw[degree], ref_carrier.slot_width)
|
||||
return self.get_roadm_target_power(ref_carrier)
|
||||
|
||||
def get_per_degree_power(self, degree, spectral_info):
|
||||
"""Get the target power in dBm out of ROADM degree for the spectral information
|
||||
If no equalization is defined on this degree use the ROADM level one.
|
||||
"""
|
||||
if degree in self.per_degree_pch_out_dbm:
|
||||
return self.per_degree_pch_out_dbm[degree]
|
||||
elif degree in self.per_degree_pch_psd:
|
||||
return psd2powerdbm(self.per_degree_pch_psd[degree], spectral_info.baud_rate)
|
||||
return self.get_roadm_target_power(spectral_info=spectral_info)
|
||||
|
||||
def propagate(self, spectral_info, degree):
|
||||
# pin_target and loss are read from eqpt_config.json['Roadm']
|
||||
# all ingress channels in xpress are set to this power level
|
||||
# but add channels are not, so we define an effective loss
|
||||
# in the case of add channels
|
||||
# find the target power on this degree:
|
||||
# if a target power has been defined for this degree use it else use the global one.
|
||||
# if the input power is lower than the target one, use the input power instead because
|
||||
# a ROADM doesn't amplify, it can only attenuate
|
||||
"""Equalization targets are read from topology file if defined and completed with default
|
||||
definition of the library.
|
||||
If the input power is lower than the target one, use the input power instead because
|
||||
a ROADM doesn't amplify, it can only attenuate.
|
||||
There is no difference for add or express : the same target is applied. For the moment
|
||||
propagates operates with spectral info carriers all having the same source or destination.
|
||||
"""
|
||||
# TODO maybe add a minimum loss for the ROADM
|
||||
per_degree_pch = self.per_degree_pch_out_dbm.get(degree, self.ref_pch_out_dbm)
|
||||
|
||||
# find the target power for the reference carrier
|
||||
ref_per_degree_pch = self.get_per_degree_ref_power(degree, spectral_info.pref.ref_carrier)
|
||||
# find the target powers for each signal carrier
|
||||
per_degree_pch = self.get_per_degree_power(degree, spectral_info=spectral_info)
|
||||
|
||||
# Definition of ref_pch_out_dbm for the reference channel:
|
||||
# Depending on propagation upstream from this ROADM, the input power (p_spani) might be smaller than
|
||||
# the target power out configured for this ROADM degree's egress. Since ROADM does not amplify,
|
||||
# the power out of the ROADM for the ref channel is the min value between target power and input power.
|
||||
# (TODO add a minimum loss for the ROADM crossing)
|
||||
self.ref_pch_out_dbm = min(spectral_info.pref.p_spani, per_degree_pch)
|
||||
self.ref_pch_out_dbm = min(spectral_info.pref.p_spani, ref_per_degree_pch)
|
||||
# Definition of effective_loss:
|
||||
# Optical power of carriers are equalized by the ROADM, so that the experienced loss is not the same for
|
||||
# different carriers. effective_loss records the loss for a reference carrier.
|
||||
self.effective_loss = spectral_info.pref.p_spani - self.ref_pch_out_dbm
|
||||
# different carriers. effective_loss records the loss for the reference carrier.
|
||||
self.ref_effective_loss = spectral_info.pref.p_spani - self.ref_pch_out_dbm
|
||||
input_power = spectral_info.signal + spectral_info.nli + spectral_info.ase
|
||||
min_power = min(lin2db(input_power * 1e3))
|
||||
per_degree_pch = per_degree_pch if per_degree_pch < min_power else min_power
|
||||
delta_power = lin2db(input_power * 1e3) - per_degree_pch
|
||||
target_power_per_channel = per_degree_pch + spectral_info.delta_pdb_per_channel
|
||||
# Computation of the per channel target power according to equalization policy
|
||||
# If target_power_per_channel has some channels power above input power, then the whole target is reduced.
|
||||
# For example, if user specifies delta_pdb_per_channel:
|
||||
# freq1: 1dB, freq2: 3dB, freq3: -3dB, and target is -20dBm out of the ROADM,
|
||||
# then the target power for each channel uses the specified delta_pdb_per_channel.
|
||||
# target_power_per_channel[f1, f2, f3] = -19, -17, -23
|
||||
# However if input_signal = -23, -16, -26, then the target can not be applied, because
|
||||
# -23 < -19dBm and -26 < -23dBm. Then the target is only applied to signals whose power is above the
|
||||
# threshold. others are left unchanged and unequalized.
|
||||
# the new target is [-23, -17, -26]
|
||||
# and the attenuation to apply is [-23, -16, -26] - [-23, -17, -26] = [0, 1, 0]
|
||||
# note that this changes the previous behaviour that equalized all identical channels based on the one
|
||||
# that had the min power.
|
||||
# This change corresponds to a discussion held during coders call. Please look at this document for
|
||||
# a reference: https://telecominfraproject.atlassian.net/wiki/spaces/OOPT/pages/669679645/PSE+Meeting+Minutes
|
||||
correction = (abs(watt2dbm(input_power) - target_power_per_channel)
|
||||
- (watt2dbm(input_power) - target_power_per_channel)) / 2
|
||||
new_target = target_power_per_channel - correction
|
||||
delta_power = watt2dbm(input_power) - new_target
|
||||
|
||||
spectral_info.apply_attenuation_db(delta_power)
|
||||
spectral_info.pmd = sqrt(spectral_info.pmd ** 2 + self.params.pmd ** 2)
|
||||
spectral_info.pdl = sqrt(spectral_info.pdl ** 2 + self.params.pdl ** 2)
|
||||
self.pch_out_dbm = watt2dbm(spectral_info.signal + spectral_info.nli + spectral_info.ase)
|
||||
self.propagated_labels = spectral_info.label
|
||||
|
||||
def update_pref(self, spectral_info):
|
||||
spectral_info.pref = spectral_info.pref._replace(p_span0=spectral_info.pref.p_span0,
|
||||
p_spani=self.ref_pch_out_dbm)
|
||||
"""Update Reference power
|
||||
|
||||
This modifies the spectral info in-place. Only the `pref` is updated with new p_spani,
|
||||
while p_span0 is not changed.
|
||||
"""
|
||||
spectral_info.pref = spectral_info.pref._replace(p_spani=self.ref_pch_out_dbm)
|
||||
|
||||
def __call__(self, spectral_info, degree):
|
||||
self.propagate(spectral_info, degree=degree)
|
||||
@@ -334,7 +452,7 @@ class Fiber(_Node):
|
||||
super().__init__(*args, params=FiberParams(**params), **kwargs)
|
||||
self.pch_out_db = None
|
||||
self.passive = True
|
||||
|
||||
self.propagated_labels = [""]
|
||||
# Raman efficiency matrix function of the delta frequency constructed such that each row is related to a
|
||||
# fixed frequency: positive elements represent a gain (from higher frequency) and negative elements represent
|
||||
# a loss (to lower frequency)
|
||||
@@ -384,6 +502,7 @@ class Fiber(_Node):
|
||||
if self.pch_out_db is None:
|
||||
return f'{type(self).__name__} {self.uid}'
|
||||
|
||||
total_pch = pretty_summary_print(per_label_average(self.pch_out_dbm, self.propagated_labels))
|
||||
return '\n'.join([f'{type(self).__name__} {self.uid}',
|
||||
f' type_variety: {self.type_variety}',
|
||||
f' length (km): {self.params.length * 1e-3:.2f}',
|
||||
@@ -391,7 +510,8 @@ class Fiber(_Node):
|
||||
f' total loss (dB): {self.loss:.2f}',
|
||||
f' (includes conn loss (dB) in: {self.params.con_in:.2f} out: {self.params.con_out:.2f})',
|
||||
f' (conn loss out includes EOL margin defined in eqpt_config.json)',
|
||||
f' pch out (dBm): {self.pch_out_db:.2f}'])
|
||||
f' reference pch out (dBm): {self.pch_out_db:.2f}',
|
||||
f' actual pch out (dBm): {total_pch}'])
|
||||
|
||||
def loss_coef_func(self, frequency):
|
||||
frequency = asarray(frequency)
|
||||
@@ -481,6 +601,8 @@ class Fiber(_Node):
|
||||
# apply the attenuation due to the output connector loss
|
||||
attenuation_out_db = self.params.con_out
|
||||
spectral_info.apply_attenuation_db(attenuation_out_db)
|
||||
self.pch_out_dbm = watt2dbm(spectral_info.signal + spectral_info.nli + spectral_info.ase)
|
||||
self.propagated_labels = spectral_info.label
|
||||
|
||||
def update_pref(self, spectral_info):
|
||||
# in case of Raman, the resulting loss of the fiber is not equivalent to self.loss
|
||||
@@ -553,6 +675,8 @@ class RamanFiber(Fiber):
|
||||
# apply the attenuation due to the output connector loss
|
||||
attenuation_out_db = self.params.con_out
|
||||
spectral_info.apply_attenuation_db(attenuation_out_db)
|
||||
self.pch_out_dbm = watt2dbm(spectral_info.signal + spectral_info.nli + spectral_info.ase)
|
||||
self.propagated_labels = spectral_info.label
|
||||
|
||||
|
||||
class Edfa(_Node):
|
||||
@@ -581,6 +705,7 @@ class Edfa(_Node):
|
||||
self.delta_p = self.operational.delta_p # delta P with Pref (power swwep) in power mode
|
||||
self.tilt_target = self.operational.tilt_target
|
||||
self.out_voa = self.operational.out_voa
|
||||
self.propagated_labels = [""]
|
||||
|
||||
@property
|
||||
def to_json(self):
|
||||
@@ -588,7 +713,7 @@ class Edfa(_Node):
|
||||
'type': type(self).__name__,
|
||||
'type_variety': self.params.type_variety,
|
||||
'operational': {
|
||||
'gain_target': round(self.effective_gain, 6),
|
||||
'gain_target': round(self.effective_gain, 6) if self.effective_gain else None,
|
||||
'delta_p': self.delta_p,
|
||||
'tilt_target': self.tilt_target,
|
||||
'out_voa': self.out_voa
|
||||
@@ -614,6 +739,7 @@ class Edfa(_Node):
|
||||
if self.pin_db is None or self.pout_db is None:
|
||||
return f'{type(self).__name__} {self.uid}'
|
||||
nf = mean(self.nf)
|
||||
total_pch = pretty_summary_print(per_label_average(self.pch_out_dbm, self.propagated_labels))
|
||||
return '\n'.join([f'{type(self).__name__} {self.uid}',
|
||||
f' type_variety: {self.params.type_variety}',
|
||||
f' effective gain(dB): {self.effective_gain:.2f}',
|
||||
@@ -626,6 +752,7 @@ class Edfa(_Node):
|
||||
f' Delta_P (dB): ' + (f'{self.delta_p:.2f}' if self.delta_p is not None else 'None'),
|
||||
f' target pch (dBm): ' + (f'{self.target_pch_out_db:.2f}' if self.target_pch_out_db is not None else 'None'),
|
||||
f' effective pch (dBm): {self.effective_pch_out_db:.2f}',
|
||||
f' actual pch out (dBm): {total_pch}',
|
||||
f' output VOA (dB): {self.out_voa:.2f}'])
|
||||
|
||||
def interpol_params(self, spectral_info):
|
||||
@@ -898,6 +1025,8 @@ class Edfa(_Node):
|
||||
spectral_info.apply_gain_db(self.gprofile - self.out_voa)
|
||||
spectral_info.pmd = sqrt(spectral_info.pmd ** 2 + self.params.pmd ** 2)
|
||||
spectral_info.pdl = sqrt(spectral_info.pdl ** 2 + self.params.pdl ** 2)
|
||||
self.pch_out_dbm = watt2dbm(spectral_info.signal + spectral_info.nli + spectral_info.ase)
|
||||
self.propagated_labels = spectral_info.label
|
||||
|
||||
def update_pref(self, spectral_info):
|
||||
spectral_info.pref = \
|
||||
|
||||
@@ -66,9 +66,6 @@ def trx_mode_params(equipment, trx_type_variety='', trx_mode='', error_message=F
|
||||
trx_params['roll_off'] = default_si_data.roll_off
|
||||
trx_params['tx_osnr'] = default_si_data.tx_osnr
|
||||
trx_params['min_spacing'] = None
|
||||
nch = automatic_nch(trx_params['f_min'], trx_params['f_max'], trx_params['spacing'])
|
||||
trx_params['nb_channel'] = nch
|
||||
print(f'There are {nch} channels propagating')
|
||||
|
||||
trx_params['power'] = db2lin(default_si_data.power_dbm) * 1e-3
|
||||
|
||||
|
||||
@@ -12,9 +12,10 @@ from __future__ import annotations
|
||||
from collections import namedtuple
|
||||
from collections.abc import Iterable
|
||||
from typing import Union
|
||||
from dataclasses import dataclass
|
||||
from numpy import argsort, mean, array, append, ones, ceil, any, zeros, outer, full, ndarray, asarray
|
||||
|
||||
from gnpy.core.utils import automatic_nch, lin2db, db2lin
|
||||
from gnpy.core.utils import automatic_nch, db2lin, watt2dbm
|
||||
from gnpy.core.exceptions import SpectrumError
|
||||
|
||||
DEFAULT_SLOT_WIDTH_STEP = 12.5e9 # Hz
|
||||
@@ -41,18 +42,21 @@ class Channel(namedtuple('Channel',
|
||||
"""
|
||||
|
||||
|
||||
class Pref(namedtuple('Pref', 'p_span0, p_spani, neq_ch ')):
|
||||
class Pref(namedtuple('Pref', 'p_span0, p_spani, ref_carrier')):
|
||||
"""noiseless reference power in dBm:
|
||||
p_span0: inital target carrier power
|
||||
p_spani: carrier power after element i
|
||||
neq_ch: equivalent channel count in dB"""
|
||||
p_span0: inital target carrier power for a reference channel defined by user
|
||||
p_spani: carrier power after element i for a reference channel defined by user
|
||||
ref_carrier records the baud rate of the reference channel
|
||||
"""
|
||||
|
||||
|
||||
class SpectralInformation(object):
|
||||
""" Class containing the parameters of the entire WDM comb."""
|
||||
""" Class containing the parameters of the entire WDM comb.
|
||||
delta_pdb_per_channel: (per frequency) per channel delta power in dbm for the actual mix of channels"""
|
||||
|
||||
def __init__(self, frequency: array, baud_rate: array, slot_width: array, signal: array, nli: array, ase: array,
|
||||
roll_off: array, chromatic_dispersion: array, pmd: array, pdl: array):
|
||||
roll_off: array, chromatic_dispersion: array, pmd: array, pdl: array, delta_pdb_per_channel: array,
|
||||
tx_osnr: array, ref_power: Pref, label: array):
|
||||
indices = argsort(frequency)
|
||||
self._frequency = frequency[indices]
|
||||
self._df = outer(ones(frequency.shape), frequency) - outer(frequency, ones(frequency.shape))
|
||||
@@ -77,8 +81,10 @@ class SpectralInformation(object):
|
||||
self._chromatic_dispersion = chromatic_dispersion[indices]
|
||||
self._pmd = pmd[indices]
|
||||
self._pdl = pdl[indices]
|
||||
pref = lin2db(mean(signal) * 1e3)
|
||||
self._pref = Pref(pref, pref, lin2db(self._number_of_channels))
|
||||
self._delta_pdb_per_channel = delta_pdb_per_channel[indices]
|
||||
self._tx_osnr = tx_osnr[indices]
|
||||
self._pref = ref_power
|
||||
self._label = label[indices]
|
||||
|
||||
@property
|
||||
def pref(self):
|
||||
@@ -155,6 +161,10 @@ class SpectralInformation(object):
|
||||
def pmd(self):
|
||||
return self._pmd
|
||||
|
||||
@property
|
||||
def label(self):
|
||||
return self._label
|
||||
|
||||
@pmd.setter
|
||||
def pmd(self, pmd):
|
||||
self._pmd = pmd
|
||||
@@ -167,6 +177,22 @@ class SpectralInformation(object):
|
||||
def pdl(self, pdl):
|
||||
self._pdl = pdl
|
||||
|
||||
@property
|
||||
def delta_pdb_per_channel(self):
|
||||
return self._delta_pdb_per_channel
|
||||
|
||||
@delta_pdb_per_channel.setter
|
||||
def delta_pdb_per_channel(self, delta_pdb_per_channel):
|
||||
self._delta_pdb_per_channel = delta_pdb_per_channel
|
||||
|
||||
@property
|
||||
def tx_osnr(self):
|
||||
return self._tx_osnr
|
||||
|
||||
@tx_osnr.setter
|
||||
def tx_osnr(self, tx_osnr):
|
||||
self._tx_osnr = tx_osnr
|
||||
|
||||
@property
|
||||
def channel_number(self):
|
||||
return self._channel_number
|
||||
@@ -197,6 +223,12 @@ class SpectralInformation(object):
|
||||
|
||||
def __add__(self, other: SpectralInformation):
|
||||
try:
|
||||
# Note that pref.p_spanx from "self" and "other" must be identical for a given simulation (correspond to the
|
||||
# the simulation setup):
|
||||
# - for a given simulation there is only one design (one p_span0),
|
||||
# - and p_spani is the propagation result of p_span0 so there should not be different p_spani either.
|
||||
if (self.pref.p_span0 != other.pref.p_span0) or (self.pref.p_spani != other.pref.p_spani):
|
||||
raise SpectrumError('reference powers of the spectrum are not identical')
|
||||
return SpectralInformation(frequency=append(self.frequency, other.frequency),
|
||||
slot_width=append(self.slot_width, other.slot_width),
|
||||
signal=append(self.signal, other.signal), nli=append(self.nli, other.nli),
|
||||
@@ -206,10 +238,16 @@ class SpectralInformation(object):
|
||||
chromatic_dispersion=append(self.chromatic_dispersion,
|
||||
other.chromatic_dispersion),
|
||||
pmd=append(self.pmd, other.pmd),
|
||||
pdl=append(self.pdl, other.pdl))
|
||||
pdl=append(self.pdl, other.pdl),
|
||||
delta_pdb_per_channel=append(self.delta_pdb_per_channel,
|
||||
other.delta_pdb_per_channel),
|
||||
tx_osnr=append(self.tx_osnr, other.tx_osnr),
|
||||
ref_power=Pref(self.pref.p_span0, self.pref.p_spani, self.pref.ref_carrier),
|
||||
label=append(self.label, other.label))
|
||||
except SpectrumError:
|
||||
raise SpectrumError('Spectra cannot be summed: channels overlapping.')
|
||||
|
||||
|
||||
def _replace(self, carriers, pref):
|
||||
self.chromatic_dispersion = array([c.chromatic_dispersion for c in carriers])
|
||||
self.pmd = array([c.pmd for c in carriers])
|
||||
@@ -221,14 +259,18 @@ class SpectralInformation(object):
|
||||
return self
|
||||
|
||||
|
||||
def create_arbitrary_spectral_information(frequency: Union[ndarray, Iterable, int, float],
|
||||
signal: Union[int, float, ndarray, Iterable],
|
||||
baud_rate: Union[int, float, ndarray, Iterable],
|
||||
slot_width: Union[int, float, ndarray, Iterable] = None,
|
||||
roll_off: Union[int, float, ndarray, Iterable] = 0.,
|
||||
chromatic_dispersion: Union[int, float, ndarray, Iterable] = 0.,
|
||||
pmd: Union[int, float, ndarray, Iterable] = 0.,
|
||||
pdl: Union[int, float, ndarray, Iterable] = 0.):
|
||||
def create_arbitrary_spectral_information(frequency: Union[ndarray, Iterable, float],
|
||||
signal: Union[float, ndarray, Iterable],
|
||||
baud_rate: Union[float, ndarray, Iterable],
|
||||
tx_osnr: Union[float, ndarray, Iterable],
|
||||
delta_pdb_per_channel: Union[float, ndarray, Iterable] = 0.,
|
||||
slot_width: Union[float, ndarray, Iterable] = None,
|
||||
roll_off: Union[float, ndarray, Iterable] = 0.,
|
||||
chromatic_dispersion: Union[float, ndarray, Iterable] = 0.,
|
||||
pmd: Union[float, ndarray, Iterable] = 0.,
|
||||
pdl: Union[float, ndarray, Iterable] = 0.,
|
||||
ref_power: Pref = None,
|
||||
label: Union[str, ndarray, Iterable] = None):
|
||||
"""This is just a wrapper around the SpectralInformation.__init__() that simplifies the creation of
|
||||
a non-uniform spectral information with NLI and ASE powers set to zero."""
|
||||
frequency = asarray(frequency)
|
||||
@@ -244,11 +286,17 @@ def create_arbitrary_spectral_information(frequency: Union[ndarray, Iterable, in
|
||||
pdl = full(number_of_channels, pdl)
|
||||
nli = zeros(number_of_channels)
|
||||
ase = zeros(number_of_channels)
|
||||
delta_pdb_per_channel = full(number_of_channels, delta_pdb_per_channel)
|
||||
tx_osnr = full(number_of_channels, tx_osnr)
|
||||
label = full(number_of_channels, label)
|
||||
return SpectralInformation(frequency=frequency, slot_width=slot_width,
|
||||
signal=signal, nli=nli, ase=ase,
|
||||
baud_rate=baud_rate, roll_off=roll_off,
|
||||
chromatic_dispersion=chromatic_dispersion,
|
||||
pmd=pmd, pdl=pdl)
|
||||
pmd=pmd, pdl=pdl,
|
||||
delta_pdb_per_channel=delta_pdb_per_channel,
|
||||
tx_osnr=tx_osnr,
|
||||
ref_power=ref_power, label=label)
|
||||
except ValueError as e:
|
||||
if 'could not broadcast' in str(e):
|
||||
raise SpectrumError('Dimension mismatch in input fields.')
|
||||
@@ -256,9 +304,82 @@ def create_arbitrary_spectral_information(frequency: Union[ndarray, Iterable, in
|
||||
raise
|
||||
|
||||
|
||||
def create_input_spectral_information(f_min, f_max, roll_off, baud_rate, power, spacing):
|
||||
""" Creates a fixed slot width spectral information with flat power """
|
||||
nb_channel = automatic_nch(f_min, f_max, spacing)
|
||||
frequency = [(f_min + spacing * i) for i in range(1, nb_channel + 1)]
|
||||
def create_input_spectral_information(f_min, f_max, roll_off, baud_rate, power, spacing, tx_osnr, ref_carrier=None):
|
||||
""" Creates a fixed slot width spectral information with flat power.
|
||||
all arguments are scalar values"""
|
||||
number_of_channels = automatic_nch(f_min, f_max, spacing)
|
||||
frequency = [(f_min + spacing * i) for i in range(1, number_of_channels + 1)]
|
||||
p_span0 = watt2dbm(power)
|
||||
p_spani = watt2dbm(power)
|
||||
delta_pdb_per_channel = zeros(number_of_channels)
|
||||
label = [f'{baud_rate * 1e-9 :.2f}G' for i in range(number_of_channels)]
|
||||
return create_arbitrary_spectral_information(frequency, slot_width=spacing, signal=power, baud_rate=baud_rate,
|
||||
roll_off=roll_off)
|
||||
roll_off=roll_off, delta_pdb_per_channel=delta_pdb_per_channel,
|
||||
tx_osnr=tx_osnr,
|
||||
ref_power=Pref(p_span0=p_span0, p_spani=p_spani,
|
||||
ref_carrier=ref_carrier),
|
||||
label=label)
|
||||
|
||||
|
||||
def carriers_to_spectral_information(initial_spectrum: dict[float, Carrier], power: float,
|
||||
ref_carrier: ReferenceCarrier) -> SpectralInformation:
|
||||
"""Initial spectrum is a dict with key = carrier frequency, and value a Carrier object.
|
||||
:param initial_spectrum: indexed by frequency in Hz, with power offset (delta_pdb), baudrate, slot width,
|
||||
tx_osnr and roll off.
|
||||
:param power: power of the request
|
||||
:param ref_carrier: reference carrier (baudrate) used for the reference channel
|
||||
"""
|
||||
frequency = list(initial_spectrum.keys())
|
||||
signal = [power * db2lin(c.delta_pdb) for c in initial_spectrum.values()]
|
||||
roll_off = [c.roll_off for c in initial_spectrum.values()]
|
||||
baud_rate = [c.baud_rate for c in initial_spectrum.values()]
|
||||
delta_pdb_per_channel = [c.delta_pdb for c in initial_spectrum.values()]
|
||||
slot_width = [c.slot_width for c in initial_spectrum.values()]
|
||||
tx_osnr = [c.tx_osnr for c in initial_spectrum.values()]
|
||||
label = [c.label for c in initial_spectrum.values()]
|
||||
p_span0 = watt2dbm(power)
|
||||
p_spani = watt2dbm(power)
|
||||
return create_arbitrary_spectral_information(frequency=frequency, signal=signal, baud_rate=baud_rate,
|
||||
slot_width=slot_width, roll_off=roll_off,
|
||||
delta_pdb_per_channel=delta_pdb_per_channel, tx_osnr=tx_osnr,
|
||||
ref_power=Pref(p_span0=p_span0, p_spani=p_spani,
|
||||
ref_carrier=ref_carrier),
|
||||
label=label)
|
||||
|
||||
|
||||
@dataclass
|
||||
class Carrier:
|
||||
"""One channel in the initial mixed-type spectrum definition, each type being defined by
|
||||
its delta_pdb (power offset with respect to reference power), baud rate, slot_width, roll_off
|
||||
and tx_osnr. delta_pdb offset is applied to target power out of Roadm.
|
||||
Label is used to group carriers which belong to the same partition when printing results.
|
||||
"""
|
||||
delta_pdb: float
|
||||
baud_rate: float
|
||||
slot_width: float
|
||||
roll_off: float
|
||||
tx_osnr: float
|
||||
label: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class ReferenceCarrier:
|
||||
"""Reference channel type is used to determine target power out of ROADM for the reference channel when
|
||||
constant power spectral density (PSD) equalization is set. Reference channel is the type that has been defined
|
||||
in SI block and used for the initial design of the network.
|
||||
Computing the power out of ROADM for the reference channel is required to correctly compute the loss
|
||||
experienced by p_span_i in Roadm element.
|
||||
|
||||
Baud rate is required to find the target power in constant PSD: power = PSD_target * baud_rate.
|
||||
For example, if target PSD is 3.125e4mW/GHz and reference carrier type a 32 GBaud channel then
|
||||
output power should be -20 dBm and for a 64 GBaud channel power target would need 3 dB more: -17 dBm.
|
||||
|
||||
Slot width is required to find the target power in constant PSW (constant power per slot width equalization):
|
||||
power = PSW_target * slot_width.
|
||||
For example, if target PSW is 2e4mW/GHz and reference carrier type a 32 GBaud channel in a 50GHz slot width then
|
||||
output power should be -20 dBm and for a 64 GBaud channel in a 75 GHz slot width, power target would be -18.24 dBm.
|
||||
|
||||
Other attributes (like slot_width or roll-off) may be added there for future equalization purpose.
|
||||
"""
|
||||
baud_rate: float
|
||||
slot_width: float
|
||||
|
||||
@@ -12,6 +12,7 @@ from operator import attrgetter
|
||||
from gnpy.core import ansi_escapes, elements
|
||||
from gnpy.core.exceptions import ConfigurationError, NetworkTopologyError
|
||||
from gnpy.core.utils import round2float, convert_length
|
||||
from gnpy.core.info import ReferenceCarrier
|
||||
from collections import namedtuple
|
||||
|
||||
|
||||
@@ -237,22 +238,20 @@ def set_egress_amplifier(network, this_node, equipment, pref_ch_db, pref_total_d
|
||||
""" this node can be a transceiver or a ROADM (same function called in both cases)
|
||||
"""
|
||||
power_mode = equipment['Span']['default'].power_mode
|
||||
ref_carrier = ReferenceCarrier(baud_rate=equipment['SI']['default'].baud_rate,
|
||||
slot_width=equipment['SI']['default'].spacing)
|
||||
next_oms = (n for n in network.successors(this_node) if not isinstance(n, elements.Transceiver))
|
||||
this_node_degree = getattr(this_node, 'per_degree_pch_out_dbm', {})
|
||||
for oms in next_oms:
|
||||
# go through all the OMS departing from the ROADM
|
||||
prev_node = this_node
|
||||
node = oms
|
||||
# if isinstance(next_node, elements.Fused): #support ROADM wo egress amp for metro applications
|
||||
# node = find_last_node(next_node)
|
||||
# next_node = next(n for n in network.successors(node))
|
||||
# next_node = find_last_node(next_node)
|
||||
if node.uid not in this_node_degree:
|
||||
# if no target power is defined on this degree or no per degree target power is given use the global one
|
||||
# if target_pch_out_db is not an attribute, then the element must be a transceiver
|
||||
this_node_degree[node.uid] = getattr(this_node.params, 'target_pch_out_db', 0)
|
||||
if isinstance(this_node, elements.Transceiver):
|
||||
this_node_out_power = 0.0 # default value if this_node is a transceiver
|
||||
if isinstance(this_node, elements.Roadm):
|
||||
# get target power out from ROADM for the reference carrier based on equalization settings
|
||||
this_node_out_power = this_node.get_per_degree_ref_power(degree=node.uid, ref_carrier=ref_carrier)
|
||||
# use the target power on this degree
|
||||
prev_dp = this_node_degree[node.uid] - pref_ch_db
|
||||
prev_dp = this_node_out_power - pref_ch_db
|
||||
dp = prev_dp
|
||||
prev_voa = 0
|
||||
voa = 0
|
||||
@@ -331,10 +330,28 @@ def set_egress_amplifier(network, this_node, equipment, pref_ch_db, pref_total_d
|
||||
prev_voa = voa
|
||||
prev_node = node
|
||||
node = next_node
|
||||
# print(f'{node.uid}')
|
||||
|
||||
if isinstance(this_node, elements.Roadm):
|
||||
this_node.per_degree_pch_out_dbm = {k: v for k, v in this_node_degree.items()}
|
||||
|
||||
def set_roadm_per_degree_targets(roadm, network):
|
||||
"""Set target powers/PSD on all degrees
|
||||
This is needed to populate per_degree_pch_out_dbm or per_degree_pch_psd or per_degree_pch_psw dicts when
|
||||
they are not initialized by users.
|
||||
"""
|
||||
next_oms = (n for n in network.successors(roadm) if not isinstance(n, elements.Transceiver))
|
||||
|
||||
for node in next_oms:
|
||||
# go through all the OMS departing from the ROADM
|
||||
if node.uid not in roadm.per_degree_pch_out_dbm and node.uid not in roadm.per_degree_pch_psd and \
|
||||
node.uid not in roadm.per_degree_pch_psw:
|
||||
# if no target power is defined on this degree or no per degree target power is given use the global one
|
||||
if roadm.params.target_pch_out_db:
|
||||
roadm.per_degree_pch_out_dbm[node.uid] = roadm.params.target_pch_out_db
|
||||
elif roadm.params.target_psd_out_mWperGHz:
|
||||
roadm.per_degree_pch_psd[node.uid] = roadm.params.target_psd_out_mWperGHz
|
||||
elif roadm.params.target_out_mWperSlotWidth:
|
||||
roadm.per_degree_pch_psw[node.uid] = roadm.params.target_out_mWperSlotWidth
|
||||
else:
|
||||
raise ConfigurationError(roadm.uid, 'needs an equalization target')
|
||||
|
||||
|
||||
def add_roadm_booster(network, roadm):
|
||||
@@ -432,10 +449,10 @@ def calculate_new_length(fiber_length, bounds, target_length):
|
||||
return (length1, n_spans1)
|
||||
elif (bounds.start <= length2 <= bounds.stop) and not(bounds.start <= length1 <= bounds.stop):
|
||||
return (length2, n_spans2)
|
||||
elif target_length - length1 < length2 - target_length:
|
||||
return (length1, n_spans1)
|
||||
else:
|
||||
elif length2 - target_length <= target_length - length1 and length2 <= bounds.stop:
|
||||
return (length2, n_spans2)
|
||||
else:
|
||||
return (length1, n_spans1)
|
||||
|
||||
|
||||
def split_fiber(network, fiber, bounds, target_length, equipment):
|
||||
@@ -547,6 +564,7 @@ def build_network(network, equipment, pref_ch_db, pref_total_db, no_insert_edfas
|
||||
add_fiber_padding(network, fibers, default_span_data.padding)
|
||||
|
||||
for roadm in roadms:
|
||||
set_roadm_per_degree_targets(roadm, network)
|
||||
set_egress_amplifier(network, roadm, equipment, pref_ch_db, pref_total_db)
|
||||
|
||||
trx = [t for t in network.nodes() if isinstance(t, elements.Transceiver)]
|
||||
|
||||
@@ -88,13 +88,22 @@ class SimParams(Parameters):
|
||||
|
||||
class RoadmParams(Parameters):
|
||||
def __init__(self, **kwargs):
|
||||
self.target_pch_out_db = kwargs.get('target_pch_out_db')
|
||||
self.target_psd_out_mWperGHz = kwargs.get('target_psd_out_mWperGHz')
|
||||
self.target_out_mWperSlotWidth = kwargs.get('target_out_mWperSlotWidth')
|
||||
equalisation_type = ['target_pch_out_db', 'target_psd_out_mWperGHz', 'target_out_mWperSlotWidth']
|
||||
temp = [kwargs.get(k) is not None for k in equalisation_type]
|
||||
if sum(temp) > 1:
|
||||
raise ParametersError('ROADM config contains more than one equalisation type.'
|
||||
+ 'Please choose only one', kwargs)
|
||||
self.per_degree_pch_out_db = kwargs.get('per_degree_pch_out_db', {})
|
||||
self.per_degree_pch_psd = kwargs.get('per_degree_psd_out_mWperGHz', {})
|
||||
self.per_degree_pch_psw = kwargs.get('per_degree_psd_out_mWperSlotWidth', {})
|
||||
try:
|
||||
self.target_pch_out_db = kwargs['target_pch_out_db']
|
||||
self.add_drop_osnr = kwargs['add_drop_osnr']
|
||||
self.pmd = kwargs['pmd']
|
||||
self.pdl = kwargs['pdl']
|
||||
self.restrictions = kwargs['restrictions']
|
||||
self.per_degree_pch_out_db = kwargs['per_degree_pch_out_db'] if 'per_degree_pch_out_db' in kwargs else {}
|
||||
except KeyError as e:
|
||||
raise ParametersError(f'ROADM configurations must include {e}. Configuration: {kwargs}')
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ This module contains utility functions that are used with gnpy.
|
||||
"""
|
||||
|
||||
from csv import writer
|
||||
from numpy import pi, cos, sqrt, log10, linspace, zeros, shape, where, logical_and
|
||||
from numpy import pi, cos, sqrt, log10, linspace, zeros, shape, where, logical_and, mean
|
||||
from scipy import constants
|
||||
|
||||
from gnpy.core.exceptions import ConfigurationError
|
||||
@@ -229,6 +229,32 @@ def snr_sum(snr, bw, snr_added, bw_added=12.5e9):
|
||||
return snr
|
||||
|
||||
|
||||
def per_label_average(values, labels):
|
||||
"""computes the average per defined spectrum band, using labels
|
||||
|
||||
>>> labels = ['A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'B', 'C', 'D', 'D', 'D', 'D']
|
||||
>>> values = [28.51, 28.23, 28.15, 28.17, 28.36, 28.53, 28.64, 28.68, 28.7, 28.71, 28.72, 28.73, 28.74, 28.91, 27.96, 27.85, 27.87, 28.02]
|
||||
>>> per_label_average(values, labels)
|
||||
{'A': 28.28, 'B': 28.68, 'C': 28.91, 'D': 27.92}
|
||||
"""
|
||||
|
||||
label_set = sorted(set(labels))
|
||||
summary = {}
|
||||
for label in label_set:
|
||||
vals = [val for val, lab in zip(values, labels) if lab == label]
|
||||
summary[label] = round(mean(vals), 2)
|
||||
return summary
|
||||
|
||||
|
||||
def pretty_summary_print(summary):
|
||||
"""Build a prettty string that shows the summary dict values per label with 2 digits
|
||||
"""
|
||||
if len(summary) == 1:
|
||||
return f'{list(summary.values())[0]:.2f}'
|
||||
text = ', '.join([f'{label}: {value:.2f}' for label, value in summary.items()])
|
||||
return text
|
||||
|
||||
|
||||
def deltawl2deltaf(delta_wl, wavelength):
|
||||
""" deltawl2deltaf(delta_wl, wavelength):
|
||||
delta_wl is BW in wavelength units
|
||||
|
||||
12
gnpy/example-data/initial_spectrum1.json
Normal file
12
gnpy/example-data/initial_spectrum1.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"spectrum":[
|
||||
{
|
||||
"f_min": 191.35e12,
|
||||
"f_max": 195.1e12,
|
||||
"baud_rate": 32e9,
|
||||
"slot_width": 50e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40
|
||||
}
|
||||
]
|
||||
}
|
||||
23
gnpy/example-data/initial_spectrum2.json
Normal file
23
gnpy/example-data/initial_spectrum2.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"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,
|
||||
"label": "mode_2"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import sys
|
||||
from math import ceil
|
||||
from numpy import linspace, mean
|
||||
from pathlib import Path
|
||||
|
||||
import gnpy.core.ansi_escapes as ansi_escapes
|
||||
from gnpy.core.elements import Transceiver, Fiber, RamanFiber
|
||||
from gnpy.core.equipment import trx_mode_params
|
||||
@@ -26,8 +27,8 @@ from gnpy.topology.request import (ResultElement, jsontocsv, compute_path_dsjctn
|
||||
deduplicate_disjunctions, compute_path_with_disjunction,
|
||||
PathRequest, compute_constrained_path, propagate)
|
||||
from gnpy.topology.spectrum_assignment import build_oms_list, pth_assign_spectrum
|
||||
from gnpy.tools.json_io import load_equipment, load_network, load_json, load_requests, save_network, \
|
||||
requests_from_json, disjunctions_from_json, save_json
|
||||
from gnpy.tools.json_io import (load_equipment, load_network, load_json, load_requests, save_network,
|
||||
requests_from_json, disjunctions_from_json, save_json, load_initial_spectrum)
|
||||
from gnpy.tools.plots import plot_baseline, plot_results
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
@@ -118,6 +119,7 @@ def transmission_main_example(args=None):
|
||||
parser.add_argument('-pl', '--plot', action='store_true')
|
||||
parser.add_argument('-l', '--list-nodes', action='store_true', help='list all transceiver nodes')
|
||||
parser.add_argument('-po', '--power', default=0, help='channel ref power in dBm')
|
||||
parser.add_argument('--spectrum', type=Path, help='user defined mixed rate spectrum JSON file')
|
||||
parser.add_argument('source', nargs='?', help='source node')
|
||||
parser.add_argument('destination', nargs='?', help='destination node')
|
||||
|
||||
@@ -194,12 +196,21 @@ def transmission_main_example(args=None):
|
||||
if args.power:
|
||||
trx_params['power'] = db2lin(float(args.power)) * 1e-3
|
||||
params.update(trx_params)
|
||||
initial_spectrum = None
|
||||
nb_channels = automatic_nch(trx_params['f_min'], trx_params['f_max'], trx_params['spacing'])
|
||||
if args.spectrum:
|
||||
initial_spectrum = load_initial_spectrum(args.spectrum)
|
||||
nb_channels = len(initial_spectrum)
|
||||
print('User input for spectrum used for propagation instead of SI')
|
||||
params['nb_channel'] = nb_channels
|
||||
req = PathRequest(**params)
|
||||
|
||||
req.initial_spectrum = initial_spectrum
|
||||
print(f'There are {nb_channels} channels propagating')
|
||||
power_mode = equipment['Span']['default'].power_mode
|
||||
print('\n'.join([f'Power mode is set to {power_mode}',
|
||||
f'=> it can be modified in eqpt_config.json - Span']))
|
||||
|
||||
# Keep the reference channel for design: the one from SI, with full load same channels
|
||||
pref_ch_db = lin2db(req.power * 1e3) # reference channel power / span (SL=20dB)
|
||||
pref_total_db = pref_ch_db + lin2db(req.nb_channel) # reference total power / span (SL=20dB)
|
||||
try:
|
||||
@@ -226,9 +237,13 @@ def transmission_main_example(args=None):
|
||||
power_range = list(linspace(p_start, p_stop, p_num))
|
||||
except TypeError:
|
||||
print('invalid power range definition in eqpt_config, should be power_range_db: [lower, upper, step]')
|
||||
|
||||
for dp_db in power_range:
|
||||
req.power = db2lin(pref_ch_db + dp_db) * 1e-3
|
||||
# if initial spectrum did not contain any power, now we need to use this one.
|
||||
# note the initial power defines a differential wrt req.power so that if req.power is set to 2mW (3dBm)
|
||||
# and initial spectrum was set to 0, this sets a initial per channel delta power to -3dB, so that
|
||||
# whatever the equalization, -3 dB is applied on all channels (ie initial power in initial spectrum pre-empts
|
||||
# "--power" option)
|
||||
if power_mode:
|
||||
print(f'\nPropagating with input power = {ansi_escapes.cyan}{lin2db(req.power*1e3):.2f} dBm{ansi_escapes.reset}:')
|
||||
else:
|
||||
@@ -264,9 +279,9 @@ def transmission_main_example(args=None):
|
||||
ch_freq = final_carrier.frequency * 1e-12
|
||||
ch_power = lin2db(final_carrier.power.signal * 1e3)
|
||||
print(
|
||||
'{:5}{:26.2f}{:26.2f}{:28.2f}{:28.2f}{:28.2f}' .format(
|
||||
'{:5}{:26.5f}{:26.2f}{:28.2f}{:28.2f}{:28.2f}' .format(
|
||||
final_carrier.channel_number, round(
|
||||
ch_freq, 2), round(
|
||||
ch_freq, 5), round(
|
||||
ch_power, 2), round(
|
||||
ch_osnr, 2), round(
|
||||
ch_snr_nl, 2), round(
|
||||
|
||||
@@ -13,10 +13,13 @@ from logging import getLogger
|
||||
from pathlib import Path
|
||||
import json
|
||||
from collections import namedtuple
|
||||
from numpy import arange
|
||||
|
||||
from gnpy.core import ansi_escapes, elements
|
||||
from gnpy.core.equipment import trx_mode_params
|
||||
from gnpy.core.exceptions import ConfigurationError, EquipmentConfigError, NetworkTopologyError, ServiceError
|
||||
from gnpy.core.science_utils import estimate_nf_model
|
||||
from gnpy.core.info import Carrier
|
||||
from gnpy.core.utils import automatic_nch, automatic_fmax, merge_amplifier_restrictions
|
||||
from gnpy.topology.request import PathRequest, Disjunction, compute_spectrum_slot_vs_bandwidth
|
||||
from gnpy.tools.convert import xls_to_json_data
|
||||
@@ -91,7 +94,6 @@ class Span(_JsonThing):
|
||||
|
||||
class Roadm(_JsonThing):
|
||||
default_values = {
|
||||
'target_pch_out_db': -17,
|
||||
'add_drop_osnr': 100,
|
||||
'pmd': 0,
|
||||
'pdl': 0,
|
||||
@@ -102,6 +104,20 @@ class Roadm(_JsonThing):
|
||||
}
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
# If equalization is not defined in equipment, then raise an error.
|
||||
# Only one type of equalization must be defined.
|
||||
allowed_equalisations = ['target_pch_out_db', 'target_psd_out_mWperGHz', 'target_out_mWperSlotWidth']
|
||||
requested_eq_mask = [eq in kwargs for eq in allowed_equalisations]
|
||||
if sum(requested_eq_mask) > 1:
|
||||
raise EquipmentConfigError('Only one equalization type should be set in ROADM, found: '
|
||||
+ ', '.join(eq for eq in allowed_equalisations if eq in kwargs))
|
||||
if not any(requested_eq_mask):
|
||||
raise EquipmentConfigError('No equalization type set in ROADM')
|
||||
|
||||
for key in allowed_equalisations:
|
||||
if key in kwargs:
|
||||
setattr(self, key, kwargs[key])
|
||||
break
|
||||
self.update_attr(self.default_values, kwargs, 'Roadm')
|
||||
|
||||
|
||||
@@ -249,11 +265,89 @@ def _automatic_spacing(baud_rate):
|
||||
return min((s[1] for s in spacing_list if s[0] > baud_rate), default=baud_rate * 1.2)
|
||||
|
||||
|
||||
def _spectrum_from_json(json_data):
|
||||
"""JSON_data is a list of spectrum partitions each with
|
||||
{f_min, f_max, baud_rate, roll_off, delta_pdb, slot_width, tx_osnr, label}
|
||||
Creates the per freq Carrier's dict.
|
||||
f_min, f_max, baud_rate, slot_width and roll_off are mandatory
|
||||
label, tx_osnr and delta_pdb are created if not present
|
||||
label should be different for each partition
|
||||
>>> json_data = {'spectrum': \
|
||||
[{'f_min': 193.2e12, 'f_max': 193.4e12, 'slot_width': 50e9, 'baud_rate': 32e9, 'roll_off': 0.15, \
|
||||
'delta_pdb': 1, 'tx_osnr': 45},\
|
||||
{'f_min': 193.4625e12, 'f_max': 193.9875e12, 'slot_width': 75e9, 'baud_rate': 64e9, 'roll_off': 0.15},\
|
||||
{'f_min': 194.075e12, 'f_max': 194.075e12, 'slot_width': 100e9, 'baud_rate': 90e9, 'roll_off': 0.15},\
|
||||
{'f_min': 194.2e12, 'f_max': 194.35e12, 'slot_width': 50e9, 'baud_rate': 32e9, 'roll_off': 0.15}]}
|
||||
>>> spectrum = _spectrum_from_json(json_data['spectrum'])
|
||||
>>> for k, v in spectrum.items():
|
||||
... print(f'{k}: {v}')
|
||||
...
|
||||
193200000000000.0: Carrier(delta_pdb=1, baud_rate=32000000000.0, slot_width=50000000000.0, roll_off=0.15, tx_osnr=45, label='0-32.00G')
|
||||
193250000000000.0: Carrier(delta_pdb=1, baud_rate=32000000000.0, slot_width=50000000000.0, roll_off=0.15, tx_osnr=45, label='0-32.00G')
|
||||
193300000000000.0: Carrier(delta_pdb=1, baud_rate=32000000000.0, slot_width=50000000000.0, roll_off=0.15, tx_osnr=45, label='0-32.00G')
|
||||
193350000000000.0: Carrier(delta_pdb=1, baud_rate=32000000000.0, slot_width=50000000000.0, roll_off=0.15, tx_osnr=45, label='0-32.00G')
|
||||
193400000000000.0: Carrier(delta_pdb=1, baud_rate=32000000000.0, slot_width=50000000000.0, roll_off=0.15, tx_osnr=45, label='0-32.00G')
|
||||
193462500000000.0: Carrier(delta_pdb=0, baud_rate=64000000000.0, slot_width=75000000000.0, roll_off=0.15, tx_osnr=40, label='1-64.00G')
|
||||
193537500000000.0: Carrier(delta_pdb=0, baud_rate=64000000000.0, slot_width=75000000000.0, roll_off=0.15, tx_osnr=40, label='1-64.00G')
|
||||
193612500000000.0: Carrier(delta_pdb=0, baud_rate=64000000000.0, slot_width=75000000000.0, roll_off=0.15, tx_osnr=40, label='1-64.00G')
|
||||
193687500000000.0: Carrier(delta_pdb=0, baud_rate=64000000000.0, slot_width=75000000000.0, roll_off=0.15, tx_osnr=40, label='1-64.00G')
|
||||
193762500000000.0: Carrier(delta_pdb=0, baud_rate=64000000000.0, slot_width=75000000000.0, roll_off=0.15, tx_osnr=40, label='1-64.00G')
|
||||
193837500000000.0: Carrier(delta_pdb=0, baud_rate=64000000000.0, slot_width=75000000000.0, roll_off=0.15, tx_osnr=40, label='1-64.00G')
|
||||
193912500000000.0: Carrier(delta_pdb=0, baud_rate=64000000000.0, slot_width=75000000000.0, roll_off=0.15, tx_osnr=40, label='1-64.00G')
|
||||
193987500000000.0: Carrier(delta_pdb=0, baud_rate=64000000000.0, slot_width=75000000000.0, roll_off=0.15, tx_osnr=40, label='1-64.00G')
|
||||
194075000000000.0: Carrier(delta_pdb=0, baud_rate=90000000000.0, slot_width=100000000000.0, roll_off=0.15, tx_osnr=40, label='2-90.00G')
|
||||
194200000000000.0: Carrier(delta_pdb=0, baud_rate=32000000000.0, slot_width=50000000000.0, roll_off=0.15, tx_osnr=40, label='3-32.00G')
|
||||
194250000000000.0: Carrier(delta_pdb=0, baud_rate=32000000000.0, slot_width=50000000000.0, roll_off=0.15, tx_osnr=40, label='3-32.00G')
|
||||
194300000000000.0: Carrier(delta_pdb=0, baud_rate=32000000000.0, slot_width=50000000000.0, roll_off=0.15, tx_osnr=40, label='3-32.00G')
|
||||
194350000000000.0: Carrier(delta_pdb=0, baud_rate=32000000000.0, slot_width=50000000000.0, roll_off=0.15, tx_osnr=40, label='3-32.00G')
|
||||
"""
|
||||
spectrum = {}
|
||||
json_data = sorted(json_data, key=lambda x: x['f_min'])
|
||||
# min freq of occupation is f_min - slot_width/2 (numbering starts at 0)
|
||||
previous_part_max_freq = 0.0
|
||||
for index, part in enumerate(json_data):
|
||||
# default delta_pdb is 0 dB
|
||||
if 'delta_pdb' not in part:
|
||||
part['delta_pdb'] = 0
|
||||
# add a label to the partition for the printings
|
||||
if 'label' not in part:
|
||||
part['label'] = f'{index}-{part["baud_rate"] * 1e-9 :.2f}G'
|
||||
# default tx_osnr is set to 40 dB
|
||||
if 'tx_osnr' not in part:
|
||||
part['tx_osnr'] = 40
|
||||
# starting freq is exactly f_min to be consistent with utils.automatic_nch
|
||||
# first partition min occupation is f_min - slot_width / 2 (central_frequency is f_min)
|
||||
# supposes that carriers are centered on frequency
|
||||
if previous_part_max_freq > (part['f_min'] - part['slot_width'] / 2):
|
||||
# check that previous part last channel does not overlap on next part first channel
|
||||
# max center of the part should be below part['f_max'] and aligned on the slot_width
|
||||
msg = 'Not a valid initial spectrum definition:\nprevious spectrum last carrier max occupation ' +\
|
||||
f'{previous_part_max_freq * 1e-12 :.5f}GHz ' +\
|
||||
'overlaps on next spectrum first carrier occupation ' +\
|
||||
f'{(part["f_min"] - part["slot_width"] / 2) * 1e-12 :.5f}GHz'
|
||||
raise ValueError(msg)
|
||||
|
||||
max_range = ((part['f_max'] - part['f_min']) // part['slot_width'] + 1) * part['slot_width']
|
||||
for current_freq in arange(part['f_min'],
|
||||
part['f_min'] + max_range,
|
||||
part['slot_width']):
|
||||
spectrum[current_freq] = Carrier(delta_pdb=part['delta_pdb'], baud_rate=part['baud_rate'],
|
||||
slot_width=part['slot_width'], roll_off=part['roll_off'],
|
||||
tx_osnr=part['tx_osnr'], label=part['label'])
|
||||
previous_part_max_freq = current_freq + part['slot_width'] / 2
|
||||
return spectrum
|
||||
|
||||
|
||||
def load_equipment(filename):
|
||||
json_data = load_json(filename)
|
||||
return _equipment_from_json(json_data, filename)
|
||||
|
||||
|
||||
def load_initial_spectrum(filename):
|
||||
json_data = load_json(filename)
|
||||
return _spectrum_from_json(json_data['spectrum'])
|
||||
|
||||
|
||||
def _update_dual_stage(equipment):
|
||||
edfa_dict = equipment['Edfa']
|
||||
for edfa in edfa_dict.values():
|
||||
@@ -384,9 +478,16 @@ def network_from_json(json_data, equipment):
|
||||
# well, there's no variety for the 'Fused' node type
|
||||
pass
|
||||
elif variety in equipment[typ]:
|
||||
extra_params = equipment[typ][variety]
|
||||
extra_params = equipment[typ][variety].__dict__
|
||||
temp = el_config.setdefault('params', {})
|
||||
temp = merge_amplifier_restrictions(temp, extra_params.__dict__)
|
||||
if typ == 'Roadm':
|
||||
# if equalization is defined, remove default equalization from the extra_params
|
||||
# If equalisation is not defined in the element config, then use the default one from equipment
|
||||
# if more than one equalization was defined in element config, then raise an error
|
||||
extra_params = merge_equalization(temp, extra_params)
|
||||
if not extra_params:
|
||||
raise ConfigurationError(f'ROADM {el_config["uid"]}: invalid equalization settings')
|
||||
temp = merge_amplifier_restrictions(temp, extra_params)
|
||||
el_config['params'] = temp
|
||||
el_config['type_variety'] = variety
|
||||
elif (typ in ['Fiber', 'RamanFiber']) or (typ == 'Edfa' and variety not in ['default', '']):
|
||||
@@ -457,16 +558,16 @@ def requests_from_json(json_data, equipment):
|
||||
for req in json_data['path-request']:
|
||||
# init all params from request
|
||||
params = {}
|
||||
params['request_id'] = req['request-id']
|
||||
params['request_id'] = f'{req["request-id"]}'
|
||||
params['source'] = req['source']
|
||||
params['bidir'] = req['bidirectional']
|
||||
params['destination'] = req['destination']
|
||||
params['trx_type'] = req['path-constraints']['te-bandwidth']['trx_type']
|
||||
params['trx_mode'] = req['path-constraints']['te-bandwidth']['trx_mode']
|
||||
params['trx_mode'] = req['path-constraints']['te-bandwidth'].get('trx_mode', None)
|
||||
params['format'] = params['trx_mode']
|
||||
params['spacing'] = req['path-constraints']['te-bandwidth']['spacing']
|
||||
try:
|
||||
nd_list = req['explicit-route-objects']['route-object-include-exclude']
|
||||
nd_list = sorted(req['explicit-route-objects']['route-object-include-exclude'], key=lambda x: x['index'])
|
||||
except KeyError:
|
||||
nd_list = []
|
||||
params['nodes_list'] = [n['num-unnum-hop']['node-id'] for n in nd_list]
|
||||
@@ -576,3 +677,42 @@ def convert_service_sheet(
|
||||
data = read_service_sheet(input_filename, eqpt, network, network_filename, bidir)
|
||||
save_json(data, output_filename)
|
||||
return data
|
||||
|
||||
|
||||
def find_equalisation(params, equalization_types):
|
||||
"""Find the equalization(s) defined in params. params can be a dict or a Roadm object.
|
||||
|
||||
>>> roadm = {'add_drop_osnr': 100, 'pmd': 1, 'pdl': 0.5,
|
||||
... 'restrictions': {'preamp_variety_list': ['a'], 'booster_variety_list': ['b']},
|
||||
... 'target_psd_out_mWperGHz': 4e-4}
|
||||
>>> equalization_types = ['target_pch_out_db', 'target_psd_out_mWperGHz']
|
||||
>>> find_equalisation(roadm, equalization_types)
|
||||
{'target_pch_out_db': False, 'target_psd_out_mWperGHz': True}
|
||||
"""
|
||||
equalization = {e: False for e in equalization_types}
|
||||
for equ in equalization_types:
|
||||
if equ in params:
|
||||
equalization[equ] = True
|
||||
return equalization
|
||||
|
||||
|
||||
def merge_equalization(params, extra_params):
|
||||
"""params contains ROADM element config and extra_params default values from equipment library.
|
||||
If equalization is not defined in ROADM element use the one defined in equipment library.
|
||||
Only one type of equalization must be defined: power (target_pch_out_db) or PSD (target_psd_out_mWperGHz)
|
||||
or PSW (target_out_mWperSlotWidth)
|
||||
params and extra_params are dict
|
||||
"""
|
||||
equalization_types = ['target_pch_out_db', 'target_psd_out_mWperGHz', 'target_out_mWperSlotWidth']
|
||||
roadm_equalizations = find_equalisation(params, equalization_types)
|
||||
if sum(roadm_equalizations.values()) > 1:
|
||||
# if ROADM config contains more than one equalization type then this is an error
|
||||
return None
|
||||
if sum(roadm_equalizations.values()) == 1:
|
||||
# if ROADM config contains one equalization
|
||||
# don't use the default equalization
|
||||
return {k: v for k, v in extra_params.items() if k not in equalization_types}
|
||||
if sum(roadm_equalizations.values()) == 0:
|
||||
# If ROADM config doesn't contain any equalization type, keep the default one
|
||||
return extra_params
|
||||
return None
|
||||
|
||||
@@ -23,7 +23,7 @@ from networkx.utils import pairwise
|
||||
from numpy import mean, argmin
|
||||
from gnpy.core.elements import Transceiver, Roadm
|
||||
from gnpy.core.utils import lin2db
|
||||
from gnpy.core.info import create_input_spectral_information
|
||||
from gnpy.core.info import create_input_spectral_information, carriers_to_spectral_information, ReferenceCarrier
|
||||
from gnpy.core.exceptions import ServiceError, DisjunctionError
|
||||
import gnpy.core.ansi_escapes as ansi_escapes
|
||||
from copy import deepcopy
|
||||
@@ -72,6 +72,7 @@ class PathRequest:
|
||||
if params.effective_freq_slot is not None:
|
||||
self.N = params.effective_freq_slot['N']
|
||||
self.M = params.effective_freq_slot['M']
|
||||
self.initial_spectrum = None
|
||||
|
||||
def __str__(self):
|
||||
return '\n\t'.join([f'{type(self).__name__} {self.request_id}',
|
||||
@@ -339,21 +340,36 @@ def compute_constrained_path(network, req):
|
||||
return total_path
|
||||
|
||||
|
||||
def ref_carrier(equipment):
|
||||
"""Create a reference carier based SI information with the specified request's power:
|
||||
req_power records the power in W that the user has defined for a given request
|
||||
(which might be different from the one used for the design).
|
||||
"""
|
||||
return ReferenceCarrier(baud_rate=equipment['SI']['default'].baud_rate,
|
||||
slot_width=equipment['SI']['default'].spacing)
|
||||
|
||||
|
||||
def propagate(path, req, equipment):
|
||||
si = create_input_spectral_information(
|
||||
req.f_min, req.f_max, req.roll_off, req.baud_rate,
|
||||
req.power, req.spacing)
|
||||
""" propagates signals in each element according to initial spectrum set by user
|
||||
"""
|
||||
if req.initial_spectrum is not None:
|
||||
si = carriers_to_spectral_information(initial_spectrum=req.initial_spectrum,
|
||||
power=req.power, ref_carrier=ref_carrier(equipment))
|
||||
else:
|
||||
si = create_input_spectral_information(
|
||||
f_min=req.f_min, f_max=req.f_max, roll_off=req.roll_off, baud_rate=req.baud_rate,
|
||||
power=req.power, spacing=req.spacing, tx_osnr=req.tx_osnr, ref_carrier=ref_carrier(equipment))
|
||||
for i, el in enumerate(path):
|
||||
if isinstance(el, Roadm):
|
||||
si = el(si, degree=path[i+1].uid)
|
||||
else:
|
||||
si = el(si)
|
||||
path[0].update_snr(req.tx_osnr)
|
||||
path[0].update_snr(si.tx_osnr)
|
||||
path[0].calc_penalties(req.penalties)
|
||||
if any(isinstance(el, Roadm) for el in path):
|
||||
path[-1].update_snr(req.tx_osnr, equipment['Roadm']['default'].add_drop_osnr)
|
||||
path[-1].update_snr(si.tx_osnr, equipment['Roadm']['default'].add_drop_osnr)
|
||||
else:
|
||||
path[-1].update_snr(req.tx_osnr)
|
||||
path[-1].update_snr(si.tx_osnr)
|
||||
path[-1].calc_penalties(req.penalties)
|
||||
return si
|
||||
|
||||
@@ -374,13 +390,18 @@ def propagate_and_optimize_mode(path, req, equipment):
|
||||
float(this_mode['min_spacing']) <= req.spacing]
|
||||
modes_to_explore = sorted(modes_to_explore,
|
||||
key=lambda x: x['bit_rate'], reverse=True)
|
||||
# print(modes_to_explore)
|
||||
# step2: computes propagation for each baudrate: stop and select the first that passes
|
||||
# TODO: the case of roll of is not included: for now use SI one
|
||||
# TODO: the case of roll off is not included: for now use SI one
|
||||
# TODO: if the loop in mode optimization does not have a feasible path, then bugs
|
||||
spc_info = create_input_spectral_information(req.f_min, req.f_max,
|
||||
equipment['SI']['default'].roll_off,
|
||||
this_br, req.power, req.spacing)
|
||||
if req.initial_spectrum is not None:
|
||||
# this case is not yet handled: spectrum can not be defined for the path-request-run function
|
||||
# and this function is only called in this case. so coming here should not be considered yet.
|
||||
msg = f'Request: {req.request_id} contains a unexpected initial_spectrum.'
|
||||
raise ServiceError(msg)
|
||||
spc_info = create_input_spectral_information(f_min=req.f_min, f_max=req.f_max,
|
||||
roll_off=equipment['SI']['default'].roll_off,
|
||||
baud_rate=this_br, power=req.power, spacing=req.spacing,
|
||||
tx_osnr=req.tx_osnr, ref_carrier=ref_carrier(equipment))
|
||||
for i, el in enumerate(path):
|
||||
if isinstance(el, Roadm):
|
||||
spc_info = el(spc_info, degree=path[i+1].uid)
|
||||
|
||||
@@ -365,12 +365,6 @@ def spectrum_selection(pth, oms_list, requested_m, requested_n=None):
|
||||
candidate = (requested_n, requested_n - requested_m, requested_n + requested_m - 1)
|
||||
else:
|
||||
candidate = (None, None, None)
|
||||
# print("coucou11")
|
||||
# print(candidate)
|
||||
# print(freq_availability[321:321+2*m])
|
||||
# a = [i+321 for i in range(2*m)]
|
||||
# print(a)
|
||||
# print(candidate)
|
||||
return candidate, path_oms
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
matplotlib>=3.5.1,<4
|
||||
networkx>=2.6,<3
|
||||
numpy>=1.22.0,<2
|
||||
pandas>=1.3.5,<2
|
||||
pbr>=5.7.0,<6
|
||||
scipy>=1.7.3,<2
|
||||
xlrd>=1.2.0,<2
|
||||
|
||||
@@ -3,7 +3,7 @@ name = gnpy
|
||||
description-file = README.md
|
||||
description-content-type = text/markdown; variant=GFM
|
||||
author = Telecom Infra Project
|
||||
author-email = jan.kundrat@telecominfraproject.com
|
||||
author-email = jkt@jankundrat.com
|
||||
license = BSD-3-Clause
|
||||
home-page = https://github.com/Telecominfraproject/oopt-gnpy
|
||||
project_urls =
|
||||
@@ -22,6 +22,7 @@ classifier =
|
||||
Programming Language :: Python :: 3.8
|
||||
Programming Language :: Python :: 3.9
|
||||
Programming Language :: Python :: 3.10
|
||||
Programming Language :: Python :: 3.11
|
||||
Programming Language :: Python :: Implementation :: CPython
|
||||
Topic :: Scientific/Engineering
|
||||
Topic :: Scientific/Engineering :: Physics
|
||||
|
||||
809
tests/data/test_long_network.json
Normal file
809
tests/data/test_long_network.json
Normal file
@@ -0,0 +1,809 @@
|
||||
{
|
||||
"network_name": "Example Network - long path",
|
||||
"elements": [{
|
||||
"uid": "Site_A",
|
||||
"type": "Transceiver",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Site A",
|
||||
"region": "",
|
||||
"latitude": 0,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "roadm Site A",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Site A",
|
||||
"region": "RLD",
|
||||
"latitude": 0.0,
|
||||
"longitude": 0.0
|
||||
}
|
||||
},
|
||||
"type": "Roadm"
|
||||
},
|
||||
{
|
||||
"uid": "booster A",
|
||||
"type": "Edfa",
|
||||
"type_variety": "std_medium_gain",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 0,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span1",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa1",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span2",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa2",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test_fixed_gain",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span3",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa3",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span4",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa4",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test_fixed_gain",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span5",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa5",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "roadm Site C",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Site A",
|
||||
"region": "RLD",
|
||||
"latitude": 0.0,
|
||||
"longitude": 0.0
|
||||
}
|
||||
},
|
||||
"type": "Roadm"
|
||||
},
|
||||
{
|
||||
"uid": "booster C",
|
||||
"type": "Edfa",
|
||||
"type_variety": "std_medium_gain",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 0,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span6",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa6",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test_fixed_gain",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span7",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa7",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span8",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa8",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test_fixed_gain",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span9",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa9",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span10",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa10",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test_fixed_gain",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "roadm Site D",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Site A",
|
||||
"region": "RLD",
|
||||
"latitude": 0.0,
|
||||
"longitude": 0.0
|
||||
}
|
||||
},
|
||||
"type": "Roadm"
|
||||
},
|
||||
{
|
||||
"uid": "booster D",
|
||||
"type": "Edfa",
|
||||
"type_variety": "std_medium_gain",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 0,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span11",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa11",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span12",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa12",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test_fixed_gain",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "roadm Site E",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Site A",
|
||||
"region": "RLD",
|
||||
"latitude": 0.0,
|
||||
"longitude": 0.0
|
||||
}
|
||||
},
|
||||
"type": "Roadm"
|
||||
},
|
||||
{
|
||||
"uid": "booster E",
|
||||
"type": "Edfa",
|
||||
"type_variety": "std_medium_gain",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 0,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span13",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa13",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span14",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa14",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test_fixed_gain",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Span15",
|
||||
"type": "Fiber",
|
||||
"type_variety": "SSMF",
|
||||
"params": {
|
||||
"length": 80,
|
||||
"loss_coef": 0.2,
|
||||
"length_units": "km"
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 1,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "Edfa15",
|
||||
"type": "Edfa",
|
||||
"type_variety": "test",
|
||||
"operational": {
|
||||
"gain_target": 16,
|
||||
"tilt_target": 0
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"region": "",
|
||||
"latitude": 2,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uid": "roadm Site B",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Site B",
|
||||
"region": "RLD",
|
||||
"latitude": 0.0,
|
||||
"longitude": 0.0
|
||||
}
|
||||
},
|
||||
"type": "Roadm"
|
||||
},
|
||||
{
|
||||
"uid": "Site_B",
|
||||
"type": "Transceiver",
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Site B",
|
||||
"region": "",
|
||||
"latitude": 3,
|
||||
"longitude": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
],
|
||||
"connections": [{
|
||||
"from_node": "Site_A",
|
||||
"to_node": "roadm Site A"
|
||||
},
|
||||
{
|
||||
"from_node": "roadm Site A",
|
||||
"to_node": "booster A"
|
||||
},
|
||||
{
|
||||
"from_node": "booster A",
|
||||
"to_node": "Span1"
|
||||
},
|
||||
{
|
||||
"from_node": "Span1",
|
||||
"to_node": "Edfa1"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa1",
|
||||
"to_node": "Span2"
|
||||
},
|
||||
{
|
||||
"from_node": "Span2",
|
||||
"to_node": "Edfa2"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa2",
|
||||
"to_node": "Span3"
|
||||
},
|
||||
{
|
||||
"from_node": "Span3",
|
||||
"to_node": "Edfa3"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa3",
|
||||
"to_node": "Span4"
|
||||
},
|
||||
{
|
||||
"from_node": "Span4",
|
||||
"to_node": "Edfa4"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa4",
|
||||
"to_node": "Span5"
|
||||
},
|
||||
{
|
||||
"from_node": "Span5",
|
||||
"to_node": "Edfa5"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa5",
|
||||
"to_node": "roadm Site C"
|
||||
},
|
||||
{
|
||||
"from_node": "roadm Site C",
|
||||
"to_node": "booster C"
|
||||
},
|
||||
{
|
||||
"from_node": "booster C",
|
||||
"to_node": "Span6"
|
||||
},
|
||||
{
|
||||
"from_node": "Span6",
|
||||
"to_node": "Edfa6"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa6",
|
||||
"to_node": "Span7"
|
||||
},
|
||||
{
|
||||
"from_node": "Span7",
|
||||
"to_node": "Edfa7"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa7",
|
||||
"to_node": "Span8"
|
||||
},
|
||||
{
|
||||
"from_node": "Span8",
|
||||
"to_node": "Edfa8"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa8",
|
||||
"to_node": "Span9"
|
||||
},
|
||||
{
|
||||
"from_node": "Span9",
|
||||
"to_node": "Edfa9"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa9",
|
||||
"to_node": "Span10"
|
||||
},
|
||||
{
|
||||
"from_node": "Span10",
|
||||
"to_node": "Edfa10"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa10",
|
||||
"to_node": "roadm Site D"
|
||||
},
|
||||
{
|
||||
"from_node": "roadm Site D",
|
||||
"to_node": "booster D"
|
||||
},
|
||||
{
|
||||
"from_node": "booster D",
|
||||
"to_node": "Span11"
|
||||
},
|
||||
{
|
||||
"from_node": "Span11",
|
||||
"to_node": "Edfa11"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa11",
|
||||
"to_node": "Span12"
|
||||
},
|
||||
{
|
||||
"from_node": "Span12",
|
||||
"to_node": "Edfa12"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa12",
|
||||
"to_node": "roadm Site E"
|
||||
},
|
||||
{
|
||||
"from_node": "roadm Site E",
|
||||
"to_node": "booster E"
|
||||
},
|
||||
{
|
||||
"from_node": "booster E",
|
||||
"to_node": "Span13"
|
||||
},
|
||||
{
|
||||
"from_node": "Span13",
|
||||
"to_node": "Edfa13"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa13",
|
||||
"to_node": "Span14"
|
||||
},
|
||||
{
|
||||
"from_node": "Span14",
|
||||
"to_node": "Edfa14"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa14",
|
||||
"to_node": "Span15"
|
||||
},
|
||||
{
|
||||
"from_node": "Span15",
|
||||
"to_node": "Edfa15"
|
||||
},
|
||||
{
|
||||
"from_node": "Edfa15",
|
||||
"to_node": "roadm Site B"
|
||||
},
|
||||
{
|
||||
"from_node": "roadm Site B",
|
||||
"to_node": "Site_B"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -16,8 +16,9 @@ Transceiver trx_Stockholm
|
||||
PMD (ps): 0.00
|
||||
PDL (dB): 0.00
|
||||
Roadm roadm_Stockholm
|
||||
effective loss (dB): 22.00
|
||||
pch out (dBm): -20.00
|
||||
effective loss (dB): 22.00
|
||||
reference pch out (dBm): -20.00
|
||||
actual pch out (dBm): -20.00
|
||||
Edfa Edfa_booster_roadm_Stockholm_to_fiber (Stockholm → Norrköping)_(1/2)
|
||||
type_variety: openroadm_mw_mw_booster
|
||||
effective gain(dB): 22.00
|
||||
@@ -30,6 +31,7 @@ Edfa Edfa_booster_roadm_Stockholm_to_fiber (Stockholm → Norrköping)_(1/2)
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 2.00
|
||||
effective pch (dBm): 2.00
|
||||
actual pch out (dBm): 2.00
|
||||
output VOA (dB): 0.00
|
||||
Fiber fiber (Stockholm → Norrköping)_(1/2)
|
||||
type_variety: SSMF
|
||||
@@ -38,7 +40,8 @@ Fiber fiber (Stockholm → Norrköping)_(1/2)
|
||||
total loss (dB): 16.33
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
pch out (dBm): -14.33
|
||||
reference pch out (dBm): -14.33
|
||||
actual pch out (dBm): -14.31
|
||||
Edfa Edfa_fiber (Stockholm → Norrköping)_(1/2)
|
||||
type_variety: openroadm_ila_low_noise
|
||||
effective gain(dB): 16.33
|
||||
@@ -51,6 +54,7 @@ Edfa Edfa_fiber (Stockholm → Norrköping)_(1/2)
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 2.00
|
||||
effective pch (dBm): 2.00
|
||||
actual pch out (dBm): 2.02
|
||||
output VOA (dB): 0.00
|
||||
Fiber fiber (Stockholm → Norrköping)_(2/2)
|
||||
type_variety: SSMF
|
||||
@@ -59,7 +63,8 @@ Fiber fiber (Stockholm → Norrköping)_(2/2)
|
||||
total loss (dB): 16.33
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
pch out (dBm): -14.33
|
||||
reference pch out (dBm): -14.33
|
||||
actual pch out (dBm): -14.30
|
||||
Edfa Edfa_preamp_roadm_Norrköping_from_fiber (Stockholm → Norrköping)_(2/2)
|
||||
type_variety: openroadm_mw_mw_preamp
|
||||
effective gain(dB): 16.33
|
||||
@@ -72,10 +77,12 @@ Edfa Edfa_preamp_roadm_Norrköping_from_fiber (Stockholm → Norrköping)_(2/2)
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 2.00
|
||||
effective pch (dBm): 2.00
|
||||
actual pch out (dBm): 2.04
|
||||
output VOA (dB): 0.00
|
||||
Roadm roadm_Norrköping
|
||||
effective loss (dB): 22.00
|
||||
pch out (dBm): -20.00
|
||||
effective loss (dB): 22.00
|
||||
reference pch out (dBm): -20.00
|
||||
actual pch out (dBm): -20.00
|
||||
Edfa Edfa_booster_roadm_Norrköping_to_fiber (Norrköping → Linköping)
|
||||
type_variety: openroadm_mw_mw_booster
|
||||
effective gain(dB): 22.00
|
||||
@@ -88,6 +95,7 @@ Edfa Edfa_booster_roadm_Norrköping_to_fiber (Norrköping → Linköping)
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 2.00
|
||||
effective pch (dBm): 2.00
|
||||
actual pch out (dBm): 2.00
|
||||
output VOA (dB): 0.00
|
||||
Fiber fiber (Norrköping → Linköping)
|
||||
type_variety: SSMF
|
||||
@@ -96,7 +104,8 @@ Fiber fiber (Norrköping → Linköping)
|
||||
total loss (dB): 11.00
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
pch out (dBm): -9.00
|
||||
reference pch out (dBm): -9.00
|
||||
actual pch out (dBm): -9.00
|
||||
Edfa Edfa_preamp_roadm_Linköping_from_fiber (Norrköping → Linköping)
|
||||
type_variety: openroadm_mw_mw_preamp
|
||||
effective gain(dB): 11.00
|
||||
@@ -109,10 +118,12 @@ Edfa Edfa_preamp_roadm_Linköping_from_fiber (Norrköping → Linköping)
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 2.00
|
||||
effective pch (dBm): 2.00
|
||||
actual pch out (dBm): 2.01
|
||||
output VOA (dB): 0.00
|
||||
Roadm roadm_Linköping
|
||||
effective loss (dB): 22.00
|
||||
pch out (dBm): -20.00
|
||||
effective loss (dB): 22.00
|
||||
reference pch out (dBm): -20.00
|
||||
actual pch out (dBm): -20.00
|
||||
Edfa Edfa_booster_roadm_Linköping_to_fiber (Linköping → Jönköping)
|
||||
type_variety: openroadm_mw_mw_booster
|
||||
effective gain(dB): 22.00
|
||||
@@ -125,6 +136,7 @@ Edfa Edfa_booster_roadm_Linköping_to_fiber (Linköping → Jönköping)
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 2.00
|
||||
effective pch (dBm): 2.00
|
||||
actual pch out (dBm): 2.00
|
||||
output VOA (dB): 0.00
|
||||
Fiber fiber (Linköping → Jönköping)
|
||||
type_variety: SSMF
|
||||
@@ -133,7 +145,8 @@ Fiber fiber (Linköping → Jönköping)
|
||||
total loss (dB): 26.80
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
pch out (dBm): -24.80
|
||||
reference pch out (dBm): -24.80
|
||||
actual pch out (dBm): -24.79
|
||||
Edfa Edfa_preamp_roadm_Jönköping_from_fiber (Linköping → Jönköping)
|
||||
type_variety: openroadm_mw_mw_preamp
|
||||
effective gain(dB): 26.80
|
||||
@@ -146,10 +159,12 @@ Edfa Edfa_preamp_roadm_Jönköping_from_fiber (Linköping → Jönköping)
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 2.00
|
||||
effective pch (dBm): 2.00
|
||||
actual pch out (dBm): 2.04
|
||||
output VOA (dB): 0.00
|
||||
Roadm roadm_Jönköping
|
||||
effective loss (dB): 22.00
|
||||
pch out (dBm): -20.00
|
||||
effective loss (dB): 22.00
|
||||
reference pch out (dBm): -20.00
|
||||
actual pch out (dBm): -20.00
|
||||
Edfa Edfa_booster_roadm_Jönköping_to_fiber (Jönköping → Borås)
|
||||
type_variety: openroadm_mw_mw_booster
|
||||
effective gain(dB): 22.00
|
||||
@@ -162,6 +177,7 @@ Edfa Edfa_booster_roadm_Jönköping_to_fiber (Jönköping → Borås)
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 2.00
|
||||
effective pch (dBm): 2.00
|
||||
actual pch out (dBm): 2.00
|
||||
output VOA (dB): 0.00
|
||||
Fiber fiber (Jönköping → Borås)
|
||||
type_variety: SSMF
|
||||
@@ -170,7 +186,8 @@ Fiber fiber (Jönköping → Borås)
|
||||
total loss (dB): 17.82
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
pch out (dBm): -15.82
|
||||
reference pch out (dBm): -15.82
|
||||
actual pch out (dBm): -15.81
|
||||
Edfa Edfa_preamp_roadm_Borås_from_fiber (Jönköping → Borås)
|
||||
type_variety: openroadm_mw_mw_preamp
|
||||
effective gain(dB): 17.82
|
||||
@@ -183,10 +200,12 @@ Edfa Edfa_preamp_roadm_Borås_from_fiber (Jönköping → Borås)
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 2.00
|
||||
effective pch (dBm): 2.00
|
||||
actual pch out (dBm): 2.02
|
||||
output VOA (dB): 0.00
|
||||
Roadm roadm_Borås
|
||||
effective loss (dB): 22.00
|
||||
pch out (dBm): -20.00
|
||||
effective loss (dB): 22.00
|
||||
reference pch out (dBm): -20.00
|
||||
actual pch out (dBm): -20.00
|
||||
Edfa Edfa_booster_roadm_Borås_to_fiber (Borås → Gothenburg)
|
||||
type_variety: openroadm_mw_mw_booster
|
||||
effective gain(dB): 22.00
|
||||
@@ -199,6 +218,7 @@ Edfa Edfa_booster_roadm_Borås_to_fiber (Borås → Gothenburg)
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 2.00
|
||||
effective pch (dBm): 2.00
|
||||
actual pch out (dBm): 2.00
|
||||
output VOA (dB): 0.00
|
||||
Fiber fiber (Borås → Gothenburg)
|
||||
type_variety: SSMF
|
||||
@@ -207,7 +227,8 @@ Fiber fiber (Borås → Gothenburg)
|
||||
total loss (dB): 13.53
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
pch out (dBm): -11.53
|
||||
reference pch out (dBm): -11.53
|
||||
actual pch out (dBm): -11.52
|
||||
Edfa Edfa_preamp_roadm_Gothenburg_from_fiber (Borås → Gothenburg)
|
||||
type_variety: openroadm_mw_mw_preamp
|
||||
effective gain(dB): 13.53
|
||||
@@ -220,10 +241,12 @@ Edfa Edfa_preamp_roadm_Gothenburg_from_fiber (Borås → Gothenburg)
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 2.00
|
||||
effective pch (dBm): 2.00
|
||||
actual pch out (dBm): 2.02
|
||||
output VOA (dB): 0.00
|
||||
Roadm roadm_Gothenburg
|
||||
effective loss (dB): 22.00
|
||||
pch out (dBm): -20.00
|
||||
effective loss (dB): 22.00
|
||||
reference pch out (dBm): -20.00
|
||||
actual pch out (dBm): -20.00
|
||||
Transceiver trx_Gothenburg
|
||||
GSNR (0.1nm, dB): 18.90
|
||||
GSNR (signal bw, dB): 14.88
|
||||
|
||||
@@ -16,8 +16,9 @@ Transceiver trx_Stockholm
|
||||
PMD (ps): 0.00
|
||||
PDL (dB): 0.00
|
||||
Roadm roadm_Stockholm
|
||||
effective loss (dB): 22.00
|
||||
pch out (dBm): -20.00
|
||||
effective loss (dB): 22.00
|
||||
reference pch out (dBm): -20.00
|
||||
actual pch out (dBm): -20.00
|
||||
Edfa Edfa_booster_roadm_Stockholm_to_fiber (Stockholm → Norrköping)_(1/2)
|
||||
type_variety: openroadm_mw_mw_booster
|
||||
effective gain(dB): 22.00
|
||||
@@ -30,6 +31,7 @@ Edfa Edfa_booster_roadm_Stockholm_to_fiber (Stockholm → Norrköping)_(1/2)
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 2.00
|
||||
effective pch (dBm): 2.00
|
||||
actual pch out (dBm): 2.00
|
||||
output VOA (dB): 0.00
|
||||
Fiber fiber (Stockholm → Norrköping)_(1/2)
|
||||
type_variety: SSMF
|
||||
@@ -38,7 +40,8 @@ Fiber fiber (Stockholm → Norrköping)_(1/2)
|
||||
total loss (dB): 16.33
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
pch out (dBm): -14.33
|
||||
reference pch out (dBm): -14.33
|
||||
actual pch out (dBm): -14.31
|
||||
Edfa Edfa_fiber (Stockholm → Norrköping)_(1/2)
|
||||
type_variety: openroadm_ila_low_noise
|
||||
effective gain(dB): 16.33
|
||||
@@ -51,6 +54,7 @@ Edfa Edfa_fiber (Stockholm → Norrköping)_(1/2)
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 2.00
|
||||
effective pch (dBm): 2.00
|
||||
actual pch out (dBm): 2.02
|
||||
output VOA (dB): 0.00
|
||||
Fiber fiber (Stockholm → Norrköping)_(2/2)
|
||||
type_variety: SSMF
|
||||
@@ -59,7 +63,8 @@ Fiber fiber (Stockholm → Norrköping)_(2/2)
|
||||
total loss (dB): 16.33
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
pch out (dBm): -14.33
|
||||
reference pch out (dBm): -14.33
|
||||
actual pch out (dBm): -14.30
|
||||
Edfa Edfa_preamp_roadm_Norrköping_from_fiber (Stockholm → Norrköping)_(2/2)
|
||||
type_variety: openroadm_mw_mw_preamp_worstcase_ver5
|
||||
effective gain(dB): 16.33
|
||||
@@ -72,10 +77,12 @@ Edfa Edfa_preamp_roadm_Norrköping_from_fiber (Stockholm → Norrköping)_(2/2)
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 2.00
|
||||
effective pch (dBm): 2.00
|
||||
actual pch out (dBm): 2.04
|
||||
output VOA (dB): 0.00
|
||||
Roadm roadm_Norrköping
|
||||
effective loss (dB): 22.00
|
||||
pch out (dBm): -20.00
|
||||
effective loss (dB): 22.00
|
||||
reference pch out (dBm): -20.00
|
||||
actual pch out (dBm): -20.00
|
||||
Edfa Edfa_booster_roadm_Norrköping_to_fiber (Norrköping → Linköping)
|
||||
type_variety: openroadm_mw_mw_booster
|
||||
effective gain(dB): 22.00
|
||||
@@ -88,6 +95,7 @@ Edfa Edfa_booster_roadm_Norrköping_to_fiber (Norrköping → Linköping)
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 2.00
|
||||
effective pch (dBm): 2.00
|
||||
actual pch out (dBm): 2.00
|
||||
output VOA (dB): 0.00
|
||||
Fiber fiber (Norrköping → Linköping)
|
||||
type_variety: SSMF
|
||||
@@ -96,7 +104,8 @@ Fiber fiber (Norrköping → Linköping)
|
||||
total loss (dB): 11.00
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
pch out (dBm): -9.00
|
||||
reference pch out (dBm): -9.00
|
||||
actual pch out (dBm): -9.00
|
||||
Edfa Edfa_preamp_roadm_Linköping_from_fiber (Norrköping → Linköping)
|
||||
type_variety: openroadm_mw_mw_preamp_worstcase_ver5
|
||||
effective gain(dB): 11.00
|
||||
@@ -109,10 +118,12 @@ Edfa Edfa_preamp_roadm_Linköping_from_fiber (Norrköping → Linköping)
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 2.00
|
||||
effective pch (dBm): 2.00
|
||||
actual pch out (dBm): 2.01
|
||||
output VOA (dB): 0.00
|
||||
Roadm roadm_Linköping
|
||||
effective loss (dB): 22.00
|
||||
pch out (dBm): -20.00
|
||||
effective loss (dB): 22.00
|
||||
reference pch out (dBm): -20.00
|
||||
actual pch out (dBm): -20.00
|
||||
Edfa Edfa_booster_roadm_Linköping_to_fiber (Linköping → Jönköping)
|
||||
type_variety: openroadm_mw_mw_booster
|
||||
effective gain(dB): 22.00
|
||||
@@ -125,6 +136,7 @@ Edfa Edfa_booster_roadm_Linköping_to_fiber (Linköping → Jönköping)
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 2.00
|
||||
effective pch (dBm): 2.00
|
||||
actual pch out (dBm): 2.00
|
||||
output VOA (dB): 0.00
|
||||
Fiber fiber (Linköping → Jönköping)
|
||||
type_variety: SSMF
|
||||
@@ -133,7 +145,8 @@ Fiber fiber (Linköping → Jönköping)
|
||||
total loss (dB): 26.80
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
pch out (dBm): -24.80
|
||||
reference pch out (dBm): -24.80
|
||||
actual pch out (dBm): -24.79
|
||||
Edfa Edfa_preamp_roadm_Jönköping_from_fiber (Linköping → Jönköping)
|
||||
type_variety: openroadm_mw_mw_preamp_worstcase_ver5
|
||||
effective gain(dB): 26.80
|
||||
@@ -146,10 +159,12 @@ Edfa Edfa_preamp_roadm_Jönköping_from_fiber (Linköping → Jönköping)
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 2.00
|
||||
effective pch (dBm): 2.00
|
||||
actual pch out (dBm): 2.04
|
||||
output VOA (dB): 0.00
|
||||
Roadm roadm_Jönköping
|
||||
effective loss (dB): 22.00
|
||||
pch out (dBm): -20.00
|
||||
effective loss (dB): 22.00
|
||||
reference pch out (dBm): -20.00
|
||||
actual pch out (dBm): -20.00
|
||||
Edfa Edfa_booster_roadm_Jönköping_to_fiber (Jönköping → Borås)
|
||||
type_variety: openroadm_mw_mw_booster
|
||||
effective gain(dB): 22.00
|
||||
@@ -162,6 +177,7 @@ Edfa Edfa_booster_roadm_Jönköping_to_fiber (Jönköping → Borås)
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 2.00
|
||||
effective pch (dBm): 2.00
|
||||
actual pch out (dBm): 2.00
|
||||
output VOA (dB): 0.00
|
||||
Fiber fiber (Jönköping → Borås)
|
||||
type_variety: SSMF
|
||||
@@ -170,7 +186,8 @@ Fiber fiber (Jönköping → Borås)
|
||||
total loss (dB): 17.82
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
pch out (dBm): -15.82
|
||||
reference pch out (dBm): -15.82
|
||||
actual pch out (dBm): -15.81
|
||||
Edfa Edfa_preamp_roadm_Borås_from_fiber (Jönköping → Borås)
|
||||
type_variety: openroadm_mw_mw_preamp_worstcase_ver5
|
||||
effective gain(dB): 17.82
|
||||
@@ -183,10 +200,12 @@ Edfa Edfa_preamp_roadm_Borås_from_fiber (Jönköping → Borås)
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 2.00
|
||||
effective pch (dBm): 2.00
|
||||
actual pch out (dBm): 2.01
|
||||
output VOA (dB): 0.00
|
||||
Roadm roadm_Borås
|
||||
effective loss (dB): 22.00
|
||||
pch out (dBm): -20.00
|
||||
effective loss (dB): 22.00
|
||||
reference pch out (dBm): -20.00
|
||||
actual pch out (dBm): -20.00
|
||||
Edfa Edfa_booster_roadm_Borås_to_fiber (Borås → Gothenburg)
|
||||
type_variety: openroadm_mw_mw_booster
|
||||
effective gain(dB): 22.00
|
||||
@@ -199,6 +218,7 @@ Edfa Edfa_booster_roadm_Borås_to_fiber (Borås → Gothenburg)
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 2.00
|
||||
effective pch (dBm): 2.00
|
||||
actual pch out (dBm): 2.00
|
||||
output VOA (dB): 0.00
|
||||
Fiber fiber (Borås → Gothenburg)
|
||||
type_variety: SSMF
|
||||
@@ -207,7 +227,8 @@ Fiber fiber (Borås → Gothenburg)
|
||||
total loss (dB): 13.53
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
pch out (dBm): -11.53
|
||||
reference pch out (dBm): -11.53
|
||||
actual pch out (dBm): -11.52
|
||||
Edfa Edfa_preamp_roadm_Gothenburg_from_fiber (Borås → Gothenburg)
|
||||
type_variety: openroadm_mw_mw_preamp_worstcase_ver5
|
||||
effective gain(dB): 13.53
|
||||
@@ -220,10 +241,12 @@ Edfa Edfa_preamp_roadm_Gothenburg_from_fiber (Borås → Gothenburg)
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 2.00
|
||||
effective pch (dBm): 2.00
|
||||
actual pch out (dBm): 2.02
|
||||
output VOA (dB): 0.00
|
||||
Roadm roadm_Gothenburg
|
||||
effective loss (dB): 22.00
|
||||
pch out (dBm): -20.00
|
||||
effective loss (dB): 22.00
|
||||
reference pch out (dBm): -20.00
|
||||
actual pch out (dBm): -20.00
|
||||
Transceiver trx_Gothenburg
|
||||
GSNR (0.1nm, dB): 19.27
|
||||
GSNR (signal bw, dB): 15.24
|
||||
|
||||
100
tests/invocation/spectrum1_transmission_main_example
Normal file
100
tests/invocation/spectrum1_transmission_main_example
Normal file
@@ -0,0 +1,100 @@
|
||||
User input for spectrum used for propagation instead of SI
|
||||
There are 76 channels propagating
|
||||
Power mode is set to True
|
||||
=> it can be modified in eqpt_config.json - Span
|
||||
|
||||
There are 3 fiber spans over 130 km between trx Lannion_CAS and trx Lorient_KMA
|
||||
|
||||
Now propagating between trx Lannion_CAS and trx Lorient_KMA:
|
||||
|
||||
Propagating with input power = [1;36;40m0.00 dBm[0m:
|
||||
Transceiver trx Lannion_CAS
|
||||
GSNR (0.1nm, dB): 40.00
|
||||
GSNR (signal bw, dB): 35.92
|
||||
OSNR ASE (0.1nm, dB): 40.00
|
||||
OSNR ASE (signal bw, dB): 35.92
|
||||
CD (ps/nm): 0.00
|
||||
PMD (ps): 0.00
|
||||
PDL (dB): 0.00
|
||||
Roadm roadm Lannion_CAS
|
||||
effective loss (dB): 20.00
|
||||
reference pch out (dBm): -20.00
|
||||
actual pch out (dBm): -20.00
|
||||
Edfa east edfa in Lannion_CAS to Corlay
|
||||
type_variety: std_medium_gain
|
||||
effective gain(dB): 21.00
|
||||
(before att_in and before output VOA)
|
||||
noise figure (dB): 6.36
|
||||
(including att_in)
|
||||
pad att_in (dB): 0.00
|
||||
Power In (dBm): -1.19
|
||||
Power Out (dBm): 19.82
|
||||
Delta_P (dB): 1.00
|
||||
target pch (dBm): 1.00
|
||||
effective pch (dBm): 1.00
|
||||
actual pch out (dBm): 1.01
|
||||
output VOA (dB): 0.00
|
||||
Fiber fiber (Lannion_CAS → Corlay)-F061
|
||||
type_variety: SSMF
|
||||
length (km): 20.00
|
||||
pad att_in (dB): 0.00
|
||||
total loss (dB): 4.00
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
reference pch out (dBm): -3.00
|
||||
actual pch out (dBm): -2.99
|
||||
Fused west fused spans in Corlay
|
||||
loss (dB): 1.00
|
||||
Fiber fiber (Corlay → Loudeac)-F010
|
||||
type_variety: SSMF
|
||||
length (km): 50.00
|
||||
pad att_in (dB): 0.00
|
||||
total loss (dB): 10.00
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
reference pch out (dBm): -14.00
|
||||
actual pch out (dBm): -13.99
|
||||
Fused west fused spans in Loudeac
|
||||
loss (dB): 1.00
|
||||
Fiber fiber (Loudeac → Lorient_KMA)-F054
|
||||
type_variety: SSMF
|
||||
length (km): 60.00
|
||||
pad att_in (dB): 0.00
|
||||
total loss (dB): 12.00
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
reference pch out (dBm): -27.00
|
||||
actual pch out (dBm): -26.99
|
||||
Edfa west edfa in Lorient_KMA to Loudeac
|
||||
type_variety: std_high_gain
|
||||
effective gain(dB): 28.00
|
||||
(before att_in and before output VOA)
|
||||
noise figure (dB): 5.92
|
||||
(including att_in)
|
||||
pad att_in (dB): 0.00
|
||||
Power In (dBm): -8.18
|
||||
Power Out (dBm): 19.85
|
||||
Delta_P (dB): 1.00
|
||||
target pch (dBm): 1.00
|
||||
effective pch (dBm): 1.00
|
||||
actual pch out (dBm): 1.05
|
||||
output VOA (dB): 0.00
|
||||
Roadm roadm Lorient_KMA
|
||||
effective loss (dB): 21.00
|
||||
reference pch out (dBm): -20.00
|
||||
actual pch out (dBm): -20.00
|
||||
Transceiver trx Lorient_KMA
|
||||
GSNR (0.1nm, dB): 23.61
|
||||
GSNR (signal bw, dB): 19.52
|
||||
OSNR ASE (0.1nm, dB): 23.89
|
||||
OSNR ASE (signal bw, dB): 19.81
|
||||
CD (ps/nm): 2171.00
|
||||
PMD (ps): 0.46
|
||||
PDL (dB): 0.00
|
||||
|
||||
Transmission result for input power = 0.00 dBm:
|
||||
Final GSNR (0.1 nm): [1;36;40m23.61 dB[0m
|
||||
|
||||
(No source node specified: picked trx Lannion_CAS)
|
||||
|
||||
(No destination node specified: picked trx Lorient_KMA)
|
||||
163
tests/invocation/spectrum2_transmission_main_example
Normal file
163
tests/invocation/spectrum2_transmission_main_example
Normal file
@@ -0,0 +1,163 @@
|
||||
User input for spectrum used for propagation instead of SI
|
||||
There are 60 channels propagating
|
||||
Power mode is set to True
|
||||
=> it can be modified in eqpt_config.json - Span
|
||||
|
||||
There are 3 fiber spans over 130 km between trx Lannion_CAS and trx Lorient_KMA
|
||||
|
||||
Now propagating between trx Lannion_CAS and trx Lorient_KMA:
|
||||
|
||||
Propagating with input power = [1;36;40m0.00 dBm[0m:
|
||||
Transceiver trx Lannion_CAS
|
||||
GSNR (0.1nm, dB): mode_1: 40.00, mode_2: 40.00
|
||||
GSNR (signal bw, dB): mode_1: 35.92, mode_2: 32.91
|
||||
OSNR ASE (0.1nm, dB): mode_1: 40.00, mode_2: 40.00
|
||||
OSNR ASE (signal bw, dB): mode_1: 35.92, mode_2: 32.91
|
||||
CD (ps/nm): 0.00
|
||||
PMD (ps): 0.00
|
||||
PDL (dB): 0.00
|
||||
Roadm roadm Lannion_CAS
|
||||
effective loss (dB): 20.00
|
||||
reference pch out (dBm): -20.00
|
||||
actual pch out (dBm): mode_1: -20.00, mode_2: -20.00
|
||||
Edfa east edfa in Lannion_CAS to Corlay
|
||||
type_variety: std_medium_gain
|
||||
effective gain(dB): 21.00
|
||||
(before att_in and before output VOA)
|
||||
noise figure (dB): 6.36
|
||||
(including att_in)
|
||||
pad att_in (dB): 0.00
|
||||
Power In (dBm): -2.22
|
||||
Power Out (dBm): 18.79
|
||||
Delta_P (dB): 1.00
|
||||
target pch (dBm): 1.00
|
||||
effective pch (dBm): 1.00
|
||||
actual pch out (dBm): mode_1: 1.01, mode_2: 1.02
|
||||
output VOA (dB): 0.00
|
||||
Fiber fiber (Lannion_CAS → Corlay)-F061
|
||||
type_variety: SSMF
|
||||
length (km): 20.00
|
||||
pad att_in (dB): 0.00
|
||||
total loss (dB): 4.00
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
reference pch out (dBm): -3.00
|
||||
actual pch out (dBm): mode_1: -2.99, mode_2: -2.98
|
||||
Fused west fused spans in Corlay
|
||||
loss (dB): 1.00
|
||||
Fiber fiber (Corlay → Loudeac)-F010
|
||||
type_variety: SSMF
|
||||
length (km): 50.00
|
||||
pad att_in (dB): 0.00
|
||||
total loss (dB): 10.00
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
reference pch out (dBm): -14.00
|
||||
actual pch out (dBm): mode_1: -13.99, mode_2: -13.98
|
||||
Fused west fused spans in Loudeac
|
||||
loss (dB): 1.00
|
||||
Fiber fiber (Loudeac → Lorient_KMA)-F054
|
||||
type_variety: SSMF
|
||||
length (km): 60.00
|
||||
pad att_in (dB): 0.00
|
||||
total loss (dB): 12.00
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
reference pch out (dBm): -27.00
|
||||
actual pch out (dBm): mode_1: -26.99, mode_2: -26.98
|
||||
Edfa west edfa in Lorient_KMA to Loudeac
|
||||
type_variety: std_high_gain
|
||||
effective gain(dB): 28.00
|
||||
(before att_in and before output VOA)
|
||||
noise figure (dB): 5.92
|
||||
(including att_in)
|
||||
pad att_in (dB): 0.00
|
||||
Power In (dBm): -9.21
|
||||
Power Out (dBm): 18.84
|
||||
Delta_P (dB): 1.00
|
||||
target pch (dBm): 1.00
|
||||
effective pch (dBm): 1.00
|
||||
actual pch out (dBm): mode_1: 1.04, mode_2: 1.09
|
||||
output VOA (dB): 0.00
|
||||
Roadm roadm Lorient_KMA
|
||||
effective loss (dB): 21.00
|
||||
reference pch out (dBm): -20.00
|
||||
actual pch out (dBm): mode_1: -20.00, mode_2: -20.00
|
||||
Transceiver trx Lorient_KMA
|
||||
GSNR (0.1nm, dB): mode_1: 23.65, mode_2: 23.81
|
||||
GSNR (signal bw, dB): mode_1: 19.57, mode_2: 16.72
|
||||
OSNR ASE (0.1nm, dB): mode_1: 23.91, mode_2: 23.87
|
||||
OSNR ASE (signal bw, dB): mode_1: 19.83, mode_2: 16.78
|
||||
CD (ps/nm): 2171.00
|
||||
PMD (ps): 0.46
|
||||
PDL (dB): 0.00
|
||||
|
||||
Transmission result for input power = 0.00 dBm:
|
||||
Final GSNR (0.1 nm): [1;36;40m23.72 dB[0m
|
||||
|
||||
The GSNR per channel at the end of the line is:
|
||||
Ch. # Channel frequency (THz) Channel power (dBm) OSNR ASE (signal bw, dB) SNR NLI (signal bw, dB) GSNR (signal bw, dB)
|
||||
1 191.40000 -20.04 19.85 33.30 19.65
|
||||
2 191.45000 -20.04 19.85 32.70 19.63
|
||||
3 191.50000 -20.04 19.84 32.45 19.61
|
||||
4 191.55000 -20.04 19.84 32.29 19.60
|
||||
5 191.60000 -20.04 19.84 32.18 19.60
|
||||
6 191.65000 -20.04 19.84 32.10 19.59
|
||||
7 191.70000 -20.04 19.84 32.03 19.59
|
||||
8 191.75000 -20.04 19.84 31.98 19.58
|
||||
9 191.80000 -20.04 19.84 31.93 19.58
|
||||
10 191.85000 -20.04 19.84 31.90 19.57
|
||||
11 191.90000 -20.04 19.84 31.86 19.57
|
||||
12 191.95000 -20.04 19.84 31.84 19.57
|
||||
13 192.00000 -20.04 19.83 31.82 19.57
|
||||
14 192.05000 -20.04 19.83 31.80 19.57
|
||||
15 192.10000 -20.04 19.83 31.78 19.56
|
||||
16 192.15000 -20.04 19.83 31.77 19.56
|
||||
17 192.20000 -20.04 19.83 31.76 19.56
|
||||
18 192.25000 -20.04 19.83 31.75 19.56
|
||||
19 192.30000 -20.04 19.83 31.75 19.56
|
||||
20 192.35000 -20.04 19.83 31.75 19.56
|
||||
21 192.40000 -20.05 19.83 31.75 19.56
|
||||
22 192.45000 -20.05 19.82 31.75 19.55
|
||||
23 192.50000 -20.05 19.82 31.76 19.55
|
||||
24 192.55000 -20.05 19.82 31.76 19.55
|
||||
25 192.60000 -20.05 19.82 31.78 19.55
|
||||
26 192.65000 -20.05 19.82 31.79 19.55
|
||||
27 192.70000 -20.05 19.82 31.81 19.55
|
||||
28 192.75000 -20.05 19.82 31.83 19.55
|
||||
29 192.80000 -20.05 19.82 31.86 19.55
|
||||
30 192.85000 -20.05 19.82 31.90 19.56
|
||||
31 192.90000 -20.04 19.82 31.95 19.56
|
||||
32 192.95000 -20.04 19.81 32.02 19.56
|
||||
33 193.00000 -20.04 19.81 32.11 19.56
|
||||
34 193.05000 -20.04 19.81 32.27 19.57
|
||||
35 193.10000 -20.04 19.81 32.61 19.59
|
||||
36 193.16250 -20.09 16.80 33.70 16.71
|
||||
37 193.23750 -20.09 16.80 34.20 16.72
|
||||
38 193.31250 -20.09 16.80 34.45 16.72
|
||||
39 193.38750 -20.09 16.79 34.62 16.72
|
||||
40 193.46250 -20.09 16.79 34.75 16.72
|
||||
41 193.53750 -20.09 16.79 34.85 16.72
|
||||
42 193.61250 -20.09 16.79 34.94 16.72
|
||||
43 193.68750 -20.09 16.79 35.02 16.72
|
||||
44 193.76250 -20.09 16.79 35.08 16.72
|
||||
45 193.83750 -20.09 16.78 35.15 16.72
|
||||
46 193.91250 -20.09 16.78 35.20 16.72
|
||||
47 193.98750 -20.09 16.78 35.26 16.72
|
||||
48 194.06250 -20.09 16.78 35.31 16.72
|
||||
49 194.13750 -20.09 16.78 35.36 16.72
|
||||
50 194.21250 -20.09 16.78 35.41 16.72
|
||||
51 194.28750 -20.09 16.78 35.47 16.72
|
||||
52 194.36250 -20.09 16.77 35.52 16.72
|
||||
53 194.43750 -20.09 16.77 35.58 16.72
|
||||
54 194.51250 -20.09 16.77 35.65 16.71
|
||||
55 194.58750 -20.09 16.77 35.72 16.71
|
||||
56 194.66250 -20.09 16.77 35.81 16.71
|
||||
57 194.73750 -20.09 16.77 35.92 16.71
|
||||
58 194.81250 -20.09 16.76 36.06 16.71
|
||||
59 194.88750 -20.09 16.76 36.27 16.71
|
||||
60 194.96250 -20.09 16.76 36.75 16.72
|
||||
|
||||
(No source node specified: picked trx Lannion_CAS)
|
||||
|
||||
(No destination node specified: picked trx Lorient_KMA)
|
||||
@@ -22,7 +22,8 @@ Fiber Span1
|
||||
total loss (dB): 17.00
|
||||
(includes conn loss (dB) in: 0.50 out: 0.50)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
pch out (dBm): -17.00
|
||||
reference pch out (dBm): -17.00
|
||||
actual pch out (dBm): -17.00
|
||||
Edfa Edfa1
|
||||
type_variety: std_low_gain
|
||||
effective gain(dB): 15.00
|
||||
@@ -35,6 +36,7 @@ Edfa Edfa1
|
||||
Delta_P (dB): -2.00
|
||||
target pch (dBm): -2.00
|
||||
effective pch (dBm): -2.00
|
||||
actual pch out (dBm): -1.99
|
||||
output VOA (dB): 0.00
|
||||
Transceiver Site_B
|
||||
GSNR (0.1nm, dB): 31.17
|
||||
|
||||
@@ -22,7 +22,8 @@ RamanFiber Span1
|
||||
total loss (dB): 17.00
|
||||
(includes conn loss (dB) in: 0.50 out: 0.50)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
pch out (dBm): -7.77
|
||||
reference pch out (dBm): -7.77
|
||||
actual pch out (dBm): -8.03
|
||||
Fused Fused1
|
||||
loss (dB): 0.00
|
||||
Edfa Edfa1
|
||||
@@ -37,6 +38,7 @@ Edfa Edfa1
|
||||
Delta_P (dB): -2.00
|
||||
target pch (dBm): -2.00
|
||||
effective pch (dBm): -2.00
|
||||
actual pch out (dBm): -2.26
|
||||
output VOA (dB): 0.00
|
||||
Transceiver Site_B
|
||||
GSNR (0.1nm, dB): 31.44
|
||||
@@ -52,82 +54,82 @@ Transmission result for input power = 0.00 dBm:
|
||||
|
||||
The GSNR per channel at the end of the line is:
|
||||
Ch. # Channel frequency (THz) Channel power (dBm) OSNR ASE (signal bw, dB) SNR NLI (signal bw, dB) GSNR (signal bw, dB)
|
||||
1 191.35 0.21 31.62 31.43 28.52
|
||||
2 191.40 0.17 31.60 31.35 28.46
|
||||
3 191.45 0.13 31.58 31.26 28.41
|
||||
4 191.50 0.09 31.56 31.18 28.36
|
||||
5 191.55 0.03 31.53 31.10 28.30
|
||||
6 191.60 -0.02 31.50 31.02 28.24
|
||||
7 191.65 -0.08 31.46 30.94 28.19
|
||||
8 191.70 -0.14 31.43 30.87 28.13
|
||||
9 191.75 -0.20 31.40 30.79 28.08
|
||||
10 191.80 -0.27 31.37 30.72 28.02
|
||||
11 191.85 -0.33 31.33 30.65 27.97
|
||||
12 191.90 -0.40 31.29 30.58 27.91
|
||||
13 191.95 -0.46 31.26 30.51 27.86
|
||||
14 192.00 -0.53 31.22 30.44 27.80
|
||||
15 192.05 -0.59 31.18 30.37 27.75
|
||||
16 192.10 -0.66 31.15 30.30 27.69
|
||||
17 192.15 -0.73 31.11 30.24 27.64
|
||||
18 192.20 -0.80 31.07 30.17 27.59
|
||||
19 192.25 -0.86 31.03 30.18 27.57
|
||||
20 192.30 -0.94 30.99 30.19 27.56
|
||||
21 192.35 -1.02 30.94 30.20 27.54
|
||||
22 192.40 -1.09 30.90 30.20 27.53
|
||||
23 192.45 -1.17 30.86 30.21 27.51
|
||||
24 192.50 -1.24 30.81 30.22 27.50
|
||||
25 192.55 -1.31 30.77 30.23 27.48
|
||||
26 192.60 -1.38 30.73 30.23 27.46
|
||||
27 192.65 -1.45 30.69 30.24 27.45
|
||||
28 192.70 -1.52 30.65 30.25 27.43
|
||||
29 192.75 -1.59 30.60 30.26 27.42
|
||||
30 192.80 -1.67 30.56 30.27 27.40
|
||||
31 192.85 -1.74 30.52 30.27 27.38
|
||||
32 192.90 -1.81 30.47 30.28 27.37
|
||||
33 192.95 -1.88 30.43 30.29 27.35
|
||||
34 193.00 -1.95 30.39 30.30 27.33
|
||||
35 193.05 -2.02 30.34 30.30 27.31
|
||||
36 193.10 -2.08 30.30 30.31 27.30
|
||||
37 193.15 -2.15 30.26 30.32 27.28
|
||||
38 193.20 -2.22 30.21 30.34 27.26
|
||||
39 193.25 -2.29 30.17 30.36 27.25
|
||||
40 193.30 -2.36 30.13 30.37 27.24
|
||||
41 193.35 -2.43 30.08 30.39 27.22
|
||||
42 193.40 -2.50 30.04 30.41 27.21
|
||||
43 193.45 -2.56 29.99 30.43 27.19
|
||||
44 193.50 -2.63 29.95 30.44 27.18
|
||||
45 193.55 -2.70 29.90 30.46 27.16
|
||||
46 193.60 -2.78 29.85 30.48 27.15
|
||||
47 193.65 -2.85 29.80 30.50 27.13
|
||||
48 193.70 -2.92 29.76 30.52 27.11
|
||||
49 193.75 -2.99 29.71 30.54 27.09
|
||||
50 193.80 -3.06 29.66 30.55 27.07
|
||||
51 193.85 -3.14 29.61 30.57 27.06
|
||||
52 193.90 -3.21 29.56 30.59 27.04
|
||||
53 193.95 -3.28 29.52 30.61 27.02
|
||||
54 194.00 -3.35 29.47 30.63 27.00
|
||||
55 194.05 -3.42 29.42 30.65 26.98
|
||||
56 194.10 -3.50 29.37 30.67 26.96
|
||||
57 194.15 -3.57 29.32 30.72 26.95
|
||||
58 194.20 -3.64 29.26 30.78 26.95
|
||||
59 194.25 -3.72 29.21 30.84 26.94
|
||||
60 194.30 -3.79 29.16 30.90 26.94
|
||||
61 194.35 -3.86 29.11 30.96 26.93
|
||||
62 194.40 -3.93 29.06 31.02 26.92
|
||||
63 194.45 -4.01 29.01 31.09 26.91
|
||||
64 194.50 -4.08 28.96 31.15 26.91
|
||||
65 194.55 -4.14 28.91 31.21 26.90
|
||||
66 194.60 -4.21 28.86 31.28 26.90
|
||||
67 194.65 -4.27 28.82 31.34 26.89
|
||||
68 194.70 -4.34 28.77 31.41 26.88
|
||||
69 194.75 -4.41 28.72 31.48 26.88
|
||||
70 194.80 -4.47 28.67 31.55 26.87
|
||||
71 194.85 -4.54 28.63 31.62 26.86
|
||||
72 194.90 -4.60 28.58 31.69 26.85
|
||||
73 194.95 -4.67 28.53 31.76 26.84
|
||||
74 195.00 -4.73 28.48 31.84 26.83
|
||||
75 195.05 -4.80 28.43 31.91 26.82
|
||||
76 195.10 -4.86 28.38 31.91 26.79
|
||||
1 191.35000 0.21 31.62 31.43 28.52
|
||||
2 191.40000 0.17 31.60 31.35 28.46
|
||||
3 191.45000 0.13 31.58 31.26 28.41
|
||||
4 191.50000 0.09 31.56 31.18 28.36
|
||||
5 191.55000 0.03 31.53 31.10 28.30
|
||||
6 191.60000 -0.02 31.50 31.02 28.24
|
||||
7 191.65000 -0.08 31.46 30.94 28.19
|
||||
8 191.70000 -0.14 31.43 30.87 28.13
|
||||
9 191.75000 -0.20 31.40 30.79 28.08
|
||||
10 191.80000 -0.27 31.37 30.72 28.02
|
||||
11 191.85000 -0.33 31.33 30.65 27.97
|
||||
12 191.90000 -0.40 31.29 30.58 27.91
|
||||
13 191.95000 -0.46 31.26 30.51 27.86
|
||||
14 192.00000 -0.53 31.22 30.44 27.80
|
||||
15 192.05000 -0.59 31.18 30.37 27.75
|
||||
16 192.10000 -0.66 31.15 30.30 27.69
|
||||
17 192.15000 -0.73 31.11 30.24 27.64
|
||||
18 192.20000 -0.80 31.07 30.17 27.59
|
||||
19 192.25000 -0.86 31.03 30.18 27.57
|
||||
20 192.30000 -0.94 30.99 30.19 27.56
|
||||
21 192.35000 -1.02 30.94 30.20 27.54
|
||||
22 192.40000 -1.09 30.90 30.20 27.53
|
||||
23 192.45000 -1.17 30.86 30.21 27.51
|
||||
24 192.50000 -1.24 30.81 30.22 27.50
|
||||
25 192.55000 -1.31 30.77 30.23 27.48
|
||||
26 192.60000 -1.38 30.73 30.23 27.46
|
||||
27 192.65000 -1.45 30.69 30.24 27.45
|
||||
28 192.70000 -1.52 30.65 30.25 27.43
|
||||
29 192.75000 -1.59 30.60 30.26 27.42
|
||||
30 192.80000 -1.67 30.56 30.27 27.40
|
||||
31 192.85000 -1.74 30.52 30.27 27.38
|
||||
32 192.90000 -1.81 30.47 30.28 27.37
|
||||
33 192.95000 -1.88 30.43 30.29 27.35
|
||||
34 193.00000 -1.95 30.39 30.30 27.33
|
||||
35 193.05000 -2.02 30.34 30.30 27.31
|
||||
36 193.10000 -2.08 30.30 30.31 27.30
|
||||
37 193.15000 -2.15 30.26 30.32 27.28
|
||||
38 193.20000 -2.22 30.21 30.34 27.26
|
||||
39 193.25000 -2.29 30.17 30.36 27.25
|
||||
40 193.30000 -2.36 30.13 30.37 27.24
|
||||
41 193.35000 -2.43 30.08 30.39 27.22
|
||||
42 193.40000 -2.50 30.04 30.41 27.21
|
||||
43 193.45000 -2.56 29.99 30.43 27.19
|
||||
44 193.50000 -2.63 29.95 30.44 27.18
|
||||
45 193.55000 -2.70 29.90 30.46 27.16
|
||||
46 193.60000 -2.78 29.85 30.48 27.15
|
||||
47 193.65000 -2.85 29.80 30.50 27.13
|
||||
48 193.70000 -2.92 29.76 30.52 27.11
|
||||
49 193.75000 -2.99 29.71 30.54 27.09
|
||||
50 193.80000 -3.06 29.66 30.55 27.07
|
||||
51 193.85000 -3.14 29.61 30.57 27.06
|
||||
52 193.90000 -3.21 29.56 30.59 27.04
|
||||
53 193.95000 -3.28 29.52 30.61 27.02
|
||||
54 194.00000 -3.35 29.47 30.63 27.00
|
||||
55 194.05000 -3.42 29.42 30.65 26.98
|
||||
56 194.10000 -3.50 29.37 30.67 26.96
|
||||
57 194.15000 -3.57 29.32 30.72 26.95
|
||||
58 194.20000 -3.64 29.26 30.78 26.95
|
||||
59 194.25000 -3.72 29.21 30.84 26.94
|
||||
60 194.30000 -3.79 29.16 30.90 26.94
|
||||
61 194.35000 -3.86 29.11 30.96 26.93
|
||||
62 194.40000 -3.93 29.06 31.02 26.92
|
||||
63 194.45000 -4.01 29.01 31.09 26.91
|
||||
64 194.50000 -4.08 28.96 31.15 26.91
|
||||
65 194.55000 -4.14 28.91 31.21 26.90
|
||||
66 194.60000 -4.21 28.86 31.28 26.90
|
||||
67 194.65000 -4.27 28.82 31.34 26.89
|
||||
68 194.70000 -4.34 28.77 31.41 26.88
|
||||
69 194.75000 -4.41 28.72 31.48 26.88
|
||||
70 194.80000 -4.47 28.67 31.55 26.87
|
||||
71 194.85000 -4.54 28.63 31.62 26.86
|
||||
72 194.90000 -4.60 28.58 31.69 26.85
|
||||
73 194.95000 -4.67 28.53 31.76 26.84
|
||||
74 195.00000 -4.73 28.48 31.84 26.83
|
||||
75 195.05000 -4.80 28.43 31.91 26.82
|
||||
76 195.10000 -4.86 28.38 31.91 26.79
|
||||
|
||||
(No source node specified: picked Site_A)
|
||||
|
||||
|
||||
453
tests/invocation/transmission_main_example_long
Normal file
453
tests/invocation/transmission_main_example_long
Normal file
@@ -0,0 +1,453 @@
|
||||
There are 96 channels propagating
|
||||
Power mode is set to True
|
||||
=> it can be modified in eqpt_config.json - Span
|
||||
|
||||
There are 15 fiber spans over 1200 km between Site_A and Site_B
|
||||
|
||||
Now propagating between Site_A and Site_B:
|
||||
|
||||
Propagating with input power = [1;36;40m0.00 dBm[0m:
|
||||
Transceiver Site_A
|
||||
GSNR (0.1nm, dB): 100.00
|
||||
GSNR (signal bw, dB): 95.92
|
||||
OSNR ASE (0.1nm, dB): 100.00
|
||||
OSNR ASE (signal bw, dB): 95.92
|
||||
CD (ps/nm): 0.00
|
||||
PMD (ps): 0.00
|
||||
PDL (dB): 0.00
|
||||
Roadm roadm Site A
|
||||
effective loss (dB): 20.00
|
||||
reference pch out (dBm): -20.00
|
||||
actual pch out (dBm): -20.00
|
||||
Edfa booster A
|
||||
type_variety: std_medium_gain
|
||||
effective gain(dB): 20.00
|
||||
(before att_in and before output VOA)
|
||||
noise figure (dB): 6.58
|
||||
(including att_in)
|
||||
pad att_in (dB): 0.00
|
||||
Power In (dBm): -0.18
|
||||
Power Out (dBm): 19.83
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 0.00
|
||||
effective pch (dBm): 0.00
|
||||
actual pch out (dBm): 0.01
|
||||
output VOA (dB): 0.00
|
||||
Fiber Span1
|
||||
type_variety: SSMF
|
||||
length (km): 80.00
|
||||
pad att_in (dB): 0.00
|
||||
total loss (dB): 16.00
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
reference pch out (dBm): -16.00
|
||||
actual pch out (dBm): -15.99
|
||||
Edfa Edfa1
|
||||
type_variety: test
|
||||
effective gain(dB): 16.00
|
||||
(before att_in and before output VOA)
|
||||
noise figure (dB): 8.86
|
||||
(including att_in)
|
||||
pad att_in (dB): 0.00
|
||||
Power In (dBm): 3.84
|
||||
Power Out (dBm): 19.84
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 0.00
|
||||
effective pch (dBm): 0.00
|
||||
actual pch out (dBm): 0.02
|
||||
output VOA (dB): 0.00
|
||||
Fiber Span2
|
||||
type_variety: SSMF
|
||||
length (km): 80.00
|
||||
pad att_in (dB): 0.00
|
||||
total loss (dB): 16.00
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
reference pch out (dBm): -16.00
|
||||
actual pch out (dBm): -15.98
|
||||
Edfa Edfa2
|
||||
type_variety: test_fixed_gain
|
||||
effective gain(dB): 16.00
|
||||
(before att_in and before output VOA)
|
||||
noise figure (dB): 9.00
|
||||
(including att_in)
|
||||
pad att_in (dB): 4.00
|
||||
Power In (dBm): 3.84
|
||||
Power Out (dBm): 19.85
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 0.00
|
||||
effective pch (dBm): 0.00
|
||||
actual pch out (dBm): 0.03
|
||||
output VOA (dB): 0.00
|
||||
Fiber Span3
|
||||
type_variety: SSMF
|
||||
length (km): 80.00
|
||||
pad att_in (dB): 0.00
|
||||
total loss (dB): 16.00
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
reference pch out (dBm): -16.00
|
||||
actual pch out (dBm): -15.97
|
||||
Edfa Edfa3
|
||||
type_variety: test
|
||||
effective gain(dB): 16.00
|
||||
(before att_in and before output VOA)
|
||||
noise figure (dB): 8.86
|
||||
(including att_in)
|
||||
pad att_in (dB): 0.00
|
||||
Power In (dBm): 3.85
|
||||
Power Out (dBm): 19.86
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 0.00
|
||||
effective pch (dBm): 0.00
|
||||
actual pch out (dBm): 0.04
|
||||
output VOA (dB): 0.00
|
||||
Fiber Span4
|
||||
type_variety: SSMF
|
||||
length (km): 80.00
|
||||
pad att_in (dB): 0.00
|
||||
total loss (dB): 16.00
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
reference pch out (dBm): -16.00
|
||||
actual pch out (dBm): -15.96
|
||||
Edfa Edfa4
|
||||
type_variety: test_fixed_gain
|
||||
effective gain(dB): 16.00
|
||||
(before att_in and before output VOA)
|
||||
noise figure (dB): 9.00
|
||||
(including att_in)
|
||||
pad att_in (dB): 4.00
|
||||
Power In (dBm): 3.86
|
||||
Power Out (dBm): 19.87
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 0.00
|
||||
effective pch (dBm): 0.00
|
||||
actual pch out (dBm): 0.05
|
||||
output VOA (dB): 0.00
|
||||
Fiber Span5
|
||||
type_variety: SSMF
|
||||
length (km): 80.00
|
||||
pad att_in (dB): 0.00
|
||||
total loss (dB): 16.00
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
reference pch out (dBm): -16.00
|
||||
actual pch out (dBm): -15.95
|
||||
Edfa Edfa5
|
||||
type_variety: test
|
||||
effective gain(dB): 16.00
|
||||
(before att_in and before output VOA)
|
||||
noise figure (dB): 8.86
|
||||
(including att_in)
|
||||
pad att_in (dB): 0.00
|
||||
Power In (dBm): 3.87
|
||||
Power Out (dBm): 19.88
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 0.00
|
||||
effective pch (dBm): 0.00
|
||||
actual pch out (dBm): 0.06
|
||||
output VOA (dB): 0.00
|
||||
Roadm roadm Site C
|
||||
effective loss (dB): 20.00
|
||||
reference pch out (dBm): -20.00
|
||||
actual pch out (dBm): -20.00
|
||||
Edfa booster C
|
||||
type_variety: std_medium_gain
|
||||
effective gain(dB): 20.00
|
||||
(before att_in and before output VOA)
|
||||
noise figure (dB): 6.58
|
||||
(including att_in)
|
||||
pad att_in (dB): 0.00
|
||||
Power In (dBm): -0.18
|
||||
Power Out (dBm): 19.83
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 0.00
|
||||
effective pch (dBm): 0.00
|
||||
actual pch out (dBm): 0.01
|
||||
output VOA (dB): 0.00
|
||||
Fiber Span6
|
||||
type_variety: SSMF
|
||||
length (km): 80.00
|
||||
pad att_in (dB): 0.00
|
||||
total loss (dB): 16.00
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
reference pch out (dBm): -16.00
|
||||
actual pch out (dBm): -15.99
|
||||
Edfa Edfa6
|
||||
type_variety: test_fixed_gain
|
||||
effective gain(dB): 16.00
|
||||
(before att_in and before output VOA)
|
||||
noise figure (dB): 9.00
|
||||
(including att_in)
|
||||
pad att_in (dB): 4.00
|
||||
Power In (dBm): 3.83
|
||||
Power Out (dBm): 19.84
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 0.00
|
||||
effective pch (dBm): 0.00
|
||||
actual pch out (dBm): 0.02
|
||||
output VOA (dB): 0.00
|
||||
Fiber Span7
|
||||
type_variety: SSMF
|
||||
length (km): 80.00
|
||||
pad att_in (dB): 0.00
|
||||
total loss (dB): 16.00
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
reference pch out (dBm): -16.00
|
||||
actual pch out (dBm): -15.98
|
||||
Edfa Edfa7
|
||||
type_variety: test
|
||||
effective gain(dB): 16.00
|
||||
(before att_in and before output VOA)
|
||||
noise figure (dB): 8.86
|
||||
(including att_in)
|
||||
pad att_in (dB): 0.00
|
||||
Power In (dBm): 3.84
|
||||
Power Out (dBm): 19.85
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 0.00
|
||||
effective pch (dBm): 0.00
|
||||
actual pch out (dBm): 0.03
|
||||
output VOA (dB): 0.00
|
||||
Fiber Span8
|
||||
type_variety: SSMF
|
||||
length (km): 80.00
|
||||
pad att_in (dB): 0.00
|
||||
total loss (dB): 16.00
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
reference pch out (dBm): -16.00
|
||||
actual pch out (dBm): -15.97
|
||||
Edfa Edfa8
|
||||
type_variety: test_fixed_gain
|
||||
effective gain(dB): 16.00
|
||||
(before att_in and before output VOA)
|
||||
noise figure (dB): 9.00
|
||||
(including att_in)
|
||||
pad att_in (dB): 4.00
|
||||
Power In (dBm): 3.85
|
||||
Power Out (dBm): 19.86
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 0.00
|
||||
effective pch (dBm): 0.00
|
||||
actual pch out (dBm): 0.04
|
||||
output VOA (dB): 0.00
|
||||
Fiber Span9
|
||||
type_variety: SSMF
|
||||
length (km): 80.00
|
||||
pad att_in (dB): 0.00
|
||||
total loss (dB): 16.00
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
reference pch out (dBm): -16.00
|
||||
actual pch out (dBm): -15.96
|
||||
Edfa Edfa9
|
||||
type_variety: test
|
||||
effective gain(dB): 16.00
|
||||
(before att_in and before output VOA)
|
||||
noise figure (dB): 8.86
|
||||
(including att_in)
|
||||
pad att_in (dB): 0.00
|
||||
Power In (dBm): 3.86
|
||||
Power Out (dBm): 19.87
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 0.00
|
||||
effective pch (dBm): 0.00
|
||||
actual pch out (dBm): 0.05
|
||||
output VOA (dB): 0.00
|
||||
Fiber Span10
|
||||
type_variety: SSMF
|
||||
length (km): 80.00
|
||||
pad att_in (dB): 0.00
|
||||
total loss (dB): 16.00
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
reference pch out (dBm): -16.00
|
||||
actual pch out (dBm): -15.95
|
||||
Edfa Edfa10
|
||||
type_variety: test_fixed_gain
|
||||
effective gain(dB): 16.00
|
||||
(before att_in and before output VOA)
|
||||
noise figure (dB): 9.00
|
||||
(including att_in)
|
||||
pad att_in (dB): 4.00
|
||||
Power In (dBm): 3.87
|
||||
Power Out (dBm): 19.88
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 0.00
|
||||
effective pch (dBm): 0.00
|
||||
actual pch out (dBm): 0.06
|
||||
output VOA (dB): 0.00
|
||||
Roadm roadm Site D
|
||||
effective loss (dB): 20.00
|
||||
reference pch out (dBm): -20.00
|
||||
actual pch out (dBm): -20.00
|
||||
Edfa booster D
|
||||
type_variety: std_medium_gain
|
||||
effective gain(dB): 20.00
|
||||
(before att_in and before output VOA)
|
||||
noise figure (dB): 6.58
|
||||
(including att_in)
|
||||
pad att_in (dB): 0.00
|
||||
Power In (dBm): -0.18
|
||||
Power Out (dBm): 19.83
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 0.00
|
||||
effective pch (dBm): 0.00
|
||||
actual pch out (dBm): 0.01
|
||||
output VOA (dB): 0.00
|
||||
Fiber Span11
|
||||
type_variety: SSMF
|
||||
length (km): 80.00
|
||||
pad att_in (dB): 0.00
|
||||
total loss (dB): 16.00
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
reference pch out (dBm): -16.00
|
||||
actual pch out (dBm): -15.99
|
||||
Edfa Edfa11
|
||||
type_variety: test
|
||||
effective gain(dB): 16.00
|
||||
(before att_in and before output VOA)
|
||||
noise figure (dB): 8.86
|
||||
(including att_in)
|
||||
pad att_in (dB): 0.00
|
||||
Power In (dBm): 3.83
|
||||
Power Out (dBm): 19.84
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 0.00
|
||||
effective pch (dBm): 0.00
|
||||
actual pch out (dBm): 0.02
|
||||
output VOA (dB): 0.00
|
||||
Fiber Span12
|
||||
type_variety: SSMF
|
||||
length (km): 80.00
|
||||
pad att_in (dB): 0.00
|
||||
total loss (dB): 16.00
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
reference pch out (dBm): -16.00
|
||||
actual pch out (dBm): -15.98
|
||||
Edfa Edfa12
|
||||
type_variety: test_fixed_gain
|
||||
effective gain(dB): 16.00
|
||||
(before att_in and before output VOA)
|
||||
noise figure (dB): 9.00
|
||||
(including att_in)
|
||||
pad att_in (dB): 4.00
|
||||
Power In (dBm): 3.84
|
||||
Power Out (dBm): 19.85
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 0.00
|
||||
effective pch (dBm): 0.00
|
||||
actual pch out (dBm): 0.03
|
||||
output VOA (dB): 0.00
|
||||
Roadm roadm Site E
|
||||
effective loss (dB): 20.00
|
||||
reference pch out (dBm): -20.00
|
||||
actual pch out (dBm): -20.00
|
||||
Edfa booster E
|
||||
type_variety: std_medium_gain
|
||||
effective gain(dB): 20.00
|
||||
(before att_in and before output VOA)
|
||||
noise figure (dB): 6.58
|
||||
(including att_in)
|
||||
pad att_in (dB): 0.00
|
||||
Power In (dBm): -0.18
|
||||
Power Out (dBm): 19.83
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 0.00
|
||||
effective pch (dBm): 0.00
|
||||
actual pch out (dBm): 0.01
|
||||
output VOA (dB): 0.00
|
||||
Fiber Span13
|
||||
type_variety: SSMF
|
||||
length (km): 80.00
|
||||
pad att_in (dB): 0.00
|
||||
total loss (dB): 16.00
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
reference pch out (dBm): -16.00
|
||||
actual pch out (dBm): -15.99
|
||||
Edfa Edfa13
|
||||
type_variety: test
|
||||
effective gain(dB): 16.00
|
||||
(before att_in and before output VOA)
|
||||
noise figure (dB): 8.86
|
||||
(including att_in)
|
||||
pad att_in (dB): 0.00
|
||||
Power In (dBm): 3.83
|
||||
Power Out (dBm): 19.84
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 0.00
|
||||
effective pch (dBm): 0.00
|
||||
actual pch out (dBm): 0.02
|
||||
output VOA (dB): 0.00
|
||||
Fiber Span14
|
||||
type_variety: SSMF
|
||||
length (km): 80.00
|
||||
pad att_in (dB): 0.00
|
||||
total loss (dB): 16.00
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
reference pch out (dBm): -16.00
|
||||
actual pch out (dBm): -15.98
|
||||
Edfa Edfa14
|
||||
type_variety: test_fixed_gain
|
||||
effective gain(dB): 16.00
|
||||
(before att_in and before output VOA)
|
||||
noise figure (dB): 9.00
|
||||
(including att_in)
|
||||
pad att_in (dB): 4.00
|
||||
Power In (dBm): 3.84
|
||||
Power Out (dBm): 19.85
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 0.00
|
||||
effective pch (dBm): 0.00
|
||||
actual pch out (dBm): 0.03
|
||||
output VOA (dB): 0.00
|
||||
Fiber Span15
|
||||
type_variety: SSMF
|
||||
length (km): 80.00
|
||||
pad att_in (dB): 0.00
|
||||
total loss (dB): 16.00
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
reference pch out (dBm): -16.00
|
||||
actual pch out (dBm): -15.97
|
||||
Edfa Edfa15
|
||||
type_variety: test
|
||||
effective gain(dB): 16.00
|
||||
(before att_in and before output VOA)
|
||||
noise figure (dB): 8.86
|
||||
(including att_in)
|
||||
pad att_in (dB): 0.00
|
||||
Power In (dBm): 3.85
|
||||
Power Out (dBm): 19.86
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 0.00
|
||||
effective pch (dBm): 0.00
|
||||
actual pch out (dBm): 0.04
|
||||
output VOA (dB): 0.00
|
||||
Roadm roadm Site B
|
||||
effective loss (dB): 20.00
|
||||
reference pch out (dBm): -20.00
|
||||
actual pch out (dBm): -20.00
|
||||
Transceiver Site_B
|
||||
GSNR (0.1nm, dB): 17.85
|
||||
GSNR (signal bw, dB): 13.77
|
||||
OSNR ASE (0.1nm, dB): 19.70
|
||||
OSNR ASE (signal bw, dB): 15.62
|
||||
CD (ps/nm): 20040.00
|
||||
PMD (ps): 1.39
|
||||
PDL (dB): 0.00
|
||||
|
||||
Transmission result for input power = 0.00 dBm:
|
||||
Final GSNR (0.1 nm): [1;36;40m17.85 dB[0m
|
||||
|
||||
(No source node specified: picked Site_A)
|
||||
|
||||
(No destination node specified: picked Site_B)
|
||||
@@ -252,8 +252,9 @@ Transceiver trx Lannion_CAS
|
||||
PMD (ps): 0.00
|
||||
PDL (dB): 0.00
|
||||
Roadm roadm Lannion_CAS
|
||||
effective loss (dB): 23.00
|
||||
pch out (dBm): -20.00
|
||||
effective loss (dB): 23.00
|
||||
reference pch out (dBm): -20.00
|
||||
actual pch out (dBm): -20.00
|
||||
Edfa east edfa in Lannion_CAS to Corlay
|
||||
type_variety: test
|
||||
effective gain(dB): 21.18
|
||||
@@ -266,6 +267,7 @@ Edfa east edfa in Lannion_CAS to Corlay
|
||||
Delta_P (dB): 0.00
|
||||
target pch (dBm): 3.00
|
||||
effective pch (dBm): 1.18
|
||||
actual pch out (dBm): 1.18
|
||||
output VOA (dB): 0.00
|
||||
Fiber fiber (Lannion_CAS → Corlay)-F061
|
||||
type_variety: SSMF
|
||||
@@ -274,7 +276,8 @@ Fiber fiber (Lannion_CAS → Corlay)-F061
|
||||
total loss (dB): 4.00
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
pch out (dBm): -2.82
|
||||
reference pch out (dBm): -2.82
|
||||
actual pch out (dBm): -2.81
|
||||
Fused west fused spans in Corlay
|
||||
loss (dB): 1.00
|
||||
Fiber fiber (Corlay → Loudeac)-F010
|
||||
@@ -284,7 +287,8 @@ Fiber fiber (Corlay → Loudeac)-F010
|
||||
total loss (dB): 10.00
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
pch out (dBm): -13.82
|
||||
reference pch out (dBm): -13.82
|
||||
actual pch out (dBm): -13.81
|
||||
Fused west fused spans in Loudeac
|
||||
loss (dB): 1.00
|
||||
Fiber fiber (Loudeac → Lorient_KMA)-F054
|
||||
@@ -294,7 +298,8 @@ Fiber fiber (Loudeac → Lorient_KMA)-F054
|
||||
total loss (dB): 12.00
|
||||
(includes conn loss (dB) in: 0.00 out: 0.00)
|
||||
(conn loss out includes EOL margin defined in eqpt_config.json)
|
||||
pch out (dBm): -26.82
|
||||
reference pch out (dBm): -26.82
|
||||
actual pch out (dBm): -26.81
|
||||
Edfa west edfa in Lorient_KMA to Loudeac
|
||||
type_variety: test
|
||||
effective gain(dB): 27.99
|
||||
@@ -307,10 +312,12 @@ Edfa west edfa in Lorient_KMA to Loudeac
|
||||
Delta_P (dB): -1.82
|
||||
target pch (dBm): 1.18
|
||||
effective pch (dBm): 1.17
|
||||
actual pch out (dBm): 1.21
|
||||
output VOA (dB): 0.00
|
||||
Roadm roadm Lorient_KMA
|
||||
effective loss (dB): 21.17
|
||||
pch out (dBm): -20.00
|
||||
effective loss (dB): 21.17
|
||||
reference pch out (dBm): -20.00
|
||||
actual pch out (dBm): -20.00
|
||||
Transceiver trx Lorient_KMA
|
||||
GSNR (0.1nm, dB): 23.94
|
||||
GSNR (signal bw, dB): 19.85
|
||||
|
||||
@@ -1 +1,6 @@
|
||||
build>=0.10.0,<1
|
||||
pytest>=6.2.5,<7
|
||||
pandas>=1.3.5,<2
|
||||
|
||||
# flake v6 killed the --diff option
|
||||
flake8>=5.0.4,<6
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
from numpy import zeros, array
|
||||
from gnpy.core.elements import Transceiver, Edfa
|
||||
from gnpy.core.utils import automatic_fmax, lin2db, db2lin, merge_amplifier_restrictions
|
||||
from gnpy.core.info import create_input_spectral_information, Pref
|
||||
from gnpy.core.info import create_input_spectral_information, ReferenceCarrier
|
||||
from gnpy.core.network import build_network
|
||||
from gnpy.tools.json_io import load_network, load_equipment
|
||||
from pathlib import Path
|
||||
@@ -73,7 +73,9 @@ def si(nch_and_spacing, bw):
|
||||
nb_channel, spacing = nch_and_spacing
|
||||
f_min = 191.3e12
|
||||
f_max = automatic_fmax(f_min, spacing, nb_channel)
|
||||
return create_input_spectral_information(f_min, f_max, 0.15, bw, 1e-3, spacing)
|
||||
return create_input_spectral_information(f_min=f_min, f_max=f_max, roll_off=0.15, baud_rate=bw, power=1e-3,
|
||||
spacing=spacing, tx_osnr=40.0,
|
||||
ref_carrier=ReferenceCarrier(baud_rate=32e9, slot_width=50e9))
|
||||
|
||||
|
||||
@pytest.mark.parametrize("gain, nf_expected", [(10, 15), (15, 10), (25, 5.8)])
|
||||
@@ -84,7 +86,7 @@ def test_variable_gain_nf(gain, nf_expected, setup_edfa_variable_gain, si):
|
||||
si.nli /= db2lin(gain)
|
||||
si.ase /= db2lin(gain)
|
||||
edfa.operational.gain_target = gain
|
||||
si.pref = si.pref._replace(p_span0=0, p_spani=-gain, neq_ch=lin2db(si.number_of_channels))
|
||||
si.pref = si.pref._replace(p_span0=0, p_spani=-gain)
|
||||
edfa.interpol_params(si)
|
||||
result = edfa.nf
|
||||
assert pytest.approx(nf_expected, abs=0.01) == result[0]
|
||||
@@ -98,7 +100,7 @@ def test_fixed_gain_nf(gain, nf_expected, setup_edfa_fixed_gain, si):
|
||||
si.nli /= db2lin(gain)
|
||||
si.ase /= db2lin(gain)
|
||||
edfa.operational.gain_target = gain
|
||||
si.pref = si.pref._replace(p_span0=0, p_spani=-gain, neq_ch=lin2db(si.number_of_channels))
|
||||
si.pref = si.pref._replace(p_span0=0, p_spani=-gain)
|
||||
edfa.interpol_params(si)
|
||||
assert pytest.approx(nf_expected, abs=0.01) == edfa.nf[0]
|
||||
|
||||
@@ -123,7 +125,7 @@ def test_compare_nf_models(gain, setup_edfa_variable_gain, si):
|
||||
si.ase /= db2lin(gain)
|
||||
edfa.operational.gain_target = gain
|
||||
# edfa is variable gain type
|
||||
si.pref = si.pref._replace(p_span0=0, p_spani=-gain, neq_ch=lin2db(si.number_of_channels))
|
||||
si.pref = si.pref._replace(p_span0=0, p_spani=-gain)
|
||||
edfa.interpol_params(si)
|
||||
nf_model = edfa.nf[0]
|
||||
|
||||
@@ -178,7 +180,7 @@ def test_ase_noise(gain, si, setup_trx, bw):
|
||||
si = span(si)
|
||||
print(span)
|
||||
|
||||
si.pref = si.pref._replace(p_span0=0, p_spani=-gain, neq_ch=lin2db(si.number_of_channels))
|
||||
si.pref = si.pref._replace(p_span0=0, p_spani=-gain)
|
||||
edfa.interpol_params(si)
|
||||
nf = edfa.nf
|
||||
print('nf', nf)
|
||||
|
||||
588
tests/test_equalization.py
Normal file
588
tests/test_equalization.py
Normal file
@@ -0,0 +1,588 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Author: Esther Le Rouzic
|
||||
# @Date: 2019-05-22
|
||||
"""
|
||||
@author: esther.lerouzic
|
||||
checks that new equalization option give the same output as old one:
|
||||
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
import pytest
|
||||
from numpy.testing import assert_allclose, assert_array_equal, assert_raises
|
||||
from numpy import array
|
||||
|
||||
from gnpy.core.utils import lin2db, automatic_nch, dbm2watt, power_dbm_to_psd_mw_ghz, watt2dbm, psd2powerdbm
|
||||
from gnpy.core.network import build_network
|
||||
from gnpy.core.elements import Roadm
|
||||
from gnpy.core.info import create_input_spectral_information, Pref, create_arbitrary_spectral_information, \
|
||||
ReferenceCarrier
|
||||
from gnpy.core.equipment import trx_mode_params
|
||||
from gnpy.core.exceptions import ConfigurationError
|
||||
from gnpy.tools.json_io import network_from_json, load_equipment, load_network, _spectrum_from_json, load_json
|
||||
from gnpy.topology.request import PathRequest, compute_constrained_path, propagate
|
||||
|
||||
|
||||
TEST_DIR = Path(__file__).parent
|
||||
EQPT_FILENAME = TEST_DIR / 'data/eqpt_config.json'
|
||||
NETWORK_FILENAME = TEST_DIR / 'data/testTopology_expected.json'
|
||||
|
||||
|
||||
@pytest.mark.parametrize('degree, equalization_type, target, expected_pch_out_dbm, expected_si',
|
||||
[('east edfa in Lannion_CAS to Morlaix', 'target_pch_out_db', -20, -20, [-20, -20, -20, -20, -20]),
|
||||
('east edfa in Lannion_CAS to Morlaix', 'target_psd_out_mWperGHz', 5e-4, -17.9588,
|
||||
[-17.9588, -16.7778, -14.9485, -16.7778, -17.9588]),
|
||||
('east edfa in Lannion_CAS to Morlaix', 'target_out_mWperSlotWidth', 3e-4, -18.2390,
|
||||
[-19.4885, -18.2390, -16.4781, -18.2390, -19.4885]),
|
||||
('east edfa in Lannion_CAS to Corlay', 'target_pch_out_db', -20, -16, [-16, -16, -16, -16, -16]),
|
||||
('east edfa in Lannion_CAS to Corlay', 'target_psd_out_mWperGHz', 5e-4, -16, [-16, -16, -16, -16, -16]),
|
||||
('east edfa in Lannion_CAS to Corlay', 'target_out_mWperSlotWidth', 5e-4, -16, [-16, -16, -16, -16, -16]),
|
||||
('east edfa in Lannion_CAS to Stbrieuc', 'target_pch_out_db', -20, -17.16699,
|
||||
[-17.16698771, -15.98599459, -14.15668776, -15.98599459, -17.16698771]),
|
||||
('east edfa in Lannion_CAS to Stbrieuc', 'target_psd_out_mWperGHz', 5e-4, -17.16699,
|
||||
[-17.16698771, -15.98599459, -14.15668776, -15.98599459, -17.16698771]),
|
||||
('east edfa in Lannion_CAS to Stbrieuc', 'target_out_mWperSlotWidth', 5e-4, -17.16699,
|
||||
[-17.16698771, -15.98599459, -14.15668776, -15.98599459, -17.16698771])])
|
||||
@pytest.mark.parametrize('delta_pdb_per_channel', [[0, 0, 0, 0, 0], [1, 3, 0, -5, 0]])
|
||||
def test_equalization_combination_degree(delta_pdb_per_channel, degree, equalization_type, target,
|
||||
expected_pch_out_dbm, expected_si):
|
||||
"""Check that ROADM correctly computes power of thr reference channel based on different
|
||||
combination of equalization for ROADM and per degree
|
||||
"""
|
||||
|
||||
roadm_config = {
|
||||
"uid": "roadm Lannion_CAS",
|
||||
"params": {
|
||||
"per_degree_pch_out_db": {
|
||||
"east edfa in Lannion_CAS to Corlay": -16
|
||||
},
|
||||
"per_degree_psd_out_mWperGHz": {
|
||||
"east edfa in Lannion_CAS to Stbrieuc": 6e-4
|
||||
},
|
||||
equalization_type: target,
|
||||
"add_drop_osnr": 38,
|
||||
"pmd": 0,
|
||||
"pdl": 0,
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
}
|
||||
}
|
||||
}
|
||||
roadm = Roadm(**roadm_config)
|
||||
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])
|
||||
signal = dbm2watt(array([-20.0, -18.0, -22.0, -25.0, -16.0]))
|
||||
ref_carrier = ReferenceCarrier(baud_rate=32e9, slot_width=50e9)
|
||||
pref = Pref(p_span0=0, p_spani=0, ref_carrier=ref_carrier)
|
||||
si = create_arbitrary_spectral_information(frequency=frequency, slot_width=slot_width,
|
||||
signal=signal, baud_rate=baud_rate, roll_off=0.15,
|
||||
delta_pdb_per_channel=delta_pdb_per_channel,
|
||||
tx_osnr=None, ref_power=pref)
|
||||
to_json_before_propagation = {
|
||||
'uid': 'roadm Lannion_CAS',
|
||||
'type': 'Roadm',
|
||||
'params': {
|
||||
equalization_type: target,
|
||||
'restrictions': {'preamp_variety_list': [], 'booster_variety_list': []},
|
||||
'per_degree_pch_out_db': {
|
||||
'east edfa in Lannion_CAS to Corlay': -16},
|
||||
"per_degree_psd_out_mWperGHz": {
|
||||
"east edfa in Lannion_CAS to Stbrieuc": 6e-4
|
||||
}
|
||||
},
|
||||
'metadata': {'location': {'latitude': 0, 'longitude': 0, 'city': None, 'region': None}}
|
||||
}
|
||||
assert roadm.to_json == to_json_before_propagation
|
||||
si = roadm(si, degree)
|
||||
assert roadm.ref_pch_out_dbm == pytest.approx(expected_pch_out_dbm, rel=1e-4)
|
||||
assert_allclose(expected_si, roadm.get_per_degree_power(degree, spectral_info=si), rtol=1e-3)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('equalization_type', ["target_psd_out_mWperGHz", "target_out_mWperSlotWidth"])
|
||||
def test_wrong_element_config(equalization_type):
|
||||
"""Check that 2 equalization correcty raise a config error
|
||||
"""
|
||||
roadm_config = {
|
||||
"uid": "roadm Brest_KLA",
|
||||
"params": {
|
||||
"per_degree_pch_out_db": {},
|
||||
"target_pch_out_db": -20,
|
||||
equalization_type: 3.125e-4,
|
||||
"add_drop_osnr": 38,
|
||||
"pmd": 0,
|
||||
"pdl": 0,
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Brest_KLA",
|
||||
"region": "RLD",
|
||||
"latitude": 4.0,
|
||||
"longitude": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
with pytest.raises(ConfigurationError):
|
||||
_ = Roadm(**roadm_config)
|
||||
|
||||
|
||||
def test_merge_equalization():
|
||||
"""Check that if equalization is not defined default one is correctly take and
|
||||
else that it is not overwritten
|
||||
"""
|
||||
json_data = {
|
||||
"elements": [{
|
||||
"uid": "roadm Brest_KLA",
|
||||
"type": "Roadm"}],
|
||||
"connections": []
|
||||
}
|
||||
equipment = load_equipment(EQPT_FILENAME)
|
||||
network = network_from_json(json_data, equipment)
|
||||
roadm = [n for n in network.nodes()][0]
|
||||
assert roadm.target_pch_out_dbm == -20
|
||||
delattr(equipment['Roadm']['default'], 'target_pch_out_db')
|
||||
setattr(equipment['Roadm']['default'], 'target_psd_out_mWperGHz', power_dbm_to_psd_mw_ghz(-20, 32e9))
|
||||
# json_data is changed (type is popped from json_data with network_from_json_function). Create a new one:
|
||||
json_data = {
|
||||
"elements": [{
|
||||
"uid": "roadm Brest_KLA",
|
||||
"type": "Roadm"}],
|
||||
"connections": []
|
||||
}
|
||||
network = network_from_json(json_data, equipment)
|
||||
roadm = [n for n in network.nodes()][0]
|
||||
assert roadm.target_pch_out_dbm is None
|
||||
assert roadm.target_psd_out_mWperGHz == 3.125e-4
|
||||
assert roadm.target_out_mWperSlotWidth is None
|
||||
json_data = {
|
||||
"elements": [{
|
||||
"uid": "roadm Brest_KLA",
|
||||
"type": "Roadm",
|
||||
"params": {"target_pch_out_db": -18}}],
|
||||
"connections": []
|
||||
}
|
||||
network = network_from_json(json_data, equipment)
|
||||
roadm = [n for n in network.nodes()][0]
|
||||
assert roadm.target_pch_out_dbm == -18
|
||||
assert roadm.target_psd_out_mWperGHz is None
|
||||
assert roadm.target_out_mWperSlotWidth is None
|
||||
json_data = {
|
||||
"elements": [{
|
||||
"uid": "roadm Brest_KLA",
|
||||
"type": "Roadm",
|
||||
"params": {"target_psd_out_mWperGHz": 5e-4}}],
|
||||
"connections": []
|
||||
}
|
||||
network = network_from_json(json_data, equipment)
|
||||
roadm = [n for n in network.nodes()][0]
|
||||
assert roadm.target_pch_out_dbm is None
|
||||
assert roadm.target_psd_out_mWperGHz == 5e-4
|
||||
assert roadm.target_out_mWperSlotWidth is None
|
||||
json_data = {
|
||||
"elements": [{
|
||||
"uid": "roadm Brest_KLA",
|
||||
"type": "Roadm",
|
||||
"params": {"target_out_mWperSlotWidth": 3e-4}}],
|
||||
"connections": []
|
||||
}
|
||||
network = network_from_json(json_data, equipment)
|
||||
roadm = [n for n in network.nodes()][0]
|
||||
assert roadm.target_pch_out_dbm is None
|
||||
assert roadm.target_psd_out_mWperGHz is None
|
||||
assert roadm.target_out_mWperSlotWidth == 3e-4
|
||||
|
||||
|
||||
@pytest.mark.parametrize('target_out, delta_pdb_per_channel, correction',
|
||||
[(-20, [0, 1, 3, 0.5, -2], [0, 0, 5, 5.5, 0]),
|
||||
(-20, [0, 0, 0, 0, 0], [0, 0, 2, 5, 0]),
|
||||
(-20, [-2, -2, -2, -2, -2], [0, 0, 0, 3, 0]),
|
||||
(-20, [0, 2, -2, -5, 4], [0, 0, 0, 0, 0]),
|
||||
(-25.5, [0, 1, 3, 0.5, -2], [0, 0, 0, 0, 0]), ])
|
||||
def test_low_input_power(target_out, delta_pdb_per_channel, correction):
|
||||
"""check that ROADM correctly equalizes on small examples, assumes p_span_0 = 0
|
||||
case of power equalisation
|
||||
"""
|
||||
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])
|
||||
signal = dbm2watt(array([-20.0, -18.0, -22.0, -25.0, -16.0]))
|
||||
target = target_out + array(delta_pdb_per_channel)
|
||||
ref_carrier = ReferenceCarrier(baud_rate=32e9, slot_width=50e9)
|
||||
pref = Pref(p_span0=0, p_spani=-20, ref_carrier=ref_carrier)
|
||||
si = create_arbitrary_spectral_information(frequency=frequency, slot_width=slot_width,
|
||||
signal=signal, baud_rate=baud_rate, roll_off=0.15,
|
||||
delta_pdb_per_channel=delta_pdb_per_channel,
|
||||
tx_osnr=None, ref_power=pref)
|
||||
roadm_config = {
|
||||
"uid": "roadm Brest_KLA",
|
||||
"params": {
|
||||
"per_degree_pch_out_db": {},
|
||||
"target_pch_out_db": target_out,
|
||||
"add_drop_osnr": 38,
|
||||
"pmd": 0,
|
||||
"pdl": 0,
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Brest_KLA",
|
||||
"region": "RLD",
|
||||
"latitude": 4.0,
|
||||
"longitude": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
roadm = Roadm(**roadm_config)
|
||||
si = roadm(si, 'toto')
|
||||
assert_allclose(watt2dbm(si.signal), target - correction, rtol=1e-5)
|
||||
# in other words check that if target is below input power, target is applied else power is unchanged
|
||||
assert_allclose((watt2dbm(signal) >= target) * target + (watt2dbm(signal) < target) * watt2dbm(signal),
|
||||
watt2dbm(si.signal), rtol=1e-5)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('target_out, delta_pdb_per_channel, correction',
|
||||
[(3.125e-4,
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 0, 2 + lin2db(64 / 32), 5 + lin2db(42 / 32), 0]),
|
||||
(3.125e-4,
|
||||
[1, 3, 0, -5, 0],
|
||||
[1, 1 + lin2db(42 / 32), 2 + lin2db(64 / 32), 0 + lin2db(42 / 32), 0]), ])
|
||||
def test_2low_input_power(target_out, delta_pdb_per_channel, correction):
|
||||
"""check that ROADM correctly equalizes on small examples, assumes p_span_0 = 0
|
||||
case of PSD equalisation
|
||||
"""
|
||||
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])
|
||||
signal = dbm2watt(array([-20.0, -18.0, -22.0, -25.0, -16.0]))
|
||||
target = psd2powerdbm(target_out, baud_rate) + array(delta_pdb_per_channel)
|
||||
ref_carrier = ReferenceCarrier(baud_rate=32e9, slot_width=50e9)
|
||||
pref = Pref(p_span0=0, p_spani=-20, ref_carrier=ref_carrier)
|
||||
si = create_arbitrary_spectral_information(frequency=frequency, slot_width=slot_width,
|
||||
signal=signal, baud_rate=baud_rate, roll_off=0.15,
|
||||
delta_pdb_per_channel=delta_pdb_per_channel,
|
||||
tx_osnr=None, ref_power=pref)
|
||||
roadm_config = {
|
||||
"uid": "roadm Brest_KLA",
|
||||
"params": {
|
||||
"per_degree_pch_out_db": {},
|
||||
"target_psd_out_mWperGHz": target_out,
|
||||
"add_drop_osnr": 38,
|
||||
"pmd": 0,
|
||||
"pdl": 0,
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
"city": "Brest_KLA",
|
||||
"region": "RLD",
|
||||
"latitude": 4.0,
|
||||
"longitude": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
roadm = Roadm(**roadm_config)
|
||||
si = roadm(si, 'toto')
|
||||
assert_allclose(watt2dbm(si.signal), target - correction, rtol=1e-5)
|
||||
|
||||
|
||||
def net_setup(equipment):
|
||||
""" common setup for tests: builds network, equipment and oms only once
|
||||
"""
|
||||
network = load_network(NETWORK_FILENAME, equipment)
|
||||
spectrum = equipment['SI']['default']
|
||||
p_db = spectrum.power_dbm
|
||||
p_total_db = p_db + lin2db(automatic_nch(spectrum.f_min, spectrum.f_max, spectrum.spacing))
|
||||
build_network(network, equipment, p_db, p_total_db)
|
||||
return network
|
||||
|
||||
|
||||
def create_voyager_req(equipment, source, dest, bidir, nodes_list, loose_list, mode, spacing, power_dbm):
|
||||
""" create the usual request list according to parameters
|
||||
"""
|
||||
params = {'request_id': 'test_request',
|
||||
'source': source,
|
||||
'bidir': bidir,
|
||||
'destination': dest,
|
||||
'trx_type': 'Voyager',
|
||||
'trx_mode': mode,
|
||||
'format': mode,
|
||||
'spacing': spacing,
|
||||
'nodes_list': nodes_list,
|
||||
'loose_list': loose_list,
|
||||
'path_bandwidth': 100.0e9,
|
||||
'effective_freq_slot': None}
|
||||
trx_params = trx_mode_params(equipment, params['trx_type'], params['trx_mode'], True)
|
||||
params.update(trx_params)
|
||||
params['power'] = dbm2watt(power_dbm) if power_dbm else dbm2watt(equipment['SI']['default'].power_dbm)
|
||||
f_min = params['f_min']
|
||||
f_max_from_si = params['f_max']
|
||||
params['nb_channel'] = automatic_nch(f_min, f_max_from_si, params['spacing'])
|
||||
return PathRequest(**params)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('power_dbm', [0, 1, -2, None])
|
||||
@pytest.mark.parametrize('mode, slot_width', (['mode 1', 50e9], ['mode 2', 75e9]))
|
||||
def test_initial_spectrum(mode, slot_width, power_dbm):
|
||||
""" checks that propagation using the user defined spectrum identical to SI, gives same result as SI
|
||||
"""
|
||||
# first propagate without any req.initial_spectrum attribute
|
||||
equipment = load_equipment(EQPT_FILENAME)
|
||||
req = create_voyager_req(equipment, 'trx Brest_KLA', 'trx Vannes_KBE', False, ['trx Vannes_KBE'], ['STRICT'],
|
||||
mode, slot_width, power_dbm)
|
||||
network = net_setup(equipment)
|
||||
path = compute_constrained_path(network, req)
|
||||
infos_expected = propagate(path, req, equipment)
|
||||
# then creates req.initial_spectrum attribute exactly corresponding to -spectrum option files
|
||||
temp = [{
|
||||
"f_min": 191.35e12 + slot_width,
|
||||
"f_max": 196.15e12 - slot_width,
|
||||
"baud_rate": req.baud_rate,
|
||||
"slot_width": slot_width,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40
|
||||
}]
|
||||
req.initial_spectrum = _spectrum_from_json(temp)
|
||||
infos_actual = propagate(path, req, equipment)
|
||||
print(infos_actual.frequency[0], infos_actual.frequency[-1])
|
||||
print(infos_expected.frequency[0], infos_expected.frequency[-1])
|
||||
|
||||
assert_array_equal(infos_expected.frequency, infos_actual.frequency)
|
||||
assert_array_equal(infos_expected.baud_rate, infos_actual.baud_rate)
|
||||
assert_array_equal(infos_expected.slot_width, infos_actual.slot_width)
|
||||
assert_array_equal(infos_expected.signal, infos_actual.signal)
|
||||
assert_array_equal(infos_expected.nli, infos_actual.nli)
|
||||
assert_array_equal(infos_expected.ase, infos_actual.ase)
|
||||
assert_array_equal(infos_expected.roll_off, infos_actual.roll_off)
|
||||
assert_array_equal(infos_expected.chromatic_dispersion, infos_actual.chromatic_dispersion)
|
||||
assert_array_equal(infos_expected.pmd, infos_actual.pmd)
|
||||
assert_array_equal(infos_expected.channel_number, infos_actual.channel_number)
|
||||
assert_array_equal(infos_expected.number_of_channels, infos_actual.number_of_channels)
|
||||
|
||||
|
||||
def test_initial_spectrum_not_identical():
|
||||
""" checks that user defined spectrum overrides spectrum defined in SI
|
||||
"""
|
||||
# first propagate without any req.initial_spectrum attribute
|
||||
equipment = load_equipment(EQPT_FILENAME)
|
||||
req = create_voyager_req(equipment, 'trx Brest_KLA', 'trx Vannes_KBE', False, ['trx Vannes_KBE'], ['STRICT'],
|
||||
'mode 1', 50e9, 0)
|
||||
network = net_setup(equipment)
|
||||
path = compute_constrained_path(network, req)
|
||||
infos_expected = propagate(path, req, equipment)
|
||||
# then creates req.initial_spectrum attribute exactly corresponding to -spectrum option files
|
||||
temp = [{
|
||||
"f_min": 191.4e12, # align f_min , f_max on Voyager f_min, f_mix and not SI !
|
||||
"f_max": 196.1e12,
|
||||
"baud_rate": 40e9,
|
||||
"slot_width": 62.5e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40
|
||||
}]
|
||||
req.initial_spectrum = _spectrum_from_json(temp)
|
||||
infos_actual = propagate(path, req, equipment)
|
||||
assert_raises(AssertionError, assert_array_equal, infos_expected.frequency, infos_actual.frequency)
|
||||
assert_raises(AssertionError, assert_array_equal, infos_expected.baud_rate, infos_actual.baud_rate)
|
||||
assert_raises(AssertionError, assert_array_equal, infos_expected.slot_width, infos_actual.slot_width)
|
||||
assert_raises(AssertionError, assert_array_equal, infos_expected.signal, infos_actual.signal)
|
||||
assert_raises(AssertionError, assert_array_equal, infos_expected.nli, infos_actual.nli)
|
||||
assert_raises(AssertionError, assert_array_equal, infos_expected.ase, infos_actual.ase)
|
||||
assert_raises(AssertionError, assert_array_equal, infos_expected.channel_number, infos_actual.channel_number)
|
||||
assert_raises(AssertionError, assert_array_equal, infos_expected.number_of_channels, infos_actual.number_of_channels)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('equalization, target_value', [
|
||||
('target_out_mWperSlotWidth', power_dbm_to_psd_mw_ghz(-20, 50e9)),
|
||||
('target_psd_out_mWperGHz', power_dbm_to_psd_mw_ghz(-20, 32e9))])
|
||||
@pytest.mark.parametrize('power_dbm', [0, 2, -0.5])
|
||||
def test_target_psd_or_psw(power_dbm, equalization, target_value):
|
||||
""" checks that if target_out_mWperSlotWidth or target_psd_out_mWperGHz is defined, it is used as equalization
|
||||
and it gives same result if computed target is the same
|
||||
"""
|
||||
equipment = load_equipment(EQPT_FILENAME)
|
||||
network = net_setup(equipment)
|
||||
req = create_voyager_req(equipment, 'trx Brest_KLA', 'trx Vannes_KBE', False, ['trx Vannes_KBE'], ['STRICT'],
|
||||
'mode 1', 50e9, power_dbm)
|
||||
path = compute_constrained_path(network, req)
|
||||
infos_expected = propagate(path, req, equipment)
|
||||
# change default equalization to power spectral density
|
||||
delattr(equipment['Roadm']['default'], 'target_pch_out_db')
|
||||
setattr(equipment['Roadm']['default'], equalization, target_value)
|
||||
# create a second instance with this roadm settings,
|
||||
network2 = net_setup(equipment)
|
||||
path2 = compute_constrained_path(network2, req)
|
||||
infos_actual = propagate(path2, req, equipment)
|
||||
# since baudrate is the same, resulting propagation should be the same as for power equalization
|
||||
assert_array_equal(infos_expected.baud_rate, infos_actual.baud_rate)
|
||||
assert_array_equal(infos_expected.slot_width, infos_actual.slot_width)
|
||||
assert_array_equal(infos_expected.signal, infos_actual.signal)
|
||||
assert_array_equal(infos_expected.nli, infos_actual.nli)
|
||||
assert_array_equal(infos_expected.ase, infos_actual.ase)
|
||||
assert_array_equal(infos_expected.roll_off, infos_actual.roll_off)
|
||||
assert_array_equal(infos_expected.chromatic_dispersion, infos_actual.chromatic_dispersion)
|
||||
assert_array_equal(infos_expected.pmd, infos_actual.pmd)
|
||||
assert_array_equal(infos_expected.channel_number, infos_actual.channel_number)
|
||||
assert_array_equal(infos_expected.number_of_channels, infos_actual.number_of_channels)
|
||||
|
||||
|
||||
def ref_network():
|
||||
""" Create a network instance with a instance of propagated path
|
||||
"""
|
||||
equipment = load_equipment(EQPT_FILENAME)
|
||||
network = net_setup(equipment)
|
||||
req0 = create_voyager_req(equipment, 'trx Brest_KLA', 'trx Vannes_KBE', False, ['trx Vannes_KBE'], ['STRICT'],
|
||||
'mode 1', 50e9, 0)
|
||||
path0 = compute_constrained_path(network, req0)
|
||||
_ = propagate(path0, req0, equipment)
|
||||
return network
|
||||
|
||||
|
||||
@pytest.mark.parametrize('deltap', [0, +1.2, -0.5])
|
||||
def test_target_psd_out_mwperghz_deltap(deltap):
|
||||
""" checks that if target_psd_out_mWperGHz is defined, delta_p of amps is correctly updated
|
||||
Power over 1.2dBm saturate amp with this test: TODO add a test on this saturation
|
||||
"""
|
||||
equipment = load_equipment(EQPT_FILENAME)
|
||||
network = net_setup(equipment)
|
||||
req = create_voyager_req(equipment, 'trx Brest_KLA', 'trx Vannes_KBE', False, ['trx Vannes_KBE'], ['STRICT'],
|
||||
'mode 1', 50e9, deltap)
|
||||
temp = [{
|
||||
"f_min": 191.35e12, # align f_min , f_max on Voyager f_min, f_mix and not SI !
|
||||
"f_max": 196.05e12,
|
||||
"baud_rate": req.baud_rate,
|
||||
"slot_width": 50e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40
|
||||
}]
|
||||
req.initial_spectrum = _spectrum_from_json(temp)
|
||||
path = compute_constrained_path(network, req)
|
||||
_ = propagate(path, req, equipment)
|
||||
# check that gain of booster is changed accordingly whereas gain of preamp and ila is not (no saturation case)
|
||||
boosters = ['east edfa in Brest_KLA to Quimper', 'east edfa in Lorient_KMA to Vannes_KBE']
|
||||
ila_preamps = ['east edfa in Quimper to Lorient_KMA', 'west edfa in Lorient_KMA to Quimper',
|
||||
'west edfa in Vannes_KBE to Lorient_KMA']
|
||||
for amp in boosters + ila_preamps:
|
||||
expected_amp = next(n for n in ref_network() if n.uid == amp)
|
||||
actual_amp = next(n for n in network.nodes() if n.uid == amp)
|
||||
expected_gain = expected_amp.pout_db - expected_amp.pin_db
|
||||
actual_gain = actual_amp.pout_db - actual_amp.pin_db
|
||||
print(actual_amp)
|
||||
if amp in boosters:
|
||||
assert expected_gain + deltap == pytest.approx(actual_gain, rel=1e-3)
|
||||
if amp in ila_preamps:
|
||||
assert expected_gain == pytest.approx(actual_gain, rel=1e-3)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('equalization', ['target_psd_out_mWperGHz', 'target_out_mWperSlotWidth'])
|
||||
@pytest.mark.parametrize('case', ['SI', 'nodes'])
|
||||
@pytest.mark.parametrize('deltap', [0, +2, -0.5])
|
||||
@pytest.mark.parametrize('target', [-20, -21, -18])
|
||||
@pytest.mark.parametrize('mode, slot_width', (['mode 1', 50e9], ['mode 2', 75e9]))
|
||||
def test_equalization(case, deltap, target, mode, slot_width, equalization):
|
||||
"""check that power target on roadm is correct for these cases; check on booster
|
||||
- SI : target_pch_out_db / target_psd_out_mWperGHz
|
||||
- node : target_pch_out_db / target_psd_out_mWperGHz
|
||||
- per degree : target_pch_out_db / target_psd_out_mWperGHz
|
||||
for these cases with and without power from user
|
||||
"""
|
||||
equipment = load_equipment(EQPT_FILENAME)
|
||||
setattr(equipment['Roadm']['default'], 'target_pch_out_db', target)
|
||||
req = create_voyager_req(equipment, 'trx Brest_KLA', 'trx Rennes_STA', False,
|
||||
['east edfa in Brest_KLA to Quimper', 'roadm Lannion_CAS', 'trx Rennes_STA'],
|
||||
['STRICT', 'STRICT', 'STRICT'],
|
||||
mode, slot_width, deltap)
|
||||
roadms = ['roadm Brest_KLA', 'roadm Lorient_KMA', 'roadm Lannion_CAS', 'roadm Rennes_STA']
|
||||
# degree = {'roadm Brest_KLA': 'east edfa in Brest_KLA to Quimper',
|
||||
# 'roadm Lorient_KMA': 'east edfa in Lorient_KMA to Loudeac'}
|
||||
# boosters = ['east edfa in Brest_KLA to Quimper', 'east edfa in Lorient_KMA to Loudeac',
|
||||
# 'east edfa in Lannion_CAS to Stbrieuc']
|
||||
target_psd = power_dbm_to_psd_mw_ghz(target, 32e9)
|
||||
ref = ReferenceCarrier(baud_rate=32e9, slot_width=50e9)
|
||||
if case == 'SI':
|
||||
delattr(equipment['Roadm']['default'], 'target_pch_out_db')
|
||||
setattr(equipment['Roadm']['default'], equalization, target_psd)
|
||||
network = net_setup(equipment)
|
||||
elif case == 'nodes':
|
||||
json_data = load_json(NETWORK_FILENAME)
|
||||
for el in json_data['elements']:
|
||||
if el['uid'] in roadms:
|
||||
el['params'] = {equalization: target_psd}
|
||||
network = network_from_json(json_data, equipment)
|
||||
spectrum = equipment['SI']['default']
|
||||
p_db = spectrum.power_dbm
|
||||
p_total_db = p_db + lin2db(automatic_nch(spectrum.f_min, spectrum.f_max, spectrum.spacing))
|
||||
build_network(network, equipment, p_db, p_total_db)
|
||||
# check that nodes not in roadms have target_pch_out_db not None
|
||||
pw_roadms = [r for r in network.nodes() if r.uid not in roadms and isinstance(r, Roadm)]
|
||||
for roadm in pw_roadms:
|
||||
assert roadm.target_psd_out_mWperGHz is None
|
||||
assert roadm.target_pch_out_dbm == target
|
||||
for roadm in [r for r in network.nodes() if r.uid in roadms and isinstance(r, Roadm)]:
|
||||
assert roadm.target_pch_out_dbm is None
|
||||
assert getattr(roadm, equalization) == target_psd
|
||||
path = compute_constrained_path(network, req)
|
||||
si = create_input_spectral_information(
|
||||
f_min=req.f_min, f_max=req.f_max, roll_off=req.roll_off, baud_rate=req.baud_rate, power=req.power,
|
||||
spacing=req.spacing, tx_osnr=req.tx_osnr, ref_carrier=ref)
|
||||
for i, el in enumerate(path):
|
||||
if isinstance(el, Roadm):
|
||||
si = el(si, degree=path[i + 1].uid)
|
||||
if case in ['SI', 'nodes', 'degrees']:
|
||||
if equalization == 'target_psd_out_mWperGHz':
|
||||
assert_allclose(power_dbm_to_psd_mw_ghz(watt2dbm(si.signal + si.ase + si.nli), si.baud_rate),
|
||||
target_psd, rtol=1e-3)
|
||||
if equalization == 'target_out_mWperSlotWidth':
|
||||
assert_allclose(power_dbm_to_psd_mw_ghz(watt2dbm(si.signal + si.ase + si.nli), si.slot_width),
|
||||
target_psd, rtol=1e-3)
|
||||
else:
|
||||
si = el(si)
|
||||
print(el.uid)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('req_power', [0, 2, -1.5])
|
||||
def test_power_option(req_power):
|
||||
"""check that --po option adds correctly power with spectral information
|
||||
"""
|
||||
equipment = load_equipment(EQPT_FILENAME)
|
||||
setattr(equipment['Roadm']['default'], 'target_pch_out_db', None)
|
||||
setattr(equipment['Roadm']['default'], 'target_psd_out_mWperGHz', power_dbm_to_psd_mw_ghz(-20, 32e9))
|
||||
network = net_setup(equipment)
|
||||
req = create_voyager_req(equipment, 'trx Brest_KLA', 'trx Vannes_KBE', False, ['trx Vannes_KBE'], ['STRICT'],
|
||||
'mode 1', 50e9, req_power)
|
||||
path = compute_constrained_path(network, req)
|
||||
infos_expected = propagate(path, req, equipment)
|
||||
|
||||
temp = [{
|
||||
"f_min": 191.4e12, # align f_min , f_max on Voyager f_min, f_max and not SI !
|
||||
"f_max": 196.1e12,
|
||||
"baud_rate": req.baud_rate,
|
||||
"slot_width": 50e9,
|
||||
"roll_off": 0.15,
|
||||
"tx_osnr": 40
|
||||
}]
|
||||
req.initial_spectrum = _spectrum_from_json(temp)
|
||||
network2 = net_setup(equipment)
|
||||
path2 = compute_constrained_path(network2, req)
|
||||
infos_actual = propagate(path2, req, equipment)
|
||||
assert_array_equal(infos_expected.baud_rate, infos_actual.baud_rate)
|
||||
assert_array_equal(infos_expected.slot_width, infos_actual.slot_width)
|
||||
assert_array_equal(infos_expected.signal, infos_actual.signal)
|
||||
assert_array_equal(infos_expected.nli, infos_actual.nli)
|
||||
assert_array_equal(infos_expected.ase, infos_actual.ase)
|
||||
assert_array_equal(infos_expected.roll_off, infos_actual.roll_off)
|
||||
assert_array_equal(infos_expected.chromatic_dispersion, infos_actual.chromatic_dispersion)
|
||||
assert_array_equal(infos_expected.pmd, infos_actual.pmd)
|
||||
assert_array_equal(infos_expected.channel_number, infos_actual.channel_number)
|
||||
assert_array_equal(infos_expected.number_of_channels, infos_actual.number_of_channels)
|
||||
@@ -4,47 +4,56 @@
|
||||
import pytest
|
||||
from numpy import array, zeros, ones
|
||||
from numpy.testing import assert_array_equal
|
||||
|
||||
from gnpy.core.info import create_arbitrary_spectral_information
|
||||
from gnpy.core.info import create_arbitrary_spectral_information, Pref
|
||||
from gnpy.core.exceptions import SpectrumError
|
||||
|
||||
|
||||
def test_create_arbitrary_spectral_information():
|
||||
si = create_arbitrary_spectral_information(frequency=[193.25e12, 193.3e12, 193.35e12],
|
||||
baud_rate=32e9, signal=[1, 1, 1])
|
||||
baud_rate=32e9, signal=[1, 1, 1],
|
||||
delta_pdb_per_channel=[1, 1, 1],
|
||||
tx_osnr=40.0,
|
||||
ref_power=Pref(1, 1, None))
|
||||
assert_array_equal(si.baud_rate, array([32e9, 32e9, 32e9]))
|
||||
assert_array_equal(si.slot_width, array([37.5e9, 37.5e9, 37.5e9]))
|
||||
assert_array_equal(si.signal, ones(3))
|
||||
assert_array_equal(si.nli, zeros(3))
|
||||
assert_array_equal(si.ase, zeros(3))
|
||||
assert_array_equal(si.delta_pdb_per_channel, ones(3))
|
||||
assert_array_equal(si.roll_off, zeros(3))
|
||||
assert_array_equal(si.chromatic_dispersion, zeros(3))
|
||||
assert_array_equal(si.pmd, zeros(3))
|
||||
assert_array_equal(si.channel_number, array([1, 2, 3]))
|
||||
assert_array_equal(si.number_of_channels, 3)
|
||||
assert_array_equal(si.df, array([[0, 50e9, 100e9], [-50e9, 0, 50e9], [-100e9, -50e9, 0]]))
|
||||
assert_array_equal(si.tx_osnr, array([40.0, 40.0, 40.0]))
|
||||
|
||||
with pytest.raises(SpectrumError, match='Spectra cannot be summed: channels overlapping.'):
|
||||
si += si
|
||||
|
||||
si = create_arbitrary_spectral_information(frequency=array([193.35e12, 193.3e12, 193.25e12]),
|
||||
slot_width=array([50e9, 50e9, 50e9]),
|
||||
baud_rate=32e9, signal=array([1, 2, 3]))
|
||||
baud_rate=32e9, signal=array([1, 2, 3]),
|
||||
tx_osnr=40.0,
|
||||
ref_power=Pref(1, 1, None))
|
||||
|
||||
assert_array_equal(si.signal, array([3, 2, 1]))
|
||||
|
||||
with pytest.raises(SpectrumError, match='Spectrum baud rate, including the roll off, '
|
||||
r'larger than the slot width for channels: \[1, 3\].'):
|
||||
create_arbitrary_spectral_information(frequency=[193.25e12, 193.3e12, 193.35e12], signal=1,
|
||||
baud_rate=[64e9, 32e9, 64e9], slot_width=50e9)
|
||||
baud_rate=[64e9, 32e9, 64e9], slot_width=50e9,
|
||||
tx_osnr=40.0,
|
||||
ref_power=Pref(1, 1, None))
|
||||
with pytest.raises(SpectrumError, match='Spectrum required slot widths larger than the frequency spectral '
|
||||
r'distances between channels: \[\(1, 2\), \(3, 4\)\].'):
|
||||
create_arbitrary_spectral_information(frequency=[193.26e12, 193.3e12, 193.35e12, 193.39e12], signal=1,
|
||||
baud_rate=32e9, slot_width=50e9)
|
||||
tx_osnr=40.0, baud_rate=32e9, slot_width=50e9, ref_power=Pref(1, 1, None))
|
||||
with pytest.raises(SpectrumError, match='Spectrum required slot widths larger than the frequency spectral '
|
||||
r'distances between channels: \[\(1, 2\), \(2, 3\)\].'):
|
||||
create_arbitrary_spectral_information(frequency=[193.25e12, 193.3e12, 193.35e12], signal=1, baud_rate=49e9,
|
||||
roll_off=0.1)
|
||||
|
||||
tx_osnr=40.0, roll_off=0.1, ref_power=Pref(1, 1, None))
|
||||
with pytest.raises(SpectrumError,
|
||||
match='Dimension mismatch in input fields.'):
|
||||
create_arbitrary_spectral_information(frequency=[193.25e12, 193.3e12, 193.35e12], signal=[1, 2], baud_rate=49e9)
|
||||
create_arbitrary_spectral_information(frequency=[193.25e12, 193.3e12, 193.35e12], signal=[1, 2], baud_rate=49e9,
|
||||
tx_osnr=40.0, ref_power=Pref(1, 1, None))
|
||||
|
||||
@@ -20,7 +20,15 @@ SRC_ROOT = Path(__file__).parent.parent
|
||||
['-e', 'gnpy/example-data/eqpt_config_openroadm_ver4.json', 'gnpy/example-data/Sweden_OpenROADMv4_example_network.json', ]),
|
||||
('openroadm-v5-Stockholm-Gothenburg', transmission_main_example,
|
||||
['-e', 'gnpy/example-data/eqpt_config_openroadm_ver5.json', 'gnpy/example-data/Sweden_OpenROADMv5_example_network.json', ]),
|
||||
))
|
||||
('transmission_main_example_long', transmission_main_example,
|
||||
['-e', 'tests/data/eqpt_config.json', 'tests/data/test_long_network.json']),
|
||||
('spectrum1_transmission_main_example', transmission_main_example,
|
||||
['--spectrum', 'gnpy/example-data/initial_spectrum1.json', 'gnpy/example-data/meshTopologyExampleV2.xls', ]),
|
||||
('spectrum2_transmission_main_example', transmission_main_example,
|
||||
['--spectrum', 'gnpy/example-data/initial_spectrum2.json', 'gnpy/example-data/meshTopologyExampleV2.xls', '--show-channels', ]),
|
||||
))
|
||||
|
||||
|
||||
def test_example_invocation(capfd, output, handler, args):
|
||||
'''Make sure that our examples produce useful output'''
|
||||
os.chdir(SRC_ROOT)
|
||||
|
||||
@@ -506,3 +506,71 @@ def test_eqpt_creation(tmpdir):
|
||||
# check that all amp in the converted files corresponds to an eqpt line
|
||||
for ampuid in jsonconverted.keys():
|
||||
assert ampuid in possiblename
|
||||
|
||||
|
||||
def test_service_json_constraint_order():
|
||||
"""test that the constraints are read in correct order"""
|
||||
|
||||
unsorted_request = {
|
||||
"request-id": "unsorted",
|
||||
"source": "trx Brest_KLA",
|
||||
"destination": "trx Vannes_KBE",
|
||||
"src-tp-id": "trx Brest_KLA",
|
||||
"dst-tp-id": "trx Vannes_KBE",
|
||||
"bidirectional": False,
|
||||
"path-constraints": {
|
||||
"te-bandwidth": {
|
||||
"technology": "flexi-grid",
|
||||
"trx_type": "Voyager",
|
||||
"trx_mode": "mode 1",
|
||||
"spacing": 50000000000.0,
|
||||
"output-power": 0.001,
|
||||
"path_bandwidth": 10000000000.0
|
||||
}
|
||||
},
|
||||
"explicit-route-objects": {
|
||||
"route-object-include-exclude": [
|
||||
{
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"index": 2,
|
||||
"num-unnum-hop": {
|
||||
"node-id": "roadm Lorient_KMA",
|
||||
"link-tp-id": "link-tp-id is not used",
|
||||
"hop-type": "STRICT"
|
||||
}
|
||||
},
|
||||
{
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"index": 3,
|
||||
"num-unnum-hop": {
|
||||
"node-id": "roadm Vannes_KBE",
|
||||
"link-tp-id": "link-tp-id is not used",
|
||||
"hop-type": "STRICT"
|
||||
}
|
||||
},
|
||||
{
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"index": 1,
|
||||
"num-unnum-hop": {
|
||||
"node-id": "roadm Lannion_CAS",
|
||||
"link-tp-id": "link-tp-id is not used",
|
||||
"hop-type": "LOOSE"
|
||||
}
|
||||
},
|
||||
{
|
||||
"explicit-route-usage": "route-include-ero",
|
||||
"index": 0,
|
||||
"num-unnum-hop": {
|
||||
"node-id": "roadm Brest_KLA",
|
||||
"link-tp-id": "link-tp-id is not used",
|
||||
"hop-type": "STRICT"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
data = {'path-request': [unsorted_request]}
|
||||
rqs = requests_from_json(data, equipment)
|
||||
assert rqs[0].nodes_list == ['roadm Brest_KLA', 'roadm Lannion_CAS', 'roadm Lorient_KMA', 'roadm Vannes_KBE']
|
||||
assert rqs[0].loose_list == ['STRICT', 'LOOSE', 'STRICT', 'STRICT']
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import pytest
|
||||
from gnpy.core.elements import Transceiver, Fiber, Edfa, Roadm
|
||||
from gnpy.core.utils import db2lin
|
||||
from gnpy.core.info import create_input_spectral_information
|
||||
from gnpy.core.info import create_input_spectral_information, ReferenceCarrier
|
||||
from gnpy.core.network import build_network
|
||||
from gnpy.tools.json_io import load_network, load_equipment
|
||||
from pathlib import Path
|
||||
@@ -45,7 +45,9 @@ def propagation(input_power, con_in, con_out, dest):
|
||||
p = input_power
|
||||
p = db2lin(p) * 1e-3
|
||||
spacing = 50e9 # THz
|
||||
si = create_input_spectral_information(191.3e12, 191.3e12 + 79 * spacing, 0.15, 32e9, p, spacing)
|
||||
si = create_input_spectral_information(f_min=191.3e12, f_max=191.3e12 + 79 * spacing, roll_off=0.15,
|
||||
baud_rate=32e9, power=p, spacing=spacing, tx_osnr=None,
|
||||
ref_carrier=ReferenceCarrier(baud_rate=32e9, slot_width=50e9))
|
||||
source = next(transceivers[uid] for uid in transceivers if uid == 'trx A')
|
||||
sink = next(transceivers[uid] for uid in transceivers if uid == dest)
|
||||
path = dijkstra_path(network, source, sink)
|
||||
|
||||
@@ -19,7 +19,7 @@ from gnpy.core.elements import Fused, Roadm, Edfa
|
||||
from gnpy.core.network import build_network
|
||||
from gnpy.tools.json_io import network_from_json, load_equipment, load_json, Amp
|
||||
from gnpy.core.equipment import trx_mode_params
|
||||
from gnpy.topology.request import PathRequest, compute_constrained_path
|
||||
from gnpy.topology.request import PathRequest, compute_constrained_path, ref_carrier
|
||||
from gnpy.core.info import create_input_spectral_information
|
||||
from gnpy.core.utils import db2lin
|
||||
|
||||
@@ -228,9 +228,9 @@ def test_roadm_target_power(prev_node_type, effective_pch_out_db, power_dbm):
|
||||
prev_node['params'] = {'loss': 0}
|
||||
json_network['elements'].append(prev_node)
|
||||
network = network_from_json(json_network, equipment)
|
||||
p_total_db = power_dbm + lin2db(automatic_nch(equipment['SI']['default'].f_min,
|
||||
equipment['SI']['default'].f_max,
|
||||
equipment['SI']['default'].spacing))
|
||||
nb_channel = automatic_nch(equipment['SI']['default'].f_min, equipment['SI']['default'].f_max,
|
||||
equipment['SI']['default'].spacing)
|
||||
p_total_db = power_dbm + lin2db(nb_channel)
|
||||
|
||||
build_network(network, equipment, power_dbm, p_total_db)
|
||||
|
||||
@@ -245,6 +245,7 @@ def test_roadm_target_power(prev_node_type, effective_pch_out_db, power_dbm):
|
||||
'format': '',
|
||||
'path_bandwidth': 100e9,
|
||||
'effective_freq_slot': None,
|
||||
'nb_channel': nb_channel
|
||||
}
|
||||
trx_params = trx_mode_params(equipment)
|
||||
params.update(trx_params)
|
||||
@@ -252,15 +253,14 @@ def test_roadm_target_power(prev_node_type, effective_pch_out_db, power_dbm):
|
||||
req.power = db2lin(power_dbm - 30)
|
||||
path = compute_constrained_path(network, req)
|
||||
si = create_input_spectral_information(
|
||||
req.f_min, req.f_max, req.roll_off, req.baud_rate,
|
||||
req.power, req.spacing)
|
||||
f_min=req.f_min, f_max=req.f_max, roll_off=req.roll_off, baud_rate=req.baud_rate,
|
||||
power=req.power, spacing=req.spacing, tx_osnr=req.tx_osnr, ref_carrier=ref_carrier(equipment))
|
||||
for i, el in enumerate(path):
|
||||
if isinstance(el, Roadm):
|
||||
min_power_in_roadm = min(si.signal + si.ase + si.nli)
|
||||
power_in_roadm = si.signal + si.ase + si.nli
|
||||
si = el(si, degree=path[i + 1].uid)
|
||||
power_out_roadm = si.signal + si.ase + si.nli
|
||||
if el.uid == 'roadm node B':
|
||||
print('input', min_power_in_roadm)
|
||||
# if previous was an EDFA, power level at ROADM input is enough for the ROADM to apply its
|
||||
# target power (as specified in equipment ie -20 dBm)
|
||||
# if it is a Fused, the input power to the ROADM is smaller than the target power, and the
|
||||
@@ -279,7 +279,7 @@ def test_roadm_target_power(prev_node_type, effective_pch_out_db, power_dbm):
|
||||
# to roadm is low.
|
||||
# check that target power correctly reports power_dbm from previous propagation
|
||||
assert_allclose(el.ref_pch_out_dbm, effective_pch_out_db + power_dbm, rtol=1e-3)
|
||||
# Check that egress power of roadm is equalized to the min carrier input power.
|
||||
assert_allclose(power_out_roadm, min_power_in_roadm, rtol=1e-3)
|
||||
# Check that egress power of roadm is not equalized power out is the same as power in.
|
||||
assert_allclose(power_out_roadm, power_in_roadm, rtol=1e-3)
|
||||
else:
|
||||
si = el(si)
|
||||
|
||||
@@ -12,7 +12,7 @@ from numpy.testing import assert_allclose
|
||||
from numpy import array, genfromtxt
|
||||
import pytest
|
||||
|
||||
from gnpy.core.info import create_input_spectral_information, create_arbitrary_spectral_information
|
||||
from gnpy.core.info import create_input_spectral_information, create_arbitrary_spectral_information, Pref, ReferenceCarrier
|
||||
from gnpy.core.elements import Fiber, RamanFiber
|
||||
from gnpy.core.parameters import SimParams
|
||||
from gnpy.tools.json_io import load_json
|
||||
@@ -28,7 +28,8 @@ def test_fiber():
|
||||
|
||||
# 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, power=1e-3, spacing=50e9)
|
||||
baud_rate=32e9, power=1e-3, spacing=50e9, tx_osnr=40.0,
|
||||
ref_carrier=ReferenceCarrier(baud_rate=32e9, slot_width=50e9))
|
||||
# propagation
|
||||
spectral_info_out = fiber(spectral_info_input)
|
||||
|
||||
@@ -44,8 +45,12 @@ def test_fiber():
|
||||
slot_width = array([37.5e9, 50e9, 75e9, 50e9, 37.5e9])
|
||||
baud_rate = array([32e9, 42e9, 64e9, 42e9, 32e9])
|
||||
signal = 1e-3 + array([0, -1e-4, 3e-4, -2e-4, +2e-4])
|
||||
delta_pdb_per_channel = [0, 0, 0, 0, 0]
|
||||
pref = Pref(p_span0=0, p_spani=0, ref_carrier=None)
|
||||
spectral_info_input = create_arbitrary_spectral_information(frequency=frequency, slot_width=slot_width,
|
||||
signal=signal, baud_rate=baud_rate, roll_off=0.15)
|
||||
signal=signal, baud_rate=baud_rate, roll_off=0.15,
|
||||
delta_pdb_per_channel=delta_pdb_per_channel,
|
||||
tx_osnr=40.0, ref_power=pref)
|
||||
|
||||
# propagation
|
||||
spectral_info_out = fiber(spectral_info_input)
|
||||
@@ -63,7 +68,8 @@ 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, power=1e-3, spacing=50e9)
|
||||
baud_rate=32e9, power=1e-3, spacing=50e9, tx_osnr=40.0,
|
||||
ref_carrier=ReferenceCarrier(baud_rate=32e9, slot_width=50e9))
|
||||
SimParams.set_params(load_json(TEST_DIR / 'data' / 'sim_params.json'))
|
||||
fiber = RamanFiber(**load_json(TEST_DIR / 'data' / 'test_science_utils_fiber_config.json'))
|
||||
|
||||
@@ -100,7 +106,8 @@ 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, power=1e-3, spacing=50e9)
|
||||
baud_rate=32e9, power=1e-3, spacing=50e9, tx_osnr=40.0,
|
||||
ref_carrier=ReferenceCarrier(baud_rate=32e9, slot_width=50e9))
|
||||
|
||||
SimParams.set_params(load_json(TEST_DIR / 'data' / 'sim_params.json'))
|
||||
fiber = Fiber(**load_json(TEST_DIR / 'data' / 'test_lumped_losses_raman_fiber_config.json'))
|
||||
|
||||
4
tox.ini
4
tox.ini
@@ -19,7 +19,7 @@ commands =
|
||||
pytest {env:CI_COVERAGE_OPTS:} -vv {posargs}
|
||||
cover: coverage html -d cover
|
||||
cover: coverage xml -o cover/coverage.xml
|
||||
python setup.py bdist_wheel
|
||||
python -m build
|
||||
|
||||
[testenv:docs]
|
||||
deps =
|
||||
@@ -43,4 +43,4 @@ commands =
|
||||
[flake8]
|
||||
max-line-length = 120
|
||||
max-complexity = 15
|
||||
ignore = N806
|
||||
ignore = N806 W503
|
||||
|
||||
Reference in New Issue
Block a user