32 Commits
v2.8 ... v2.9

Author SHA1 Message Date
Jan Kundrát
5b6f8c60cf docs: use the default theme on ReadTheDocs.org as well
Historically, we've been using the RTD theme on the RTD site which hosts
the docs for us, and a Sphinx-default, "Alabaster" theme for other docs
builds. Doing that however started failing:

 Traceback (most recent call last):
   File "/home/docs/checkouts/readthedocs.org/user_builds/gnpy/envs/499/lib/python3.12/site-packages/sphinx/builders/html/__init__.py", line 1096, in handle_page
     output = self.templates.render(templatename, ctx)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/docs/checkouts/readthedocs.org/user_builds/gnpy/envs/499/lib/python3.12/site-packages/readthedocs_ext/readthedocs.py", line 181, in rtd_render
     content = old_render(template, render_context)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/docs/checkouts/readthedocs.org/user_builds/gnpy/envs/499/lib/python3.12/site-packages/sphinx/jinja2glue.py", line 194, in render
     return self.environment.get_template(template).render(context)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/docs/checkouts/readthedocs.org/user_builds/gnpy/envs/499/lib/python3.12/site-packages/jinja2/environment.py", line 1301, in render
     self.environment.handle_exception()
   File "/home/docs/checkouts/readthedocs.org/user_builds/gnpy/envs/499/lib/python3.12/site-packages/jinja2/environment.py", line 936, in handle_exception
     raise rewrite_traceback_stack(source=source)
   File "/home/docs/checkouts/readthedocs.org/user_builds/gnpy/envs/499/lib/python3.12/site-packages/sphinx/themes/basic/page.html", line 10, in top-level template code
     {%- extends "layout.html" %}
     ^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/docs/checkouts/readthedocs.org/user_builds/gnpy/envs/499/lib/python3.12/site-packages/sphinx/themes/classic/layout.html", line 10, in top-level template code
     {%- extends "basic/layout.html" %}
     ^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/docs/checkouts/readthedocs.org/user_builds/gnpy/envs/499/lib/python3.12/site-packages/sphinx/themes/default/../basic/layout.html", line 170, in top-level template code
     {%- block content %}
   File "/home/docs/checkouts/readthedocs.org/user_builds/gnpy/envs/499/lib/python3.12/site-packages/sphinx/themes/default/../basic/layout.html", line 189, in block 'content'
     {%- block sidebar2 %}{{ sidebar() }}{% endblock %}
     ^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/docs/checkouts/readthedocs.org/user_builds/gnpy/envs/499/lib/python3.12/site-packages/sphinx/themes/default/../basic/layout.html", line 189, in block 'sidebar2'
     {%- block sidebar2 %}{{ sidebar() }}{% endblock %}
     ^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/docs/checkouts/readthedocs.org/user_builds/gnpy/envs/499/lib/python3.12/site-packages/jinja2/sandbox.py", line 393, in call
     return __context.call(__obj, *args, **kwargs)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/docs/checkouts/readthedocs.org/user_builds/gnpy/envs/499/lib/python3.12/site-packages/jinja2/runtime.py", line 777, in _invoke
     rv = self._func(*arguments)
          ^^^^^^^^^^^^^^^^^^^^^^
   File "/home/docs/checkouts/readthedocs.org/user_builds/gnpy/envs/499/lib/python3.12/site-packages/sphinx/themes/default/../basic/layout.html", line 63, in template
     {%- include sidebartemplate %}
     ^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/docs/checkouts/readthedocs.org/user_builds/gnpy/envs/499/lib/python3.12/site-packages/sphinx/jinja2glue.py", line 215, in get_source
     raise TemplateNotFound(template)
 jinja2.exceptions.TemplateNotFound: about.html

 The above exception was the direct cause of the following exception:

 Traceback (most recent call last):
   File "/home/docs/checkouts/readthedocs.org/user_builds/gnpy/envs/499/lib/python3.12/site-packages/sphinx/cmd/build.py", line 281, in build_main
     app.build(args.force_all, args.filenames)
   File "/home/docs/checkouts/readthedocs.org/user_builds/gnpy/envs/499/lib/python3.12/site-packages/sphinx/application.py", line 347, in build
     self.builder.build_update()
   File "/home/docs/checkouts/readthedocs.org/user_builds/gnpy/envs/499/lib/python3.12/site-packages/sphinx/builders/__init__.py", line 310, in build_update
     self.build(to_build,
   File "/home/docs/checkouts/readthedocs.org/user_builds/gnpy/envs/499/lib/python3.12/site-packages/sphinx/builders/__init__.py", line 376, in build
     self.write(docnames, list(updated_docnames), method)
   File "/home/docs/checkouts/readthedocs.org/user_builds/gnpy/envs/499/lib/python3.12/site-packages/sphinx/builders/__init__.py", line 571, in write
     self._write_serial(sorted(docnames))
   File "/home/docs/checkouts/readthedocs.org/user_builds/gnpy/envs/499/lib/python3.12/site-packages/sphinx/builders/__init__.py", line 581, in _write_serial
     self.write_doc(docname, doctree)
   File "/home/docs/checkouts/readthedocs.org/user_builds/gnpy/envs/499/lib/python3.12/site-packages/sphinx/builders/html/__init__.py", line 672, in write_doc
     self.handle_page(docname, ctx, event_arg=doctree)
   File "/home/docs/checkouts/readthedocs.org/user_builds/gnpy/envs/499/lib/python3.12/site-packages/sphinx/builders/html/__init__.py", line 1103, in handle_page
     raise ThemeError(__("An error happened in rendering the page %s.\nReason: %r") %
 sphinx.errors.ThemeError: An error happened in rendering the page about-project.
 Reason: TemplateNotFound('about.html')

 Theme error:
 An error happened in rendering the page about-project.
 Reason: TemplateNotFound('about.html')

I have no clue what that means because we have never requested this
`about.html`, nor do we reference that file from anywhere. Chances are
that it's "just" some version pinning/compatibility issue, but hey --
why mess with that when there's a perfectly good default theme that
we're using for other purposes already.

As a side effect, this also solves that long-standing issue that Esther
reported where the tables have overly long lines. Apparently, it's a
theme-specific misfeature (readthedocs/sphinx_rtd_theme/#117), and the
Alabaster one doesn't suffer from that.

All hail alabaster!

Change-Id: I857890f29f14b7c0f66bca201c9a9c1b1cbf8841
2024-03-13 21:30:20 +01:00
Jan Kundrát
3a733b1fd5 docs: try to unbreak the readthedocs.io build
It was failing with a message:

  Config validation error in build.os. Value os not found.

Apparently, the v2 config file is mandatory, so let's do that.

Change-Id: I267d5314db026de532b2b6644f500d25de08e343
2024-03-13 21:30:20 +01:00
Jan Kundrát
2d68b94a46 build: specify dependencies directly in setup.cfg
In tox v4, "reuse of environments" was disabled [1]. This is then later
explained [2] to refer to exactly that thing which we were using for
inheriting the dependencies from the top-level testenv all the way to
the docs build. That's why the docs build in GitHub CI started failing.

IMHO, The Correct Way™ of specifying what dependencies are used for
which feature are the so-called "extra dependencies". Once they are in
place, it is be possible to install gnpy via, e.g., `pip install
oopt-gnpy[docs]`. However, this process is (as far as I can tell)
incompatible with `requirements.txt`; all my attempts at using the
standard dependency syntax in that file have failed for me.

So, in order to make this happen, let's move all the dependencies from a
more-or-less ad-hoc collection of files to this declarative approach
right in setup.cfg. That way, the deps are listed on a single place, in
a declarative manner, and as a result, the installation is now a trivial
pip oneliner.

As a result, one can also remove that duplication of dependencies in
docs requirements.

[1] https://tox.wiki/en/4.11.4/upgrading.html#reuse-of-environments
[2] https://tox.wiki/en/4.11.4/upgrading.html#packaging-configuration-and-inheritance

Change-Id: I34aa0c71e993b39e2b805a7de40e133b4d290318
Fixes: 47c89626 fix docs requirements
2024-03-13 21:28:01 +01:00
EstherLerouzic
bc71823bd0 docs: add a release-note section and update documentation for penalties and SI
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I12a5747df3cee6df79c24dd6261f7be17aa77fcf
2024-02-09 18:59:40 +01:00
EstherLerouzic
5481b93728 Fix frequency scaling for fiber
- wrong parameter was used in parameter
- error message could not read 0-dimensional arrey for 0 and -1 element
- add a test that makes use of the feature

Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: Id7f6d6766d5b91a4b9410ad23aaa5e472b8ebb6f
2024-01-16 09:10:31 +00:00
EstherLerouzic
05e301182d Change fedora-python in action
"Until version 0.4, this action always used the
latest fedora-python-tox image"
https://github.com/fedora-python/tox-github-action

So let's use one that supports python 3.8

Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: Ibf3e0baa715da70b4c2af6e2cde6efccfab50311
2024-01-15 20:02:13 +01:00
EstherLerouzic
47c89626e3 fix docs requirements
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I9d151b842a38380b0368e099c67957ec36b78250
2024-01-15 13:53:44 +01:00
EstherLerouzic
7a032a63b5 ci change allow_whitelist which is deprecated
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: Ic62050d351eb5bb2f8be2b8d9e0088bd965dc71d
2024-01-15 13:12:35 +01:00
EstherLerouzic
f195d5f496 fix: use ref power on transceiver to Roadm (or transceivers) links
The recent refactor removed a default pref in case of transceivers-OMS
(amplified links starting with a transceiver).
This resulted in a mismatch between input power during design
(default 0 forced in the function) and the design ref power using SI
power_dbm.

This change ensures that the same power is used for the input power
and for the design ref power, and avoid inconsistent gain computatiion.

The code has been using the same power input (SI power_dbm) to define the
power target out of a transceiver and the target out of amplifiers
(at the input of fibers). This will be changed in a future patch.

Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I610c8df19039bcf156a8ba77c79114b22913a538
2023-12-08 12:27:05 +01:00
Esther Le Rouzic
56569f866f Merge changes from topics "mixed-rate", "refactor_remove_pref"
* changes:
  Add a test on EOL
  add invocation test with the 3 equalization settings
  Add a test on out_voa optimisation function
  Clean a bit, add docstrings
  Remove Pref, and move ref_carrier definition
  Remove p_span0 from SI
  Remove p_spani from Pref
  Use design delta_p and gains instead of p_spani
  restore initial power sweep behaviour
  refactor cli to use a common design function
  Parametrize verbose in autodesign
  refactor build_network: create a separate function to add elements
  Computes reference input power in fiber during design
  Computes reference input power in ROADM during design
  Add a variable to hold delta_p even if gain mode is selected
  Add frequency range in default_edfa profile
  Add a test on gain mode behaviour
  Check element setting before and after propagation
  Correct design: apply saturation in all cases
  Add more tests on amp saturation
2023-12-04 16:09:37 +00:00
Esther Le Rouzic
bf1f293043 Merge "Add test in amplifier behaviour" 2023-12-04 16:08:14 +00:00
EstherLerouzic
d7c1a6b75e Add a test on EOL
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: Iddce655a64623a42cdaeaa2e8c269e3a737dd935
2023-11-20 17:07:53 +01:00
EstherLerouzic
c69c2a3af2 add invocation test with the 3 equalization settings
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I0aee8da7bbf71991c68e163c7188efe1ddf29ff9
2023-11-20 17:07:53 +01:00
EstherLerouzic
fb29d72906 Add a test on out_voa optimisation function
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I36d71d85e5837965f6d5ae47820506d06b3cb94e
2023-11-20 17:07:53 +01:00
EstherLerouzic
30a06da6b1 Clean a bit, add docstrings
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I8639d458ebb090761846387921f9da4fc65a9f64
2023-11-20 17:07:53 +01:00
EstherLerouzic
139c8cc1e7 Remove Pref, and move ref_carrier definition
Finally, ref_carrier is not meant to change after design since
it is the carrier used for design. So let's move its definition
to networks function. Only ROADM need the ref_carrier baud rate
so let's define a dedicated variable in ROADM to hold it.

Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: Ida7e42dd534a04c8df8792b44980f3fd2165ecb6
2023-11-20 17:07:53 +01:00
EstherLerouzic
7034d4c686 Remove p_span0 from SI
reference channel is defined during design. No need to convey it
anymore during propagation.

move target_pch_out_db definition to the design phase and change
its name to be consistent with what it contains (dbm)

Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I350e4557e8488a614674042de26152ab89b2d245
2023-11-20 17:07:53 +01:00
EstherLerouzic
10164495b9 Remove p_spani from Pref
next step: remove Pref

Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I7cc17253a2d7ab3fb42e3d07c1665991cffa6222
2023-11-20 17:07:53 +01:00
EstherLerouzic
87211b35e9 Use design delta_p and gains instead of p_spani
Remove the visualisation of the effective_pch in amp because actual
and target are the relevant ones. effective_pch was artificially
related to a mix of reference channel and noisy channel (mixed between
on the fly redesign but using actual ROADM equalisation which includes noise
in its actual loss).

the change does no more rely on the target power (which is rounded)
but on the designed gain, which is not rounded.

Propagations are slightly changed for openroadm simulations because of that.
(I verified)

The gain of amp was estimated on the fly with p_spni also in case of
RamanFiber preceding elements. removing p_spani requies that an estimation
of Raman gain be done during design.

This commit also adds this estimation.

Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I960b85e99f85a7d168ac5349e325c4928fa5673b
2023-11-20 17:07:46 +01:00
EstherLerouzic
e9f9ddb4d6 restore initial power sweep behaviour
if user define a delta_p that is reduced because of saturation,
then this initial setting is still kept for power sweep to be sure
that the full amplitude of sweep is used.

SI power = 0 dBm
max power amp1 = 20 dBm,
user_defined_delta_p set by user = 3
80 channels, so pch_max = 20 - 10log10(80) = 0.96 dBm
power_sweep -> power range [-3, 0] dBm

then for initial design,
   pref = 0 dBm
   computed_delta_p =
      min(pch_max, pref + user_defined_delta_p) - pref = 0.96

but for -3 power sweep
   pref = -3 dBm
   computed_delta_p =
      min(pch_max, pref + user_defined_delta_p) - pref =
      min(0.96,    -3 + 3) - (-3) = 3
   so the user defined delta_p is applied as much as possible

Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I8fd459c29aa9754ff9d4868af1d8be8642a31913
2023-11-20 11:10:07 +01:00
EstherLerouzic
8ea13bb4d6 refactor cli to use a common design function
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I029d8c7fc29b1e86e1e3b2b64933bae5da134226
2023-11-20 10:27:43 +01:00
EstherLerouzic
b45829d2df Parametrize verbose in autodesign
transmission-main-example and path-request-run functions implement an
on-the-fly redesign based on p_span_i.
Since we remove p_span_i from elements, we will need to properly call
redesign several times before each propagation, to keep the same
behaviour of these functions.

in this commit we simply enable the possibility to mute warnings.

Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I3aa3d8fc87325033ef69641078bdd7213e0409eb
2023-11-20 10:27:41 +01:00
EstherLerouzic
6ac3a517cf refactor build_network: create a separate function to add elements
separate function that adds element, from function that configure them

Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: Ica332223bdf7fc599cb007d7513d7cd62d9c5f9c
2023-11-20 10:25:07 +01:00
EstherLerouzic
2f2920a716 Computes reference input power in fiber during design
input power is computed at design time: so let's record it and
use it instead of p_span_i for reference channel fiber loss computation.
Note that this loss parameter is only used for visualisation purpose.

Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I16bd792bd6079ce521aafadcf5e21922aa3b4c81
2023-11-20 10:23:21 +01:00
EstherLerouzic
07fd89351b Computes reference input power in ROADM during design
input power is computed at design time: so let's record it and
use it instead of p_span_i for ROADM reference channel loss computation.
Note that this loss parameter is only used for visualisation purpose.
No impact on propagation.

Since this loss is computed for the reference channel used for
design, we need to record input power based on input degrees,
and indicate this information within the call function.

Note that this will be also usefull later on to implement ROADM
parameters

Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I64d510fc20df72f07158f400964d592d76dc0ce4
2023-11-20 10:23:21 +01:00
EstherLerouzic
7c60b000b5 Add a variable to hold delta_p even if gain mode is selected
Let's use a clean convention to hold values that are configured,
autodesigned or resulting from propagation.

- edfa.operational.delta_p: holds the value set by the user if any.
  This is needed in case of redesign for power sweep for example.
  It is never changed.
- edfa.delta_p:
  o if power_mode is true, records the value computed by the design.
      Applies user defined value except:
      If the user has set non possible values (eg leading to saturation),
      then the value is corrected at design phase.
      If the element is propagated for different conditions than
      design, for example leading to saturation,  then delta_p might be
      different than the value initially computed during design.
  o if power_mode is False, it is set to None
- edfa._delta_p: records the value computed during design whatever
  the power mode

Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I4e130a3abe0a5e3f6c057d89360e50531c168123
2023-11-20 10:23:21 +01:00
EstherLerouzic
537eb017b5 Add frequency range in default_edfa profile
This range is the property of amps and is independant from user propagation range.

Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: Ib89f1987910aa3121a3b8c859a0a785f7d5e27eb
2023-11-20 10:23:21 +01:00
EstherLerouzic
9c514e8086 Add a test on gain mode behaviour
This test checks that setting in gain mode forces amp to the gain settings
and ignores any power requirements. Change in SI in eqpt config and change
in req power (eg power sweep) should have no effect on the propagation.

Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: Iad826f30010fe3110d105b5206d99f502fbf98ff
2023-11-20 10:23:21 +01:00
EstherLerouzic
78efb6c650 Check element setting before and after propagation
In power mode, all elements design attributes should not change except
amplifiers' gain in case of power saturation.

Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I2fec00232c80dd395e4dec20ec531c9c2e127760
2023-11-20 10:23:18 +01:00
EstherLerouzic
3510d59250 Correct design: apply saturation in all cases
Previously saturation was not checked during design if amp type was set.
This commit also applies saturation for these amplifiers.

This changes some of the autodesign result (since range for selection
is changed). For example, this changes some of the gains, or type variety
of amplifier of test files.

The commit also removes one of the rounding in the design phase, and
applies rounding only for printing purpose.

It also adds minor refactor on a function

In order to keep power sweep behaviour in case of saturation, the saturation
check in amplifier element uses initial power targets set by user instead
of a possible autodesign delta_p result.

Note that gain_mode is unchanged: design in gain mode means that delta_p
is set to None during the build process, even if the user defined a value
in operational.delta_p.

Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: Idc5cfc8263cf678473acb6ec490207d9d6ba5c0a
2023-11-20 10:21:38 +01:00
EstherLerouzic
41d9d156a6 Add more tests on amp saturation
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: Ibba18bed646748d59cfe906b403a9b100c58bb7e
2023-11-20 10:21:35 +01:00
EstherLerouzic
e9d5e748e4 Add test in amplifier behaviour
Check that amp correctly applies saturation, when there is tilt.

Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I3e7623e9d5b28bdc12eae24766588645781c2827
2023-11-20 10:21:06 +01:00
48 changed files with 3968 additions and 495 deletions

View File

@@ -14,7 +14,7 @@ jobs:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
with: with:
fetch-depth: 0 fetch-depth: 0
- uses: fedora-python/tox-github-action@v0.4 - uses: fedora-python/tox-github-action@v37.0
with: with:
tox_env: ${{ matrix.tox_env }} tox_env: ${{ matrix.tox_env }}
dnf_install: ${{ matrix.dnf_install }} dnf_install: ${{ matrix.dnf_install }}
@@ -106,8 +106,7 @@ jobs:
with: with:
python-version: ${{ matrix.python_version }} python-version: ${{ matrix.python_version }}
- run: | - run: |
pip install -r tests/requirements.txt pip install --editable .[tests]
pip install --editable .
pytest -vv pytest -vv
strategy: strategy:
fail-fast: false fail-fast: false
@@ -136,8 +135,7 @@ jobs:
with: with:
python-version: ${{ matrix.python_version }} python-version: ${{ matrix.python_version }}
- run: | - run: |
pip install -r tests/requirements.txt pip install --editable .[tests]
pip install --editable .
pytest -vv pytest -vv
strategy: strategy:
fail-fast: false fail-fast: false

View File

@@ -1,5 +1,15 @@
version: 2
build: build:
image: latest os: ubuntu-22.04
tools:
python: "3.12"
python: python:
version: 3.8 install:
requirements_file: docs/requirements.txt - method: pip
path: .
extra_requirements:
- docs
sphinx:
configuration: docs/conf.py

View File

@@ -65,7 +65,7 @@ author = 'Telecom Infra Project - OOPT PSE Group'
# #
# This is also used if you do content translation via gettext catalogs. # This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases. # Usually you set "language" from the command line for these cases.
language = None language = 'en'
# List of patterns, relative to source directory, that match files and # List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files. # directories to ignore when looking for source files.
@@ -84,18 +84,11 @@ todo_include_todos = False
# The theme to use for HTML and HTML Help pages. See the documentation for # The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes. # a list of builtin themes.
# #
on_rtd = os.environ.get('READTHEDOCS') == 'True' html_theme = 'alabaster'
if on_rtd: html_theme_options = {
html_theme = 'default' 'logo': 'images/GNPy-logo.png',
html_theme_options = { 'logo_name': False,
'logo_only': True, }
}
else:
html_theme = 'alabaster'
html_theme_options = {
'logo': 'images/GNPy-logo.png',
'logo_name': False,
}
html_logo = 'images/GNPy-logo.png' html_logo = 'images/GNPy-logo.png'

View File

@@ -17,6 +17,7 @@ in real-world mesh optical networks. It is based on the Gaussian Noise Model.
about-project about-project
model model
gnpy-api gnpy-api
release-notes
Indices and tables Indices and tables
================== ==================

View File

@@ -180,25 +180,60 @@ used to determine the service list path feasibility when running the
The modes are defined as follows: The modes are defined as follows:
+----------------------+-----------+-----------------------------------------+ +----------------------------+-----------+-----------------------------------------+
| field | type | description | | field | type | description |
+======================+===========+=========================================+ +============================+===========+=========================================+
| ``format`` | (string) | a unique name to ID the mode | | ``format`` | (string) | a unique name to ID the mode |
+----------------------+-----------+-----------------------------------------+ +----------------------------+-----------+-----------------------------------------+
| ``baud_rate`` | (number) | in Hz | | ``baud_rate`` | (number) | in Hz |
+----------------------+-----------+-----------------------------------------+ +----------------------------+-----------+-----------------------------------------+
| ``OSNR`` | (number) | min required OSNR in 0.1nm (dB) | | ``OSNR`` | (number) | min required OSNR in 0.1nm (dB) |
+----------------------+-----------+-----------------------------------------+ +----------------------------+-----------+-----------------------------------------+
| ``bit_rate`` | (number) | in bit/s | | ``bit_rate`` | (number) | in bit/s |
+----------------------+-----------+-----------------------------------------+ +----------------------------+-----------+-----------------------------------------+
| ``roll_off`` | (number) | Pure number between 0 and 1. TX signal | | ``roll_off`` | (number) | Pure number between 0 and 1. TX signal |
| | | roll-off shape. Used by Raman-aware | | | | roll-off shape. Used by Raman-aware |
| | | simulation code. | | | | simulation code. |
+----------------------+-----------+-----------------------------------------+ +----------------------------+-----------+-----------------------------------------+
| ``tx_osnr`` | (number) | In dB. OSNR out from transponder. | | ``tx_osnr`` | (number) | In dB. OSNR out from transponder. |
+----------------------+-----------+-----------------------------------------+ +----------------------------+-----------+-----------------------------------------+
| ``cost`` | (number) | Arbitrary unit | | ``equalization_offset_db`` | (number) | In dB. Deviation from the per channel |
+----------------------+-----------+-----------------------------------------+ | | | equalization target in ROADM for this |
| | | type of transceiver. |
+----------------------------+-----------+-----------------------------------------+
| ``penalties`` | (list) | list of impairments as described in |
| | | impairment table. |
+----------------------------+-----------+-----------------------------------------+
| ``cost`` | (number) | Arbitrary unit |
+----------------------------+-----------+-----------------------------------------+
Penalties are linearly interpolated between given points and set to 'inf' outside interval.
The accumulated penalties are substracted to the path GSNR before comparing with the min required OSNR.
The penalties per impairment type are defined as a list of dict (impairment type - penalty values) as follows:
+-----------------------------+-----------+-----------------------------------------------+
| field | type | description |
+=============================+===========+===============================================+
| ``chromatic_dispersion`` or | (number) | In ps/nm/. Value of chromatic dispersion. |
| ``pdl`` or | | In dB. Value of polarization dependant loss. |
| ``pmd`` | (string) | In ps. Value of polarization mode dispersion. |
+-----------------------------+-----------+-----------------------------------------------+
| ``penalty_value`` | (number) | in dB. Penalty on the transceiver min OSNR |
| | | corresponding to the impairment level |
+-----------------------------+-----------+-----------------------------------------------+
for example:
.. code-block:: json
"penalties": [{
"chromatic_dispersion": 360000,
"penalty_value": 0.5
}, {
"pmd": 110,
"penalty_value": 0.5
}
]
ROADM ROADM
~~~~~ ~~~~~
@@ -441,6 +476,11 @@ SpectralInformation
~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~
GNPy requires a description of all channels that are propagated through the network. GNPy requires a description of all channels that are propagated through the network.
This block defines a reference channel (target input power in spans, nb of channels) which is used to design the network or correct the settings.
It may be updated with different options --power.
It also defines the channels to be propagated for the gnpy-transmission-example script unless a different definition is provided with ``--spectrum`` option.
Flexgrid channel partitioning is available since the 2.7 release via the extra ``--spectrum`` option. 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: In the simplest case, homogeneous channel allocation can be defined via the ``SpectralInformation`` construct which defines a spectrum of N identical carriers:
@@ -463,7 +503,8 @@ In the simplest case, homogeneous channel allocation can be defined via the ``Sp
+----------------------+-----------+-------------------------------------------+ +----------------------+-----------+-------------------------------------------+
| ``tx_osnr`` | (number) | In dB. OSNR out from transponder. | | ``tx_osnr`` | (number) | In dB. OSNR out from transponder. |
+----------------------+-----------+-------------------------------------------+ +----------------------+-----------+-------------------------------------------+
| ``power_dbm`` | (number) | Reference channel power, in dBm. | | ``power_dbm`` | (number) | In dBm. Target input power in spans to |
| | | be considered for the design |
| | | In gain mode | | | | In gain mode |
| | | (see spans/power_mode = false), if no | | | | (see spans/power_mode = false), if no |
| | | gain is set in an amplifier, auto-design | | | | gain is set in an amplifier, auto-design |

96
docs/release-notes.rst Normal file
View File

@@ -0,0 +1,96 @@
.. _release-notes:
Release change log
==================
Each release introduces some changes and new features.
v2.8
----
**Spectrum assignment**: requests can now support multiple slots.
The definition in service file supports multiple assignments (unchanged syntax):
.. code-block:: json
"effective-freq-slot": [
{
"N": 0,
"M": 4
}, {
"N": 50,
"M": 4
}
],
But in results, label-hop is now a list of slots and center frequency index:
.. code-block:: json
{
"path-route-object": {
"index": 4,
"label-hop": [
{
"N": 0,
"M": 4
}, {
"N": 50,
"M": 4
}
]
}
},
instead of
.. code-block:: json
{
"path-route-object": {
"index": 4,
"label-hop": {
"N": 0,
"M": 4
}
}
},
**change in display**: only warnings are displayed ; information are disabled and needs the -v (verbose)
option to be displayed on standard output.
**frequency scaling**: Chromatic dispersion, effective area, Raman Gain coefficient,
and nonlinear coefficient can now be defined with a scaling along frequency.
**power offset**: Power equalization now enables defining a power offset in transceiver library to represent
the deviation from the general equalisation strategy defined in ROADMs.
.. code-block:: json
"mode": [{
"format": "100G",
"baud_rate": 32.0e9,
"tx_osnr": 35.0,
"min_spacing": 50.0e9,
"cost": 1,
"OSNR": 10.0,
"bit_rate": 100.0e9,
"roll_off": 0.2,
"equalization_offset_db": 0.0
}, {
"format": "200G",
"baud_rate": 64.0e9,
"tx_osnr": 35.0,
"min_spacing": 75.0e9,
"cost": 1,
"OSNR": 13.0,
"bit_rate": 200.0e9,
"roll_off": 0.2,
"equalization_offset_db": 1.76
}
]
v2.7
----

View File

@@ -1,7 +0,0 @@
alabaster>=0.7.12,<1
docutils>=0.17.1,<1
myst-parser>=0.16.1,<1
Pygments>=2.11.2,<3
rstcheck
Sphinx>=4.4.0,<5
sphinxcontrib-bibtex>=2.4.1,<3

View File

@@ -258,6 +258,8 @@ class Roadm(_Node):
self.per_degree_pch_out_dbm = self.params.per_degree_pch_out_db 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_psd = self.params.per_degree_pch_psd
self.per_degree_pch_psw = self.params.per_degree_pch_psw self.per_degree_pch_psw = self.params.per_degree_pch_psw
self.ref_pch_in_dbm = {}
self.ref_carrier = None
@property @property
def to_json(self): def to_json(self):
@@ -302,8 +304,7 @@ class Roadm(_Node):
f' reference pch out (dBm): {self.ref_pch_out_dbm:.2f}', f' reference pch out (dBm): {self.ref_pch_out_dbm:.2f}',
f' actual pch out (dBm): {total_pch}']) f' actual pch out (dBm): {total_pch}'])
def get_roadm_target_power(self, ref_carrier: ReferenceCarrier = None, def get_roadm_target_power(self, spectral_info: SpectralInformation = None) -> Union[float, ndarray]:
spectral_info: SpectralInformation = None) -> Union[float, ndarray]:
"""Computes the power in dBm for a reference carrier or for a spectral information. """Computes the power in dBm for a reference carrier or for a spectral information.
power is computed based on equalization target. power is computed based on equalization target.
if spectral_info baud_rate is baud_rate = [32e9, 42e9, 64e9, 42e9, 32e9], and if spectral_info baud_rate is baud_rate = [32e9, 42e9, 64e9, 42e9, 32e9], and
@@ -325,22 +326,22 @@ class Roadm(_Node):
if self.target_pch_out_dbm is not None: if self.target_pch_out_dbm is not None:
return self.target_pch_out_dbm return self.target_pch_out_dbm
if self.target_psd_out_mWperGHz is not None: if self.target_psd_out_mWperGHz is not None:
return psd2powerdbm(self.target_psd_out_mWperGHz, ref_carrier.baud_rate) return psd2powerdbm(self.target_psd_out_mWperGHz, self.ref_carrier.baud_rate)
if self.target_out_mWperSlotWidth is not None: if self.target_out_mWperSlotWidth is not None:
return psd2powerdbm(self.target_out_mWperSlotWidth, ref_carrier.slot_width) return psd2powerdbm(self.target_out_mWperSlotWidth, self.ref_carrier.slot_width)
return None return None
def get_per_degree_ref_power(self, degree, ref_carrier): def get_per_degree_ref_power(self, degree):
"""Get the target power in dBm out of ROADM degree for the reference bandwidth """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 no equalization is defined on this degree use the ROADM level one.
""" """
if degree in self.per_degree_pch_out_dbm: if degree in self.per_degree_pch_out_dbm:
return self.per_degree_pch_out_dbm[degree] return self.per_degree_pch_out_dbm[degree]
elif degree in self.per_degree_pch_psd: elif degree in self.per_degree_pch_psd:
return psd2powerdbm(self.per_degree_pch_psd[degree], ref_carrier.baud_rate) return psd2powerdbm(self.per_degree_pch_psd[degree], self.ref_carrier.baud_rate)
elif degree in self.per_degree_pch_psw: elif degree in self.per_degree_pch_psw:
return psd2powerdbm(self.per_degree_pch_psw[degree], ref_carrier.slot_width) return psd2powerdbm(self.per_degree_pch_psw[degree], self.ref_carrier.slot_width)
return self.get_roadm_target_power(ref_carrier) return self.get_roadm_target_power()
def get_per_degree_power(self, degree, spectral_info): def get_per_degree_power(self, degree, spectral_info):
"""Get the target power in dBm out of ROADM degree for the spectral information """Get the target power in dBm out of ROADM degree for the spectral information
@@ -354,7 +355,7 @@ class Roadm(_Node):
return psd2powerdbm(self.per_degree_pch_psw[degree], spectral_info.slot_width) return psd2powerdbm(self.per_degree_pch_psw[degree], spectral_info.slot_width)
return self.get_roadm_target_power(spectral_info=spectral_info) return self.get_roadm_target_power(spectral_info=spectral_info)
def propagate(self, spectral_info, degree): def propagate(self, spectral_info, degree, from_degree):
"""Equalization targets are read from topology file if defined and completed with default """Equalization targets are read from topology file if defined and completed with default
definition of the library. definition of the library.
If the input power is lower than the target one, use the input power instead because If the input power is lower than the target one, use the input power instead because
@@ -365,20 +366,20 @@ class Roadm(_Node):
# TODO maybe add a minimum loss for the ROADM # TODO maybe add a minimum loss for the ROADM
# find the target power for the reference carrier # find the target power for the reference carrier
ref_per_degree_pch = self.get_per_degree_ref_power(degree, spectral_info.pref.ref_carrier) ref_per_degree_pch = self.get_per_degree_ref_power(degree)
# find the target powers for each signal carrier # find the target powers for each signal carrier
per_degree_pch = self.get_per_degree_power(degree, spectral_info=spectral_info) per_degree_pch = self.get_per_degree_power(degree, spectral_info=spectral_info)
# Definition of ref_pch_out_dbm for the reference channel: # 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 # Depending on propagation upstream from this ROADM, the input power might be smaller than
# the target power out configured for this ROADM degree's egress. Since ROADM does not amplify, # 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. # 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) # (TODO add a minimum loss for the ROADM crossing)
self.ref_pch_out_dbm = min(spectral_info.pref.p_spani, ref_per_degree_pch) self.ref_pch_out_dbm = min(self.ref_pch_in_dbm[from_degree], ref_per_degree_pch)
# Definition of effective_loss: # Definition of effective_loss:
# Optical power of carriers are equalized by the ROADM, so that the experienced loss is not the same for # 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 the reference carrier. # 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 self.ref_effective_loss = self.ref_pch_in_dbm[from_degree] - self.ref_pch_out_dbm
input_power = spectral_info.signal + spectral_info.nli + spectral_info.ase input_power = spectral_info.signal + spectral_info.nli + spectral_info.ase
target_power_per_channel = per_degree_pch + spectral_info.delta_pdb_per_channel target_power_per_channel = per_degree_pch + spectral_info.delta_pdb_per_channel
# Computation of the per channel target power according to equalization policy # Computation of the per channel target power according to equalization policy
@@ -407,17 +408,8 @@ class Roadm(_Node):
self.pch_out_dbm = watt2dbm(spectral_info.signal + spectral_info.nli + spectral_info.ase) self.pch_out_dbm = watt2dbm(spectral_info.signal + spectral_info.nli + spectral_info.ase)
self.propagated_labels = spectral_info.label self.propagated_labels = spectral_info.label
def update_pref(self, spectral_info): def __call__(self, spectral_info, degree, from_degree):
"""Update Reference power self.propagate(spectral_info, degree=degree, from_degree=from_degree)
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)
self.update_pref(spectral_info)
return spectral_info return spectral_info
@@ -451,13 +443,8 @@ class Fused(_Node):
def propagate(self, spectral_info): def propagate(self, spectral_info):
spectral_info.apply_attenuation_db(self.loss) spectral_info.apply_attenuation_db(self.loss)
def update_pref(self, spectral_info):
spectral_info.pref = spectral_info.pref._replace(p_span0=spectral_info.pref.p_span0,
p_spani=spectral_info.pref.p_spani - self.loss)
def __call__(self, spectral_info): def __call__(self, spectral_info):
self.propagate(spectral_info) self.propagate(spectral_info)
self.update_pref(spectral_info)
return spectral_info return spectral_info
@@ -482,6 +469,7 @@ class Fiber(_Node):
f"({1e-3 * self.params.length} km), boundaries excluded.") f"({1e-3 * self.params.length} km), boundaries excluded.")
self.lumped_losses = db2lin(- lumped_losses_power) # [linear units] self.lumped_losses = db2lin(- lumped_losses_power) # [linear units]
self.z_lumped_losses = array(z_lumped_losses) * 1e3 # [m] self.z_lumped_losses = array(z_lumped_losses) * 1e3 # [m]
self.ref_pch_in_dbm = None
@property @property
def to_json(self): def to_json(self):
@@ -527,10 +515,17 @@ class Fiber(_Node):
interpolation = interp1d(ref_frequency, parameter)(spectrum_frequency) interpolation = interp1d(ref_frequency, parameter)(spectrum_frequency)
return interpolation return interpolation
except ValueError: except ValueError:
try:
start = spectrum_frequency[0]
stop = spectrum_frequency[-1]
except IndexError:
# when frequency is a 0-dimensionnal array
start = spectrum_frequency
stop = spectrum_frequency
raise SpectrumError('The spectrum bandwidth exceeds the frequency interval used to define the fiber ' raise SpectrumError('The spectrum bandwidth exceeds the frequency interval used to define the fiber '
f'{name} in "{type(self).__name__} {self.uid}".' f'{name} in "{type(self).__name__} {self.uid}".'
f'\nSpectrum f_min-f_max: {round(spectrum_frequency[0] * 1e-12, 2)}-' f'\nSpectrum f_min-f_max: {round(start * 1e-12, 2)}-'
f'{round(spectrum_frequency[-1] * 1e-12, 2)}' f'{round(stop * 1e-12, 2)}'
f'\n{name} f_min-f_max: {round(ref_frequency[0] * 1e-12, 2)}-' f'\n{name} f_min-f_max: {round(ref_frequency[0] * 1e-12, 2)}-'
f'{round(ref_frequency[-1] * 1e-12, 2)}') f'{round(ref_frequency[-1] * 1e-12, 2)}')
@@ -675,21 +670,16 @@ class Fiber(_Node):
self.pch_out_dbm = watt2dbm(spectral_info.signal + spectral_info.nli + spectral_info.ase) self.pch_out_dbm = watt2dbm(spectral_info.signal + spectral_info.nli + spectral_info.ase)
self.propagated_labels = spectral_info.label 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
# because of Raman gain. In order to correctly update pref, we need the resulting loss:
# power_out - power_in. We use the total signal power (sum on all channels) to compute
# this loss, because pref is a noiseless reference.
loss = round(lin2db(self._psig_in / sum(spectral_info.signal)), 2)
self.pch_out_db = spectral_info.pref.p_spani - loss
spectral_info.pref = spectral_info.pref._replace(p_span0=spectral_info.pref.p_span0,
p_spani=self.pch_out_db)
def __call__(self, spectral_info): def __call__(self, spectral_info):
# _psig_in records the total signal power of the spectral information before propagation. # _psig_in records the total signal power of the spectral information before propagation.
self._psig_in = sum(spectral_info.signal) self._psig_in = sum(spectral_info.signal)
self.propagate(spectral_info) self.propagate(spectral_info)
self.update_pref(spectral_info) # In case of Raman, the resulting loss of the fiber is not equivalent to self.loss
# because of Raman gain. The resulting loss is:
# power_out - power_in. We use the total signal power (sum on all channels) to compute
# this loss.
loss = round(lin2db(self._psig_in / sum(spectral_info.signal)), 2)
self.pch_out_db = self.ref_pch_in_dbm - loss
return spectral_info return spectral_info
@@ -771,12 +761,19 @@ class Edfa(_Node):
self.pin_db = None self.pin_db = None
self.nch = None self.nch = None
self.pout_db = None self.pout_db = None
self.target_pch_out_db = None self.target_pch_out_dbm = None
self.effective_pch_out_db = None self.effective_pch_out_db = None
self.passive = False self.passive = False
self.att_in = None self.att_in = None
self.effective_gain = self.operational.gain_target self.effective_gain = self.operational.gain_target
self.delta_p = self.operational.delta_p # delta P with Pref (power swwep) in power mode # self.operational.delta_p is defined by user for reference channel
# self.delta_p is set with self.operational.delta_p, but it may be changed during design:
# - if operational.delta_p is None, self.delta_p is computed at design phase
# - if operational.delta_p can not be applied because of saturation, self.delta_p is recomputed
# - if power_mode is False, then it is set to None
self.delta_p = self.operational.delta_p
# self._delta_p contains computed delta_p during design even if power_mode is False
self._delta_p = None
self.tilt_target = self.operational.tilt_target self.tilt_target = self.operational.tilt_target
self.out_voa = self.operational.out_voa self.out_voa = self.operational.out_voa
self.propagated_labels = [""] self.propagated_labels = [""]
@@ -823,9 +820,10 @@ class Edfa(_Node):
f' pad att_in (dB): {self.att_in:.2f}', f' pad att_in (dB): {self.att_in:.2f}',
f' Power In (dBm): {self.pin_db:.2f}', f' Power In (dBm): {self.pin_db:.2f}',
f' Power Out (dBm): {self.pout_db:.2f}', f' Power Out (dBm): {self.pout_db:.2f}',
f' Delta_P (dB): ' + (f'{self.delta_p:.2f}' if self.delta_p is not None else 'None'), ' Delta_P (dB): ' + (f'{self.delta_p:.2f}'
f' target pch (dBm): ' + (f'{self.target_pch_out_db:.2f}' if self.target_pch_out_db is not None else 'None'), if self.delta_p is not None else 'None'),
f' effective pch (dBm): {self.effective_pch_out_db:.2f}', ' target pch (dBm): ' + (f'{self.target_pch_out_dbm:.2f}'
if self.target_pch_out_dbm is not None else 'None'),
f' actual pch out (dBm): {total_pch}', f' actual pch out (dBm): {total_pch}',
f' output VOA (dB): {self.out_voa:.2f}']) f' output VOA (dB): {self.out_voa:.2f}'])
@@ -853,20 +851,12 @@ class Edfa(_Node):
# For now, with homogeneous spectrum, we can calculate it as the difference between neighbouring channels. # For now, with homogeneous spectrum, we can calculate it as the difference between neighbouring channels.
self.slot_width = self.channel_freq[1] - self.channel_freq[0] self.slot_width = self.channel_freq[1] - self.channel_freq[0]
"""in power mode: delta_p is defined and can be used to calculate the power target
This power target is used calculate the amplifier gain"""
pref = spectral_info.pref
if self.delta_p is not None:
self.target_pch_out_db = round(self.delta_p + pref.p_span0, 2)
self.effective_gain = self.target_pch_out_db - pref.p_spani
"""check power saturation and correct effective gain & power accordingly:""" """check power saturation and correct effective gain & power accordingly:"""
# Compute the saturation accounting for actual power at the input of the amp # Compute the saturation accounting for actual power at the input of the amp
self.effective_gain = min( self.effective_gain = min(
self.effective_gain, self.effective_gain,
self.params.p_max - self.pin_db self.params.p_max - self.pin_db
) )
self.effective_pch_out_db = round(pref.p_spani + self.effective_gain, 2)
"""check power saturation and correct target_gain accordingly:""" """check power saturation and correct target_gain accordingly:"""
self.nf = self._calc_nf() self.nf = self._calc_nf()
@@ -1102,12 +1092,6 @@ class Edfa(_Node):
self.pch_out_dbm = watt2dbm(spectral_info.signal + spectral_info.nli + spectral_info.ase) self.pch_out_dbm = watt2dbm(spectral_info.signal + spectral_info.nli + spectral_info.ase)
self.propagated_labels = spectral_info.label 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=spectral_info.pref.p_spani + self.effective_gain - self.out_voa)
def __call__(self, spectral_info): def __call__(self, spectral_info):
self.propagate(spectral_info) self.propagate(spectral_info)
self.update_pref(spectral_info)
return spectral_info return spectral_info

View File

@@ -45,15 +45,6 @@ class Channel(
""" """
class Pref(namedtuple('Pref', 'p_span0, p_spani, ref_carrier')):
"""noiseless reference power in dBm:
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 SpectralInformation(object):
"""Class containing the parameters of the entire WDM comb. """Class containing the parameters of the entire WDM comb.
@@ -61,7 +52,7 @@ class SpectralInformation(object):
def __init__(self, frequency: array, baud_rate: array, slot_width: array, signal: array, nli: array, ase: array, 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, latency: array, roll_off: array, chromatic_dispersion: array, pmd: array, pdl: array, latency: array,
delta_pdb_per_channel: array, tx_osnr: array, ref_power: Pref, label: array): delta_pdb_per_channel: array, tx_osnr: array, label: array):
indices = argsort(frequency) indices = argsort(frequency)
self._frequency = frequency[indices] self._frequency = frequency[indices]
self._df = outer(ones(frequency.shape), frequency) - outer(frequency, ones(frequency.shape)) self._df = outer(ones(frequency.shape), frequency) - outer(frequency, ones(frequency.shape))
@@ -89,18 +80,8 @@ class SpectralInformation(object):
self._latency = latency[indices] self._latency = latency[indices]
self._delta_pdb_per_channel = delta_pdb_per_channel[indices] self._delta_pdb_per_channel = delta_pdb_per_channel[indices]
self._tx_osnr = tx_osnr[indices] self._tx_osnr = tx_osnr[indices]
self._pref = ref_power
self._label = label[indices] self._label = label[indices]
@property
def pref(self):
"""Instance of gnpy.info.Pref"""
return self._pref
@pref.setter
def pref(self, pref: Pref):
self._pref = pref
@property @property
def frequency(self): def frequency(self):
return self._frequency return self._frequency
@@ -237,12 +218,6 @@ class SpectralInformation(object):
def __add__(self, other: SpectralInformation): def __add__(self, other: SpectralInformation):
try: 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), return SpectralInformation(frequency=append(self.frequency, other.frequency),
slot_width=append(self.slot_width, other.slot_width), slot_width=append(self.slot_width, other.slot_width),
signal=append(self.signal, other.signal), nli=append(self.nli, other.nli), signal=append(self.signal, other.signal), nli=append(self.nli, other.nli),
@@ -257,13 +232,11 @@ class SpectralInformation(object):
delta_pdb_per_channel=append(self.delta_pdb_per_channel, delta_pdb_per_channel=append(self.delta_pdb_per_channel,
other.delta_pdb_per_channel), other.delta_pdb_per_channel),
tx_osnr=append(self.tx_osnr, other.tx_osnr), 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)) label=append(self.label, other.label))
except SpectrumError: except SpectrumError:
raise SpectrumError('Spectra cannot be summed: channels overlapping.') raise SpectrumError('Spectra cannot be summed: channels overlapping.')
def _replace(self, carriers):
def _replace(self, carriers, pref):
self.chromatic_dispersion = array([c.chromatic_dispersion for c in carriers]) self.chromatic_dispersion = array([c.chromatic_dispersion for c in carriers])
self.pmd = array([c.pmd for c in carriers]) self.pmd = array([c.pmd for c in carriers])
self.pdl = array([c.pdl for c in carriers]) self.pdl = array([c.pdl for c in carriers])
@@ -271,7 +244,6 @@ class SpectralInformation(object):
self.signal = array([c.power.signal for c in carriers]) self.signal = array([c.power.signal for c in carriers])
self.nli = array([c.power.nli for c in carriers]) self.nli = array([c.power.nli for c in carriers])
self.ase = array([c.power.ase for c in carriers]) self.ase = array([c.power.ase for c in carriers])
self.pref = pref
return self return self
@@ -286,7 +258,6 @@ def create_arbitrary_spectral_information(frequency: Union[ndarray, Iterable, fl
pmd: Union[float, ndarray, Iterable] = 0., pmd: Union[float, ndarray, Iterable] = 0.,
pdl: Union[float, ndarray, Iterable] = 0., pdl: Union[float, ndarray, Iterable] = 0.,
latency: Union[float, ndarray, Iterable] = 0., latency: Union[float, ndarray, Iterable] = 0.,
ref_power: Pref = None,
label: Union[str, ndarray, Iterable] = None): label: Union[str, ndarray, Iterable] = None):
"""This is just a wrapper around the SpectralInformation.__init__() that simplifies the creation of """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.""" a non-uniform spectral information with NLI and ASE powers set to zero."""
@@ -313,8 +284,7 @@ def create_arbitrary_spectral_information(frequency: Union[ndarray, Iterable, fl
chromatic_dispersion=chromatic_dispersion, chromatic_dispersion=chromatic_dispersion,
pmd=pmd, pdl=pdl, latency=latency, pmd=pmd, pdl=pdl, latency=latency,
delta_pdb_per_channel=delta_pdb_per_channel, delta_pdb_per_channel=delta_pdb_per_channel,
tx_osnr=tx_osnr, tx_osnr=tx_osnr, label=label)
ref_power=ref_power, label=label)
except ValueError as e: except ValueError as e:
if 'could not broadcast' in str(e): if 'could not broadcast' in str(e):
raise SpectrumError('Dimension mismatch in input fields.') raise SpectrumError('Dimension mismatch in input fields.')
@@ -322,31 +292,24 @@ def create_arbitrary_spectral_information(frequency: Union[ndarray, Iterable, fl
raise raise
def create_input_spectral_information(f_min, f_max, roll_off, baud_rate, power, spacing, tx_osnr, delta_pdb=0, def create_input_spectral_information(f_min, f_max, roll_off, baud_rate, power, spacing, tx_osnr, delta_pdb=0):
ref_carrier=None):
"""Creates a fixed slot width spectral information with flat power. """Creates a fixed slot width spectral information with flat power.
all arguments are scalar values""" all arguments are scalar values"""
number_of_channels = automatic_nch(f_min, f_max, spacing) number_of_channels = automatic_nch(f_min, f_max, spacing)
frequency = [(f_min + spacing * i) for i in range(1, number_of_channels + 1)] 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 = delta_pdb * ones(number_of_channels) delta_pdb_per_channel = delta_pdb * ones(number_of_channels)
label = [f'{baud_rate * 1e-9 :.2f}G' for i in range(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, return create_arbitrary_spectral_information(frequency, slot_width=spacing, signal=power, baud_rate=baud_rate,
roll_off=roll_off, delta_pdb_per_channel=delta_pdb_per_channel, roll_off=roll_off, delta_pdb_per_channel=delta_pdb_per_channel,
tx_osnr=tx_osnr, tx_osnr=tx_osnr, label=label)
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, def carriers_to_spectral_information(initial_spectrum: dict[float, Carrier],
ref_carrier: ReferenceCarrier) -> SpectralInformation: power: float) -> SpectralInformation:
"""Initial spectrum is a dict with key = carrier frequency, and value a Carrier object. """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, :param initial_spectrum: indexed by frequency in Hz, with power offset (delta_pdb), baudrate, slot width,
tx_osnr and roll off. tx_osnr and roll off.
:param power: power of the request :param power: power of the request
:param ref_carrier: reference carrier (baudrate) used for the reference channel
""" """
frequency = list(initial_spectrum.keys()) frequency = list(initial_spectrum.keys())
signal = [power * db2lin(c.delta_pdb) for c in initial_spectrum.values()] signal = [power * db2lin(c.delta_pdb) for c in initial_spectrum.values()]
@@ -357,12 +320,9 @@ def carriers_to_spectral_information(initial_spectrum: dict[float, Carrier], pow
tx_osnr = [c.tx_osnr 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()] label = [c.label for c in initial_spectrum.values()]
p_span0 = watt2dbm(power) p_span0 = watt2dbm(power)
p_spani = watt2dbm(power)
return create_arbitrary_spectral_information(frequency=frequency, signal=signal, baud_rate=baud_rate, return create_arbitrary_spectral_information(frequency=frequency, signal=signal, baud_rate=baud_rate,
slot_width=slot_width, roll_off=roll_off, slot_width=slot_width, roll_off=roll_off,
delta_pdb_per_channel=delta_pdb_per_channel, tx_osnr=tx_osnr, 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) label=label)

View File

@@ -8,15 +8,17 @@ gnpy.core.network
Working with networks which consist of network elements Working with networks which consist of network elements
""" """
from copy import deepcopy
from operator import attrgetter from operator import attrgetter
from collections import namedtuple from collections import namedtuple
from logging import getLogger from logging import getLogger
from gnpy.core import elements from gnpy.core import elements
from gnpy.core.exceptions import ConfigurationError, NetworkTopologyError from gnpy.core.exceptions import ConfigurationError, NetworkTopologyError
from gnpy.core.utils import round2float, convert_length from gnpy.core.utils import round2float, convert_length, psd2powerdbm, lin2db, watt2dbm, dbm2watt
from gnpy.core.info import ReferenceCarrier from gnpy.core.info import ReferenceCarrier, create_input_spectral_information
from gnpy.tools.json_io import Amp from gnpy.tools import json_io
from gnpy.core.parameters import SimParams
logger = getLogger(__name__) logger = getLogger(__name__)
@@ -38,7 +40,7 @@ def edfa_nf(gain_target, variety_type, equipment):
return amp._calc_nf(True) return amp._calc_nf(True)
def select_edfa(raman_allowed, gain_target, power_target, equipment, uid, restrictions=None): def select_edfa(raman_allowed, gain_target, power_target, equipment, uid, restrictions=None, verbose=True):
"""amplifer selection algorithm """amplifer selection algorithm
@Orange Jean-Luc Augé @Orange Jean-Luc Augé
""" """
@@ -61,15 +63,8 @@ def select_edfa(raman_allowed, gain_target, power_target, equipment, uid, restri
# power attribut include power AND gain limitations # power attribut include power AND gain limitations
edfa_list = [Edfa_list( edfa_list = [Edfa_list(
variety=edfa_variety, variety=edfa_variety,
power=min( power=min(pin + edfa.gain_flatmax + TARGET_EXTENDED_GAIN, edfa.p_max) - power_target,
pin gain_min=gain_target + 3 - edfa.gain_min,
+ edfa.gain_flatmax
+ TARGET_EXTENDED_GAIN,
edfa.p_max
)
- power_target,
gain_min=gain_target + 3
- edfa.gain_min,
nf=edfa_nf(gain_target, edfa_variety, equipment)) nf=edfa_nf(gain_target, edfa_variety, equipment))
for edfa_variety, edfa in edfa_dict.items() for edfa_variety, edfa in edfa_dict.items()
if ((edfa.allowed_for_design or restrictions is not None) and not edfa.raman)] if ((edfa.allowed_for_design or restrictions is not None) and not edfa.raman)]
@@ -78,15 +73,8 @@ def select_edfa(raman_allowed, gain_target, power_target, equipment, uid, restri
# do not allow extended gain min for Raman # do not allow extended gain min for Raman
raman_list = [Edfa_list( raman_list = [Edfa_list(
variety=edfa_variety, variety=edfa_variety,
power=min( power=min(pin + edfa.gain_flatmax + TARGET_EXTENDED_GAIN, edfa.p_max) - power_target,
pin gain_min=gain_target - edfa.gain_min,
+ edfa.gain_flatmax
+ TARGET_EXTENDED_GAIN,
edfa.p_max
)
- power_target,
gain_min=gain_target
- edfa.gain_min,
nf=edfa_nf(gain_target, edfa_variety, equipment)) nf=edfa_nf(gain_target, edfa_variety, equipment))
for edfa_variety, edfa in edfa_dict.items() for edfa_variety, edfa in edfa_dict.items()
if (edfa.allowed_for_design and edfa.raman)] \ if (edfa.allowed_for_design and edfa.raman)] \
@@ -110,9 +98,10 @@ def select_edfa(raman_allowed, gain_target, power_target, equipment, uid, restri
please increase span fiber padding') please increase span fiber padding')
else: else:
# TODO: convert to logging # TODO: convert to logging
logger.warning(f'\n\tWARNING: target gain in node {uid} is below all available amplifiers min gain: ' if verbose:
+ '\n\tamplifier input padding will be assumed, consider increase span fiber padding ' logger.warning(f'\n\tWARNING: target gain in node {uid} is below all available amplifiers min gain: '
+ 'instead.\n') + '\n\tamplifier input padding will be assumed, consider increase span fiber padding '
+ 'instead.\n')
acceptable_gain_min_list = edfa_list acceptable_gain_min_list = edfa_list
# filter on gain+power limitation: # filter on gain+power limitation:
@@ -132,30 +121,34 @@ def select_edfa(raman_allowed, gain_target, power_target, equipment, uid, restri
# =>chose the amp with the best NF among the acceptable ones: # =>chose the amp with the best NF among the acceptable ones:
selected_edfa = min(acceptable_power_list, key=attrgetter('nf')) # filter on NF selected_edfa = min(acceptable_power_list, key=attrgetter('nf')) # filter on NF
# check what are the gain and power limitations of this amp # check what are the gain and power limitations of this amp
power_reduction = round(min(selected_edfa.power, 0), 2) power_reduction = min(selected_edfa.power, 0)
if power_reduction < -0.5: if power_reduction < -0.5 and verbose:
logger.warning(f'\n\tWARNING: target gain and power in node {uid}\n' logger.warning(f'\n\tWARNING: target gain and power in node {uid}\n'
+ '\tis beyond all available amplifiers capabilities and/or extended_gain_range:\n' + '\tis beyond all available amplifiers capabilities and/or extended_gain_range:\n'
+ f'\ta power reduction of {power_reduction} is applied\n') + f'\ta power reduction of {round(power_reduction, 2)} is applied\n')
return selected_edfa.variety, power_reduction return selected_edfa.variety, power_reduction
def target_power(network, node, equipment): # get_fiber_dp def target_power(network, node, equipment): # get_fiber_dp
"""Computes target power using J. -L. Auge, V. Curri and E. Le Rouzic,
Open Design for Multi-Vendor Optical Networks, OFC 2019.
equation 4
"""
if isinstance(node, elements.Roadm): if isinstance(node, elements.Roadm):
return 0 return 0
SPAN_LOSS_REF = 20 SPAN_LOSS_REF = 20
POWER_SLOPE = 0.3 POWER_SLOPE = 0.3
dp_range = list(equipment['Span']['default'].delta_power_range_db) dp_range = list(equipment['Span']['default'].delta_power_range_db)
node_loss = span_loss(network, node) node_loss = span_loss(network, node, equipment)
try: try:
dp = round2float((node_loss - SPAN_LOSS_REF) * POWER_SLOPE, dp_range[2]) dp = round2float((node_loss - SPAN_LOSS_REF) * POWER_SLOPE, dp_range[2])
dp = max(dp_range[0], dp) dp = max(dp_range[0], dp)
dp = min(dp_range[1], dp) dp = min(dp_range[1], dp)
except IndexError: except IndexError:
raise ConfigurationError(f'invalid delta_power_range_db definition in eqpt_config[Span]' raise ConfigurationError('invalid delta_power_range_db definition in eqpt_config[Span]'
f'delta_power_range_db: [lower_bound, upper_bound, step]') 'delta_power_range_db: [lower_bound, upper_bound, step]')
return dp return dp
@@ -194,12 +187,64 @@ def next_node_generator(network, node):
yield from next_node_generator(network, next_node) yield from next_node_generator(network, next_node)
def span_loss(network, node): def estimate_raman_gain(node, equipment):
"""If node is RamanFiber, then estimate the possible Raman gain if any
for this purpose propagate a fake signal in a copy.
to be accurate the nb of channel should be the same as in SI, but this increases computation time
"""
f_min = equipment['SI']['default'].f_min
f_max = equipment['SI']['default'].f_max
roll_off = equipment['SI']['default'].roll_off
baud_rate = equipment['SI']['default'].baud_rate
power_dbm = equipment['SI']['default'].power_dbm
power = dbm2watt(equipment['SI']['default'].power_dbm)
spacing = equipment['SI']['default'].spacing
tx_osnr = equipment['SI']['default'].tx_osnr
sim_params = {
"raman_params": {
"flag": True,
"result_spatial_resolution": 10e3,
"solver_spatial_resolution": 50
},
"nli_params": {
"method": "ggn_spectrally_separated",
"dispersion_tolerance": 1,
"phase_shift_tolerance": 0.1,
"computed_channels": [1, 18, 37, 56, 75]
}
}
if isinstance(node, elements.RamanFiber):
# in order to take into account gain generated in RamanFiber, propagate in the RamanFiber with
# SI reference channel.
spectral_info_input = create_input_spectral_information(f_min=f_min, f_max=f_max, roll_off=roll_off,
baud_rate=baud_rate, power=power, spacing=spacing,
tx_osnr=tx_osnr)
n_copy = deepcopy(node)
# need to set ref_pch_in_dbm in order to correctly run propagate of the element, because this
# setting has not yet been done by autodesign
n_copy.ref_pch_in_dbm = power_dbm
SimParams.set_params(sim_params)
pin = watt2dbm(sum(spectral_info_input.signal))
spectral_info_out = n_copy(spectral_info_input)
pout = watt2dbm(sum(spectral_info_out.signal))
estimated_gain = pout - pin + node.loss
return round(estimated_gain, 2)
else:
return 0.0
def span_loss(network, node, equipment):
"""Total loss of a span (Fiber and Fused nodes) which contains the given node""" """Total loss of a span (Fiber and Fused nodes) which contains the given node"""
loss = node.loss if node.passive else 0 loss = node.loss if node.passive else 0
loss += sum(n.loss for n in prev_node_generator(network, node)) loss += sum(n.loss for n in prev_node_generator(network, node))
loss += sum(n.loss for n in next_node_generator(network, node)) loss += sum(n.loss for n in next_node_generator(network, node))
return loss # add the possible Raman gain
gain = estimate_raman_gain(node, equipment)
gain += sum(estimate_raman_gain(n, equipment) for n in prev_node_generator(network, node))
gain += sum(estimate_raman_gain(n, equipment) for n in next_node_generator(network, node))
return loss - gain
def find_first_node(network, node): def find_first_node(network, node):
@@ -236,21 +281,26 @@ def set_amplifier_voa(amp, power_target, power_mode):
amp.out_voa = voa amp.out_voa = voa
def set_egress_amplifier(network, this_node, equipment, pref_ch_db, pref_total_db): def set_egress_amplifier(network, this_node, equipment, pref_ch_db, pref_total_db, verbose):
"""this node can be a transceiver or a ROADM (same function called in both cases)""" """This node can be a transceiver or a ROADM (same function called in both cases).
go through each link staring from this_node until next Roadm or Transceiver and
set gain and delta_p according to configurations set by user.
power_mode = True, set amplifiers delta_p and effective_gain
power_mode = False, set amplifiers effective_gain and ignore delta_p config: set it to None
"""
power_mode = equipment['Span']['default'].power_mode 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)) next_oms = (n for n in network.successors(this_node) if not isinstance(n, elements.Transceiver))
for oms in next_oms: for oms in next_oms:
# go through all the OMS departing from the ROADM # go through all the OMS departing from the ROADM
prev_node = this_node prev_node = this_node
node = oms node = oms
if isinstance(this_node, elements.Transceiver): if isinstance(this_node, elements.Transceiver):
this_node_out_power = 0.0 # default value if this_node is a transceiver # for the time being use the same power for the target of roadms and for transceivers
# TODO: This should be changed when introducing a power parameter dedicated to transceivers
this_node_out_power = pref_ch_db
if isinstance(this_node, elements.Roadm): if isinstance(this_node, elements.Roadm):
# get target power out from ROADM for the reference carrier based on equalization settings # 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) this_node_out_power = this_node.get_per_degree_ref_power(degree=node.uid)
# use the target power on this degree # use the target power on this degree
prev_dp = this_node_out_power - pref_ch_db prev_dp = this_node_out_power - pref_ch_db
dp = prev_dp dp = prev_dp
@@ -259,20 +309,18 @@ def set_egress_amplifier(network, this_node, equipment, pref_ch_db, pref_total_d
visited_nodes = [] visited_nodes = []
while not (isinstance(node, elements.Roadm) or isinstance(node, elements.Transceiver)): while not (isinstance(node, elements.Roadm) or isinstance(node, elements.Transceiver)):
# go through all nodes in the OMS (loop until next Roadm instance) # go through all nodes in the OMS (loop until next Roadm instance)
try: next_node = get_next_node(node, network)
next_node = next(network.successors(node))
except StopIteration:
raise NetworkTopologyError(f'{type(node).__name__} {node.uid} is not properly connected, please check network topology')
visited_nodes.append(node) visited_nodes.append(node)
if next_node in visited_nodes: if next_node in visited_nodes:
raise NetworkTopologyError(f'Loop detected for {type(node).__name__} {node.uid}, please check network topology') raise NetworkTopologyError(f'Loop detected for {type(node).__name__} {node.uid}, '
+ 'please check network topology')
if isinstance(node, elements.Edfa): if isinstance(node, elements.Edfa):
node_loss = span_loss(network, prev_node) node_loss = span_loss(network, prev_node, equipment)
voa = node.out_voa if node.out_voa else 0 voa = node.out_voa if node.out_voa else 0
if node.delta_p is None: if node.operational.delta_p is None:
dp = target_power(network, next_node, equipment) + voa dp = target_power(network, next_node, equipment) + voa
else: else:
dp = node.delta_p dp = node.operational.delta_p
if node.effective_gain is None or power_mode: if node.effective_gain is None or power_mode:
gain_target = node_loss + dp - prev_dp + prev_voa gain_target = node_loss + dp - prev_dp + prev_voa
else: # gain mode with effective_gain else: # gain mode with effective_gain
@@ -299,12 +347,22 @@ def set_egress_amplifier(network, this_node, equipment, pref_ch_db, pref_total_d
restrictions = next_node.restrictions['preamp_variety_list'] restrictions = next_node.restrictions['preamp_variety_list']
else: else:
restrictions = None restrictions = None
edfa_variety, power_reduction = select_edfa(raman_allowed, gain_target, power_target, equipment, node.uid, restrictions) edfa_variety, power_reduction = select_edfa(raman_allowed, gain_target, power_target, equipment,
node.uid, restrictions, verbose)
extra_params = equipment['Edfa'][edfa_variety] extra_params = equipment['Edfa'][edfa_variety]
node.params.update_params(extra_params.__dict__) node.params.update_params(extra_params.__dict__)
dp += power_reduction dp += power_reduction
gain_target += power_reduction gain_target += power_reduction
else: else:
# Check power saturation also in this case
p_max = equipment['Edfa'][node.params.type_variety].p_max
if power_mode:
power_reduction = min(0, p_max - (pref_total_db + dp))
else:
pout = pref_total_db + prev_dp - node_loss - prev_voa + gain_target
power_reduction = min(0, p_max - pout)
dp += power_reduction
gain_target += power_reduction
if node.params.raman and not raman_allowed: if node.params.raman and not raman_allowed:
if isinstance(prev_node, elements.Fiber): if isinstance(prev_node, elements.Fiber):
logger.warning(f'\n\tWARNING: raman is used in node {node.uid}\n ' logger.warning(f'\n\tWARNING: raman is used in node {node.uid}\n '
@@ -315,17 +373,32 @@ def set_egress_amplifier(network, this_node, equipment, pref_ch_db, pref_total_d
# if variety is imposed by user, and if the gain_target (computed or imposed) is also above # if variety is imposed by user, and if the gain_target (computed or imposed) is also above
# variety max gain + extended range, then warn that gain > max_gain + extended range # variety max gain + extended range, then warn that gain > max_gain + extended range
if gain_target - equipment['Edfa'][node.params.type_variety].gain_flatmax - \ if gain_target - equipment['Edfa'][node.params.type_variety].gain_flatmax - \
equipment['Span']['default'].target_extended_gain > 1e-2: equipment['Span']['default'].target_extended_gain > 1e-2 and verbose:
# 1e-2 to allow a small margin according to round2float min step # 1e-2 to allow a small margin according to round2float min step
logger.warning(f'\n\tWARNING: effective gain in Node {node.uid}\n' logger.warning(f'\n\tWARNING: effective gain in Node {node.uid}\n'
+ f'\tis above user specified amplifier {node.params.type_variety}\n' + f'\tis above user specified amplifier {node.params.type_variety}\n'
+ '\tmax flat gain: ' + '\tmax flat gain: '
+ f'{equipment["Edfa"][node.params.type_variety].gain_flatmax}dB ; ' + f'{equipment["Edfa"][node.params.type_variety].gain_flatmax}dB ; '
+ f'required gain: {gain_target}dB. Please check amplifier type.\n') + f'required gain: {round(gain_target, 2)}dB. Please check amplifier type.\n')
node.delta_p = dp if power_mode else None node.delta_p = dp if power_mode else None
node.effective_gain = gain_target node.effective_gain = gain_target
# if voa is not set, then set it and possibly optimize it with gain and update delta_p and
# effective_gain values
set_amplifier_voa(node, power_target, power_mode) set_amplifier_voa(node, power_target, power_mode)
# set_amplifier_voa may change delta_p in power_mode
node._delta_p = node.delta_p if power_mode else dp
# target_pch_out_dbm records target power for design: If user defines one, then this is displayed,
# else display the one computed during design
if node.delta_p is not None and node.operational.delta_p is not None:
# use the user defined target
node.target_pch_out_dbm = round(node.operational.delta_p + pref_ch_db, 2)
elif node.delta_p is not None:
# use the design target if no target were set
node.target_pch_out_dbm = round(node.delta_p + pref_ch_db, 2)
elif node.delta_p is None:
node.target_pch_out_dbm = None
prev_dp = dp prev_dp = dp
prev_voa = voa prev_voa = voa
@@ -333,6 +406,13 @@ def set_egress_amplifier(network, this_node, equipment, pref_ch_db, pref_total_d
node = next_node node = next_node
def set_roadm_ref_carrier(roadm, equipment):
"""ref_carrier records carrier information used for design and usefull for equalization
"""
roadm.ref_carrier = ReferenceCarrier(baud_rate=equipment['SI']['default'].baud_rate,
slot_width=equipment['SI']['default'].spacing)
def set_roadm_per_degree_targets(roadm, network): def set_roadm_per_degree_targets(roadm, network):
"""Set target powers/PSD on all degrees """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 This is needed to populate per_degree_pch_out_dbm or per_degree_pch_psd or per_degree_pch_psw dicts when
@@ -355,15 +435,101 @@ def set_roadm_per_degree_targets(roadm, network):
raise ConfigurationError(roadm.uid, 'needs an equalization target') raise ConfigurationError(roadm.uid, 'needs an equalization target')
def set_roadm_input_powers(network, roadm, equipment, pref_ch_db):
"""Set reference powers at ROADM input for a reference channel and based on the adjacent OMS.
This supposes that there is no dependency on path. For example, the succession:
node power out of element
roadm A (target power -10dBm) -10dBm
fiber A (16 dB loss) -26dBm
roadm B (target power -12dBm) -26dBm
fiber B (10 dB loss) -36dBm
roadm C (target power -14dBm) -36dBm
is not consistent because target powers in roadm B and roadm C can not be met.
input power for the reference channel will be set -26 dBm in roadm B and -22dBm in roadm C,
because at design time we can not know about path.
The function raises a warning if target powers can not be met with the design.
User should be aware that design was not successfull and that power reduction was applied.
Note that this value is only used for visualisation purpose (to compute ROADM loss in elements).
"""
previous_elements = [n for n in network.predecessors(roadm)]
roadm.ref_pch_in_dbm = {}
for element in previous_elements:
node = element
loss = 0.0
while isinstance(node, (elements.Fiber, elements.Fused, elements.RamanFiber)):
# go through all predecessors until a power target is found either in an amplifier, a ROADM or a transceiver
# then deduce power at ROADM input from this degree based on this target and crossed losses
loss += node.loss
previous_node = node
node = next(network.predecessors(node))
if isinstance(node, elements.Edfa):
roadm.ref_pch_in_dbm[element.uid] = pref_ch_db + node._delta_p - node.out_voa - loss
elif isinstance(node, elements.Roadm):
roadm.ref_pch_in_dbm[element.uid] = \
node.get_per_degree_ref_power(degree=previous_node.uid) - loss
elif isinstance(node, elements.Transceiver):
roadm.ref_pch_in_dbm[element.uid] = pref_ch_db - loss
# check if target power can be met
temp = []
if roadm.per_degree_pch_out_dbm:
temp.append(max([p for p in roadm.per_degree_pch_out_dbm.values()]))
if roadm.per_degree_pch_psd:
temp.append(max([psd2powerdbm(p, roadm.ref_carrier.baud_rate) for p in roadm.per_degree_pch_psd.values()]))
if roadm.per_degree_pch_psw:
temp.append(max([psd2powerdbm(p, roadm.ref_carrier.slot_width) for p in roadm.per_degree_pch_psw.values()]))
if roadm.params.target_pch_out_db:
temp.append(roadm.params.target_pch_out_db)
if roadm.params.target_psd_out_mWperGHz:
temp.append(psd2powerdbm(roadm.params.target_psd_out_mWperGHz, roadm.ref_carrier.baud_rate))
if roadm.params.target_out_mWperSlotWidth:
temp.append(psd2powerdbm(roadm.params.target_out_mWperSlotWidth, roadm.ref_carrier.slot_width))
if not temp:
raise ConfigurationError(f'Could not find target power/PSD/PSW in ROADM "{roadm.uid}"')
target_to_be_supported = max(temp)
for from_degree, in_power in roadm.ref_pch_in_dbm.items():
if in_power < target_to_be_supported:
logger.warning(
f'WARNING: maximum target power {target_to_be_supported}dBm '
+ f'in ROADM "{roadm.uid}" can not be met for at least one crossing path. Min input power '
+ f'from "{from_degree}" direction is {round(in_power, 2)}dBm. Please correct input topology.'
)
def set_fiber_input_power(network, fiber, equipment, pref_ch_db):
"""Set reference powers at fiber input for a reference channel.
Supposes that target power out of ROADMs and amplifiers are consistent.
This is only for visualisation purpose
"""
loss = 0.0
node = next(network.predecessors(fiber))
while isinstance(node, elements.Fused):
loss += node.loss
previous_node = node
node = next(network.predecessors(node))
if isinstance(node, (elements.Fiber, elements.RamanFiber)) and node.ref_pch_in_dbm is not None:
fiber.ref_pch_in_dbm = node.ref_pch_in_dbm - loss - node.loss
if isinstance(node, (elements.Fiber, elements.RamanFiber)) and node.ref_pch_in_dbm is None:
set_fiber_input_power(network, node, equipment, pref_ch_db)
fiber.ref_pch_in_dbm = node.ref_pch_in_dbm - loss - node.loss
elif isinstance(node, elements.Roadm):
fiber.ref_pch_in_dbm = \
node.get_per_degree_ref_power(degree=previous_node.uid) - loss
elif isinstance(node, elements.Edfa):
fiber.ref_pch_in_dbm = pref_ch_db + node._delta_p - node.out_voa - loss
elif isinstance(node, elements.Transceiver):
fiber.ref_pch_in_dbm = pref_ch_db - loss
def add_roadm_booster(network, roadm): def add_roadm_booster(network, roadm):
next_nodes = [n for n in network.successors(roadm) next_nodes = [n for n in network.successors(roadm)
if not (isinstance(n, elements.Transceiver) or isinstance(n, elements.Fused) or isinstance(n, elements.Edfa))] if not (isinstance(n, elements.Transceiver) or isinstance(n, elements.Fused)
or isinstance(n, elements.Edfa))]
# no amplification for fused spans or TRX # no amplification for fused spans or TRX
for next_node in next_nodes: for next_node in next_nodes:
network.remove_edge(roadm, next_node) network.remove_edge(roadm, next_node)
amp = elements.Edfa( amp = elements.Edfa(
uid=f'Edfa_booster_{roadm.uid}_to_{next_node.uid}', uid=f'Edfa_booster_{roadm.uid}_to_{next_node.uid}',
params=Amp.default_values, params=json_io.Amp.default_values,
metadata={ metadata={
'location': { 'location': {
'latitude': roadm.lat, 'latitude': roadm.lat,
@@ -389,7 +555,7 @@ def add_roadm_preamp(network, roadm):
network.remove_edge(prev_node, roadm) network.remove_edge(prev_node, roadm)
amp = elements.Edfa( amp = elements.Edfa(
uid=f'Edfa_preamp_{roadm.uid}_from_{prev_node.uid}', uid=f'Edfa_preamp_{roadm.uid}_from_{prev_node.uid}',
params=Amp.default_values, params=json_io.Amp.default_values,
metadata={ metadata={
'location': { 'location': {
'latitude': roadm.lat, 'latitude': roadm.lat,
@@ -412,13 +578,13 @@ def add_roadm_preamp(network, roadm):
def add_inline_amplifier(network, fiber): def add_inline_amplifier(network, fiber):
next_node = next(network.successors(fiber)) next_node = get_next_node(fiber, network)
if isinstance(next_node, elements.Fiber) or isinstance(next_node, elements.RamanFiber): if isinstance(next_node, elements.Fiber) or isinstance(next_node, elements.RamanFiber):
# no amplification for fused spans or TRX # no amplification for fused spans or TRX
network.remove_edge(fiber, next_node) network.remove_edge(fiber, next_node)
amp = elements.Edfa( amp = elements.Edfa(
uid=f'Edfa_{fiber.uid}', uid=f'Edfa_{fiber.uid}',
params=Amp.default_values, params=json_io.Amp.default_values,
metadata={ metadata={
'location': { 'location': {
'latitude': (fiber.lat + next_node.lat) / 2, 'latitude': (fiber.lat + next_node.lat) / 2,
@@ -437,6 +603,9 @@ def add_inline_amplifier(network, fiber):
def calculate_new_length(fiber_length, bounds, target_length): def calculate_new_length(fiber_length, bounds, target_length):
"""If fiber is over boundary, then assume this is a link "intent" and computes the set of
identical fiber spans this link should be composed of.
"""
if fiber_length < bounds.stop: if fiber_length < bounds.stop:
return fiber_length, 1 return fiber_length, 1
@@ -456,7 +625,21 @@ def calculate_new_length(fiber_length, bounds, target_length):
return (length1, n_spans1) return (length1, n_spans1)
def split_fiber(network, fiber, bounds, target_length, equipment): def get_next_node(node, network):
"""get_next node else raise tha appropriate error
"""
try:
next_node = next(network.successors(node))
return next_node
except StopIteration:
raise NetworkTopologyError(
f'{type(node).__name__} {node.uid} is not properly connected, please check network topology')
def split_fiber(network, fiber, bounds, target_length):
"""If fiber length exceeds boundary then assume this is a link "intent", and replace this one-span link
with an n_spans link, with identical fiber types.
"""
new_length, n_spans = calculate_new_length(fiber.params.length, bounds, target_length) new_length, n_spans = calculate_new_length(fiber.params.length, bounds, target_length)
if n_spans == 1: if n_spans == 1:
return return
@@ -499,11 +682,10 @@ def split_fiber(network, fiber, bounds, target_length, equipment):
def add_connector_loss(network, fibers, default_con_in, default_con_out, EOL): def add_connector_loss(network, fibers, default_con_in, default_con_out, EOL):
"""Add default connector loss if no loss are defined. EOL repair margin is added as a connector loss
"""
for fiber in fibers: for fiber in fibers:
try: next_node = get_next_node(fiber, network)
next_node = next(network.successors(fiber))
except StopIteration:
raise NetworkTopologyError(f'Fiber {fiber.uid} is not properly connected, please check network topology')
if fiber.params.con_in is None: if fiber.params.con_in is None:
fiber.params.con_in = default_con_in fiber.params.con_in = default_con_in
if fiber.params.con_out is None: if fiber.params.con_out is None:
@@ -512,19 +694,14 @@ def add_connector_loss(network, fibers, default_con_in, default_con_out, EOL):
fiber.params.con_out += EOL fiber.params.con_out += EOL
def add_fiber_padding(network, fibers, padding): def add_fiber_padding(network, fibers, padding, equipment):
"""last_fibers = (fiber for n in network.nodes() """Add a padding att_in at the input of the 1st fiber of a succession of fibers and fused
if not (isinstance(n, elements.Fiber) or isinstance(n, elements.Fused)) """
for fiber in network.predecessors(n)
if isinstance(fiber, elements.Fiber))"""
for fiber in fibers: for fiber in fibers:
try: next_node = get_next_node(fiber, network)
next_node = next(network.successors(fiber))
except StopIteration:
raise NetworkTopologyError(f'Fiber {fiber.uid} is not properly connected, please check network topology')
if isinstance(next_node, elements.Fused): if isinstance(next_node, elements.Fused):
continue continue
this_span_loss = span_loss(network, fiber) this_span_loss = span_loss(network, fiber, equipment)
if this_span_loss < padding: if this_span_loss < padding:
# add a padding att_in at the input of the 1st fiber: # add a padding att_in at the input of the 1st fiber:
# address the case when several fibers are spliced together # address the case when several fibers are spliced together
@@ -535,41 +712,65 @@ def add_fiber_padding(network, fibers, padding):
first_fiber.params.att_in = first_fiber.params.att_in + padding - this_span_loss first_fiber.params.att_in = first_fiber.params.att_in + padding - this_span_loss
def build_network(network, equipment, pref_ch_db, pref_total_db, no_insert_edfas=False): def add_missing_elements_in_network(network, equipment):
"""Autodesign network: add missing elements. split fibers if their length is too big
add ROADM preamp or booster and inline amplifiers between fibers
"""
default_span_data = equipment['Span']['default'] default_span_data = equipment['Span']['default']
max_length = int(convert_length(default_span_data.max_length, default_span_data.length_units)) max_length = int(convert_length(default_span_data.max_length, default_span_data.length_units))
min_length = max(int(default_span_data.padding / 0.2 * 1e3), 50_000) min_length = max(int(default_span_data.padding / 0.2 * 1e3), 50_000)
bounds = range(min_length, max_length) bounds = range(min_length, max_length)
target_length = max(min_length, min(max_length, 90_000)) target_length = max(min_length, min(max_length, 90_000))
fibers = [f for f in network.nodes() if isinstance(f, elements.Fiber)]
for fiber in fibers:
split_fiber(network, fiber, bounds, target_length)
roadms = [r for r in network.nodes() if isinstance(r, elements.Roadm)]
for roadm in roadms:
add_roadm_preamp(network, roadm)
add_roadm_booster(network, roadm)
fibers = [f for f in network.nodes() if isinstance(f, elements.Fiber)]
for fiber in fibers:
add_inline_amplifier(network, fiber)
# set roadm loss for gain_mode before to build network
def add_missing_fiber_attributes(network, equipment):
"""Fill in connector loss with default values. Add the padding loss is required.
EOL is added as a connector loss
"""
default_span_data = equipment['Span']['default']
fibers = [f for f in network.nodes() if isinstance(f, elements.Fiber)] fibers = [f for f in network.nodes() if isinstance(f, elements.Fiber)]
add_connector_loss(network, fibers, default_span_data.con_in, default_span_data.con_out, default_span_data.EOL) add_connector_loss(network, fibers, default_span_data.con_in, default_span_data.con_out, default_span_data.EOL)
# don't group split fiber and add amp in the same loop # don't group split fiber and add amp in the same loop
# =>for code clarity (at the expense of speed): # =>for code clarity (at the expense of speed):
add_fiber_padding(network, fibers, default_span_data.padding, equipment)
def build_network(network, equipment, pref_ch_db, pref_total_db, set_connector_losses=True, verbose=True):
"""Set roadm equalization target and amplifier gain and power
"""
roadms = [r for r in network.nodes() if isinstance(r, elements.Roadm)] roadms = [r for r in network.nodes() if isinstance(r, elements.Roadm)]
transceivers = [t for t in network.nodes() if isinstance(t, elements.Transceiver)]
if not no_insert_edfas: if set_connector_losses:
for fiber in fibers: add_missing_fiber_attributes(network, equipment)
split_fiber(network, fiber, bounds, target_length, equipment) # set roadm equalization targets first
for roadm in roadms:
add_roadm_preamp(network, roadm)
add_roadm_booster(network, roadm)
fibers = [f for f in network.nodes() if isinstance(f, elements.Fiber)]
for fiber in fibers:
add_inline_amplifier(network, fiber)
add_fiber_padding(network, fibers, default_span_data.padding)
for roadm in roadms: for roadm in roadms:
set_roadm_ref_carrier(roadm, equipment)
set_roadm_per_degree_targets(roadm, network) set_roadm_per_degree_targets(roadm, network)
set_egress_amplifier(network, roadm, equipment, pref_ch_db, pref_total_db) # then set amplifiers gain, delta_p and out_voa on each OMS
for roadm in roadms + transceivers:
set_egress_amplifier(network, roadm, equipment, pref_ch_db, pref_total_db, verbose)
for roadm in roadms:
set_roadm_input_powers(network, roadm, equipment, pref_ch_db)
for fiber in [f for f in network.nodes() if isinstance(f, (elements.Fiber, elements.RamanFiber))]:
set_fiber_input_power(network, fiber, equipment, pref_ch_db)
trx = [t for t in network.nodes() if isinstance(t, elements.Transceiver)]
for t in trx: def design_network(reference_channel, network, equipment, set_connector_losses=True, verbose=True):
next_node = next(network.successors(t), None) """Network is designed according to reference channel. Verbose indicate if the function should
if next_node and not isinstance(next_node, elements.Roadm): print all warnings or not
set_egress_amplifier(network, t, equipment, 0, pref_total_db) """
pref_ch_db = watt2dbm(reference_channel.power) # reference channel power
pref_total_db = pref_ch_db + lin2db(reference_channel.nb_channel) # reference total power
build_network(network, equipment, pref_ch_db, pref_total_db, set_connector_losses=set_connector_losses,
verbose=verbose)

View File

@@ -179,8 +179,8 @@ class FiberParams(Parameters):
# Chromatic Dispersion # Chromatic Dispersion
if 'dispersion_per_frequency' in kwargs: if 'dispersion_per_frequency' in kwargs:
# Frequency-dependent dispersion # Frequency-dependent dispersion
self._dispersion = asarray(kwargs['dispersion']['value']) # s/m/m self._dispersion = asarray(kwargs['dispersion_per_frequency']['value']) # s/m/m
self._f_dispersion_ref = asarray(kwargs['dispersion']['frequency']) # Hz self._f_dispersion_ref = asarray(kwargs['dispersion_per_frequency']['frequency']) # Hz
self._dispersion_slope = None self._dispersion_slope = None
elif 'dispersion' in kwargs: elif 'dispersion' in kwargs:
# Single value dispersion # Single value dispersion

View File

@@ -5,6 +5,8 @@
"gain_ripple": [ "gain_ripple": [
0.0 0.0
], ],
"f_min": 191.35e12,
"f_max": 196.1e12,
"dgt": [ "dgt": [
1.0, 1.0,
1.017807767853702, 1.017807767853702,

View File

@@ -19,9 +19,9 @@ import gnpy.core.ansi_escapes as ansi_escapes
from gnpy.core.elements import Transceiver, Fiber, RamanFiber from gnpy.core.elements import Transceiver, Fiber, RamanFiber
from gnpy.core.equipment import trx_mode_params from gnpy.core.equipment import trx_mode_params
import gnpy.core.exceptions as exceptions import gnpy.core.exceptions as exceptions
from gnpy.core.network import build_network from gnpy.core.network import add_missing_elements_in_network, design_network
from gnpy.core.parameters import SimParams from gnpy.core.parameters import SimParams
from gnpy.core.utils import db2lin, lin2db, automatic_nch from gnpy.core.utils import db2lin, lin2db, automatic_nch, watt2dbm, dbm2watt
from gnpy.topology.request import (ResultElement, jsontocsv, compute_path_dsjctn, requests_aggregation, from gnpy.topology.request import (ResultElement, jsontocsv, compute_path_dsjctn, requests_aggregation,
BLOCKING_NOPATH, correct_json_route_list, BLOCKING_NOPATH, correct_json_route_list,
deduplicate_disjunctions, compute_path_with_disjunction, deduplicate_disjunctions, compute_path_with_disjunction,
@@ -197,37 +197,37 @@ def transmission_main_example(args=None):
trx_params['power'] = db2lin(float(args.power)) * 1e-3 trx_params['power'] = db2lin(float(args.power)) * 1e-3
params.update(trx_params) params.update(trx_params)
initial_spectrum = None initial_spectrum = None
nb_channels = automatic_nch(trx_params['f_min'], trx_params['f_max'], trx_params['spacing']) params['nb_channel'] = automatic_nch(trx_params['f_min'], trx_params['f_max'], trx_params['spacing'])
# use ref_req to hold reference channel used for design and req for the propagation
# and req to hold channels to be propagated
# apply power sweep on the design and on the channels
ref_req = PathRequest(**params)
pref_ch_db = watt2dbm(ref_req.power)
if args.spectrum: if args.spectrum:
# use the spectrum defined by user for the propagation.
# the nb of channel for design remains the one of the reference channel
initial_spectrum = load_initial_spectrum(args.spectrum) initial_spectrum = load_initial_spectrum(args.spectrum)
nb_channels = len(initial_spectrum) params['nb_channel'] = len(initial_spectrum)
print('User input for spectrum used for propagation instead of SI') print('User input for spectrum used for propagation instead of SI')
params['nb_channel'] = nb_channels
req = PathRequest(**params) req = PathRequest(**params)
p_ch_db = watt2dbm(req.power)
req.initial_spectrum = initial_spectrum req.initial_spectrum = initial_spectrum
print(f'There are {nb_channels} channels propagating') print(f'There are {req.nb_channel} channels propagating')
power_mode = equipment['Span']['default'].power_mode power_mode = equipment['Span']['default'].power_mode
print('\n'.join([f'Power mode is set to {power_mode}', print('\n'.join([f'Power mode is set to {power_mode}',
f'=> it can be modified in eqpt_config.json - Span'])) '=> it can be modified in eqpt_config.json - Span']))
if not args.no_insert_edfas:
try:
add_missing_elements_in_network(network, equipment)
except exceptions.NetworkTopologyError as e:
print(f'{ansi_escapes.red}Invalid network definition:{ansi_escapes.reset} {e}')
sys.exit(1)
except exceptions.ConfigurationError as e:
print(f'{ansi_escapes.red}Configuration error:{ansi_escapes.reset} {e}')
sys.exit(1)
# 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:
build_network(network, equipment, pref_ch_db, pref_total_db, args.no_insert_edfas)
except exceptions.NetworkTopologyError as e:
print(f'{ansi_escapes.red}Invalid network definition:{ansi_escapes.reset} {e}')
sys.exit(1)
except exceptions.ConfigurationError as e:
print(f'{ansi_escapes.red}Configuration error:{ansi_escapes.reset} {e}')
sys.exit(1)
path = compute_constrained_path(network, req) path = compute_constrained_path(network, req)
spans = [s.params.length for s in path if isinstance(s, RamanFiber) or isinstance(s, Fiber)] spans = [s.params.length for s in path if isinstance(s, RamanFiber) or isinstance(s, Fiber)]
print(f'\nThere are {len(spans)} fiber spans over {sum(spans)/1000:.0f} km between {source.uid} '
f'and {destination.uid}')
print(f'\nNow propagating between {source.uid} and {destination.uid}:')
power_range = [0] power_range = [0]
if power_mode: if power_mode:
# power cannot be changed in gain mode # power cannot be changed in gain mode
@@ -237,15 +237,32 @@ def transmission_main_example(args=None):
power_range = list(linspace(p_start, p_stop, p_num)) power_range = list(linspace(p_start, p_stop, p_num))
except TypeError: except TypeError:
print('invalid power range definition in eqpt_config, should be power_range_db: [lower, upper, step]') print('invalid power range definition in eqpt_config, should be power_range_db: [lower, upper, step]')
# initial network is designed using req.power. that is that any missing information (amp gain or delta_p) is filled
# using this req.power, previous to any sweep requested later on.
try:
design_network(ref_req, network, equipment, set_connector_losses=True, verbose=True)
except exceptions.NetworkTopologyError as e:
print(f'{ansi_escapes.red}Invalid network definition:{ansi_escapes.reset} {e}')
sys.exit(1)
except exceptions.ConfigurationError as e:
print(f'{ansi_escapes.red}Configuration error:{ansi_escapes.reset} {e}')
sys.exit(1)
print(f'\nThere are {len(spans)} fiber spans over {sum(spans)/1000:.0f} km between {source.uid} '
f'and {destination.uid}')
print(f'\nNow propagating between {source.uid} and {destination.uid}:')
for dp_db in power_range: for dp_db in power_range:
req.power = db2lin(pref_ch_db + dp_db) * 1e-3 ref_req.power = dbm2watt(pref_ch_db + dp_db)
req.power = dbm2watt(p_ch_db + dp_db)
design_network(ref_req, network, equipment, set_connector_losses=False, verbose=False)
# if initial spectrum did not contain any power, now we need to use this one. # 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) # 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 # 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 # whatever the equalization, -3 dB is applied on all channels (ie initial power in initial spectrum pre-empts
# "--power" option) # "--power" option)
if power_mode: if power_mode:
print(f'\nPropagating with input power = {ansi_escapes.cyan}{lin2db(req.power*1e3):.2f} dBm{ansi_escapes.reset}:') print(f'\nPropagating with input power = {ansi_escapes.cyan}{watt2dbm(req.power):.2f} '
+ f'dBm{ansi_escapes.reset}:')
else: else:
print(f'\nPropagating in {ansi_escapes.cyan}gain mode{ansi_escapes.reset}: power cannot be set manually') print(f'\nPropagating in {ansi_escapes.cyan}gain mode{ansi_escapes.reset}: power cannot be set manually')
infos = propagate(path, req, equipment) infos = propagate(path, req, equipment)
@@ -330,17 +347,43 @@ def path_requests_run(args=None):
# Build the network once using the default power defined in SI in eqpt config # Build the network once using the default power defined in SI in eqpt config
# TODO power density: db2linp(ower_dbm": 0)/power_dbm": 0 * nb channels as defined by # TODO power density: db2linp(ower_dbm": 0)/power_dbm": 0 * nb channels as defined by
# spacing, f_min and f_max # spacing, f_min and f_max
p_db = equipment['SI']['default'].power_dbm if not args.no_insert_edfas:
p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min, try:
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing)) add_missing_elements_in_network(network, equipment)
except exceptions.NetworkTopologyError as e:
print(f'{ansi_escapes.red}Invalid network definition:{ansi_escapes.reset} {e}')
sys.exit(1)
except exceptions.ConfigurationError as e:
print(f'{ansi_escapes.red}Configuration error:{ansi_escapes.reset} {e}')
sys.exit(1)
params = {
'request_id': 'reference',
'trx_type': '',
'trx_mode': '',
'source': None,
'destination': None,
'bidir': False,
'nodes_list': [],
'loose_list': [],
'format': '',
'path_bandwidth': 0,
'effective_freq_slot': None,
'nb_channel': automatic_nch(equipment['SI']['default'].f_min, equipment['SI']['default'].f_max,
equipment['SI']['default'].spacing)
}
trx_params = trx_mode_params(equipment)
params.update(trx_params)
reference_channel = PathRequest(**params)
try: try:
build_network(network, equipment, p_db, p_total_db, args.no_insert_edfas) design_network(reference_channel, network, equipment, verbose=True)
except exceptions.NetworkTopologyError as e: except exceptions.NetworkTopologyError as e:
print(f'{ansi_escapes.red}Invalid network definition:{ansi_escapes.reset} {e}') print(f'{ansi_escapes.red}Invalid network definition:{ansi_escapes.reset} {e}')
sys.exit(1) sys.exit(1)
except exceptions.ConfigurationError as e: except exceptions.ConfigurationError as e:
print(f'{ansi_escapes.red}Configuration error:{ansi_escapes.reset} {e}') print(f'{ansi_escapes.red}Configuration error:{ansi_escapes.reset} {e}')
sys.exit(1) sys.exit(1)
if args.save_network is not None: if args.save_network is not None:
save_network(network, args.save_network) save_network(network, args.save_network)
print(f'{ansi_escapes.blue}Network (after autodesign) saved to {args.save_network}{ansi_escapes.reset}') print(f'{ansi_escapes.blue}Network (after autodesign) saved to {args.save_network}{ansi_escapes.reset}')

View File

@@ -23,7 +23,8 @@ from networkx.utils import pairwise
from numpy import mean, argmin from numpy import mean, argmin
from gnpy.core.elements import Transceiver, Roadm from gnpy.core.elements import Transceiver, Roadm
from gnpy.core.utils import lin2db from gnpy.core.utils import lin2db
from gnpy.core.info import create_input_spectral_information, carriers_to_spectral_information, ReferenceCarrier from gnpy.core.info import create_input_spectral_information, carriers_to_spectral_information
from gnpy.core import network as network_module
from gnpy.core.exceptions import ServiceError, DisjunctionError from gnpy.core.exceptions import ServiceError, DisjunctionError
from copy import deepcopy from copy import deepcopy
from csv import writer from csv import writer
@@ -329,28 +330,17 @@ def compute_constrained_path(network, req):
return total_path 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): def propagate(path, req, equipment):
"""propagates signals in each element according to initial spectrum set by user""" """propagates signals in each element according to initial spectrum set by user"""
if req.initial_spectrum is not None: if req.initial_spectrum is not None:
si = carriers_to_spectral_information(initial_spectrum=req.initial_spectrum, si = carriers_to_spectral_information(initial_spectrum=req.initial_spectrum, power=req.power)
power=req.power, ref_carrier=ref_carrier(equipment))
else: else:
si = create_input_spectral_information( 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, 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, delta_pdb=req.offset_db, power=req.power, spacing=req.spacing, tx_osnr=req.tx_osnr, delta_pdb=req.offset_db)
ref_carrier=ref_carrier(equipment))
for i, el in enumerate(path): for i, el in enumerate(path):
if isinstance(el, Roadm): if isinstance(el, Roadm):
si = el(si, degree=path[i+1].uid) si = el(si, degree=path[i + 1].uid, from_degree=path[i - 1].uid)
else: else:
si = el(si) si = el(si)
path[0].update_snr(si.tx_osnr) path[0].update_snr(si.tx_osnr)
@@ -391,11 +381,10 @@ def propagate_and_optimize_mode(path, req, equipment):
spc_info = create_input_spectral_information(f_min=req.f_min, f_max=req.f_max, spc_info = create_input_spectral_information(f_min=req.f_min, f_max=req.f_max,
roll_off=equipment['SI']['default'].roll_off, roll_off=equipment['SI']['default'].roll_off,
baud_rate=this_br, power=req.power, spacing=req.spacing, baud_rate=this_br, power=req.power, spacing=req.spacing,
delta_pdb=this_offset, delta_pdb=this_offset, tx_osnr=req.tx_osnr)
tx_osnr=req.tx_osnr, ref_carrier=ref_carrier(equipment))
for i, el in enumerate(path): for i, el in enumerate(path):
if isinstance(el, Roadm): if isinstance(el, Roadm):
spc_info = el(spc_info, degree=path[i+1].uid) spc_info = el(spc_info, degree=path[i + 1].uid, from_degree=path[i - 1].uid)
else: else:
spc_info = el(spc_info) spc_info = el(spc_info)
for this_mode in modes_to_explore: for this_mode in modes_to_explore:
@@ -1102,6 +1091,7 @@ def compute_path_with_disjunction(network, equipment, pathreqlist, pathlist):
# elements to simulate performance, several demands having the same destination # elements to simulate performance, several demands having the same destination
# may use the same transponder for the performance simulation. This is why # may use the same transponder for the performance simulation. This is why
# we use deepcopy: to ensure that each propagation is recorded and not overwritten # we use deepcopy: to ensure that each propagation is recorded and not overwritten
network_module.design_network(pathreq, network, equipment, set_connector_losses=False, verbose=False)
total_path = deepcopy(pathlist[i]) total_path = deepcopy(pathlist[i])
msg = msg + f'\n\tComputed path (roadms):{[e.uid for e in total_path if isinstance(e, Roadm)]}' msg = msg + f'\n\tComputed path (roadms):{[e.uid for e in total_path if isinstance(e, Roadm)]}'
LOGGER.info(msg) LOGGER.info(msg)

View File

@@ -1,11 +0,0 @@
# matplotlib 3.8 removed support for Python 3.8
matplotlib>=3.7.3,<4
# networkx 3.2 removed support for Python 3.8
networkx>=3.1,<4
# numpy 1.25 removed support for Python 3.8
numpy>=1.24.4,<2
pbr>=6.0.0,<7
# scipy 1.11 removed support for Python 3.8
scipy>=1.10.1,<2
# xlrd 2.x removed support for .xlsx, it's only .xls now
xlrd>=1.2.0,<2

View File

@@ -49,3 +49,35 @@ console_scripts =
gnpy-transmission-example = gnpy.tools.cli_examples:transmission_main_example gnpy-transmission-example = gnpy.tools.cli_examples:transmission_main_example
gnpy-path-request = gnpy.tools.cli_examples:path_requests_run gnpy-path-request = gnpy.tools.cli_examples:path_requests_run
gnpy-convert-xls = gnpy.tools.convert:_do_convert gnpy-convert-xls = gnpy.tools.convert:_do_convert
[options]
install_requires =
# matplotlib 3.8 removed support for Python 3.8
matplotlib>=3.7.3,<4
# networkx 3.2 removed support for Python 3.8
networkx>=3.1,<4
# numpy 1.25 removed support for Python 3.8
numpy>=1.24.4,<2
pbr>=6.0.0,<7
# scipy 1.11 removed support for Python 3.8
scipy>=1.10.1,<2
# xlrd 2.x removed support for .xlsx, it's only .xls now
xlrd>=1.2.0,<2
[options.extras_require]
tests =
build>=1.0.3,<2
pytest>=7.4.3,<8
# pandas 2.1 removed support for Python 3.8
pandas>=2.0.3,<3
# flake v6 killed the --diff option
flake8>=5.0.4,<6
docs =
alabaster>=0.7.12,<1
docutils>=0.17.1,<1
myst-parser>=0.16.1,<1
Pygments>=2.11.2,<3
rstcheck
Sphinx>=5.3.0,<6
sphinxcontrib-bibtex>=2.4.1,<3

View File

@@ -83375,7 +83375,7 @@
"type": "Edfa", "type": "Edfa",
"type_variety": "std_medium_gain", "type_variety": "std_medium_gain",
"operational": { "operational": {
"gain_target": 28.5006, "gain_target": 28.5,
"delta_p": null, "delta_p": null,
"tilt_target": 0, "tilt_target": 0,
"out_voa": 0 "out_voa": 0
@@ -88752,7 +88752,7 @@
"type": "Edfa", "type": "Edfa",
"type_variety": "std_medium_gain", "type_variety": "std_medium_gain",
"operational": { "operational": {
"gain_target": 28.5032, "gain_target": 28.5,
"delta_p": null, "delta_p": null,
"tilt_target": 0, "tilt_target": 0,
"out_voa": 0 "out_voa": 0
@@ -89037,7 +89037,7 @@
"type": "Edfa", "type": "Edfa",
"type_variety": "std_medium_gain", "type_variety": "std_medium_gain",
"operational": { "operational": {
"gain_target": 28.5006, "gain_target": 28.5,
"delta_p": null, "delta_p": null,
"tilt_target": 0, "tilt_target": 0,
"out_voa": 0 "out_voa": 0
@@ -89721,7 +89721,7 @@
"type": "Edfa", "type": "Edfa",
"type_variety": "std_medium_gain", "type_variety": "std_medium_gain",
"operational": { "operational": {
"gain_target": 28.502, "gain_target": 28.5,
"delta_p": null, "delta_p": null,
"tilt_target": 0, "tilt_target": 0,
"out_voa": 0 "out_voa": 0
@@ -89797,7 +89797,7 @@
"type": "Edfa", "type": "Edfa",
"type_variety": "std_medium_gain", "type_variety": "std_medium_gain",
"operational": { "operational": {
"gain_target": 28.502, "gain_target": 28.5,
"delta_p": null, "delta_p": null,
"tilt_target": 0, "tilt_target": 0,
"out_voa": 0 "out_voa": 0
@@ -89911,7 +89911,7 @@
"type": "Edfa", "type": "Edfa",
"type_variety": "std_medium_gain", "type_variety": "std_medium_gain",
"operational": { "operational": {
"gain_target": 28.5032, "gain_target": 28.5,
"delta_p": null, "delta_p": null,
"tilt_target": 0, "tilt_target": 0,
"out_voa": 0 "out_voa": 0
@@ -193159,4 +193159,4 @@
"to_node": "fiber (Warsaw → Vienna)-_(7/7)" "to_node": "fiber (Warsaw → Vienna)-_(7/7)"
} }
] ]
} }

View File

@@ -1,4 +1,6 @@
{ {
"f_min": 191.35e12,
"f_max": 196.1e12,
"nf_ripple": [ "nf_ripple": [
0.0, 0.0,
0.0, 0.0,

View File

@@ -0,0 +1,220 @@
{
"Edfa": [{
"type_variety": "CienaDB_medium_gain",
"type_def": "advanced_model",
"gain_flatmax": 25,
"gain_min": 15,
"p_max": 21,
"advanced_config_from_json": "std_medium_gain_advanced_config.json",
"out_voa_auto": false,
"allowed_for_design": true
}, {
"type_variety": "std_medium_gain",
"type_def": "variable_gain",
"gain_flatmax": 26,
"gain_min": 15,
"p_max": 21,
"nf_min": 6,
"nf_max": 10,
"out_voa_auto": false,
"allowed_for_design": true
}, {
"type_variety": "std_low_gain",
"type_def": "variable_gain",
"gain_flatmax": 16,
"gain_min": 8,
"p_max": 21,
"nf_min": 7,
"nf_max": 11,
"out_voa_auto": false,
"allowed_for_design": true
}, {
"type_variety": "test",
"type_def": "variable_gain",
"gain_flatmax": 25,
"gain_min": 15,
"p_max": 21,
"nf_min": 5.8,
"nf_max": 10,
"out_voa_auto": false,
"allowed_for_design": true
}, {
"type_variety": "test_fixed_gain",
"type_def": "fixed_gain",
"gain_flatmax": 21,
"gain_min": 20,
"p_max": 21,
"nf0": 5,
"allowed_for_design": true
}, {
"type_variety": "std_booster",
"type_def": "fixed_gain",
"gain_flatmax": 21,
"gain_min": 20,
"p_max": 21,
"nf0": 5,
"allowed_for_design": false
}
],
"Fiber": [{
"type_variety": "SSMF",
"dispersion": 1.67e-05,
"effective_area": 83e-12,
"pmd_coef": 1.265e-15
}
],
"Span": [{
"power_mode": true,
"delta_power_range_db": [0, 0, 0.5],
"max_fiber_lineic_loss_for_raman": 0.25,
"target_extended_gain": 2.5,
"max_length": 150,
"length_units": "km",
"max_loss": 28,
"padding": 10,
"EOL": 0,
"con_in": 0,
"con_out": 0
}
],
"Roadm": [{
"target_psd_out_mWperGHz": 3.125e-4,
"add_drop_osnr": 38,
"pmd": 0,
"pdl": 0,
"restrictions": {
"preamp_variety_list": [],
"booster_variety_list": []
}
}
],
"SI": [{
"f_min": 191.35e12,
"f_max": 196.1e12,
"baud_rate": 32e9,
"spacing": 50e9,
"power_dbm": 0,
"power_range_db": [0, 0, 0.5],
"roll_off": 0.15,
"tx_osnr": 100,
"sys_margins": 0
}
],
"Transceiver": [{
"type_variety": "vendorA_trx-type1",
"frequency": {
"min": 191.4e12,
"max": 196.1e12
},
"mode": [{
"format": "PS_SP64_1",
"baud_rate": 32e9,
"OSNR": 11,
"bit_rate": 100e9,
"roll_off": 0.15,
"tx_osnr": 100,
"min_spacing": 50e9,
"cost": 1
}, {
"format": "PS_SP64_2",
"baud_rate": 64e9,
"OSNR": 15,
"bit_rate": 200e9,
"roll_off": 0.15,
"tx_osnr": 100,
"min_spacing": 75e9,
"cost": 1
}, {
"format": "mode 1",
"baud_rate": 32e9,
"OSNR": 11,
"bit_rate": 100e9,
"roll_off": 0.15,
"tx_osnr": 100,
"min_spacing": 50e9,
"cost": 1
}, {
"format": "mode 2",
"baud_rate": 64e9,
"OSNR": 15,
"bit_rate": 200e9,
"roll_off": 0.15,
"tx_osnr": 100,
"min_spacing": 75e9,
"cost": 1
}
]
}, {
"type_variety": "Voyager_16QAM",
"frequency": {
"min": 191.4e12,
"max": 196.1e12
},
"mode": [{
"format": "16QAM",
"baud_rate": 32e9,
"OSNR": 19,
"bit_rate": 200e9,
"roll_off": 0.15,
"tx_osnr": 100,
"min_spacing": 50e9,
"cost": 1
}
]
}, {
"type_variety": "Voyager",
"frequency": {
"min": 191.4e12,
"max": 196.1e12
},
"mode": [{
"format": "mode 1",
"baud_rate": 32e9,
"OSNR": 12,
"bit_rate": 100e9,
"roll_off": 0.15,
"tx_osnr": 45,
"min_spacing": 50e9,
"cost": 1
}, {
"format": "mode 3",
"baud_rate": 44e9,
"OSNR": 18,
"bit_rate": 300e9,
"roll_off": 0.15,
"tx_osnr": 45,
"min_spacing": 62.5e9,
"cost": 1
}, {
"format": "mode 2",
"baud_rate": 66e9,
"OSNR": 21,
"bit_rate": 400e9,
"roll_off": 0.15,
"tx_osnr": 45,
"min_spacing": 75e9,
"cost": 1
}, {
"format": "mode 2 - fake",
"baud_rate": 66e9,
"OSNR": 21,
"bit_rate": 400e9,
"roll_off": 0.15,
"tx_osnr": 45,
"min_spacing": 75e9,
"cost": 1
}, {
"format": "mode 4",
"baud_rate": 66e9,
"OSNR": 16,
"bit_rate": 200e9,
"roll_off": 0.15,
"tx_osnr": 45,
"min_spacing": 75e9,
"cost": 1
}
]
}
]
}

View File

@@ -0,0 +1,220 @@
{
"Edfa": [{
"type_variety": "CienaDB_medium_gain",
"type_def": "advanced_model",
"gain_flatmax": 25,
"gain_min": 15,
"p_max": 21,
"advanced_config_from_json": "std_medium_gain_advanced_config.json",
"out_voa_auto": false,
"allowed_for_design": true
}, {
"type_variety": "std_medium_gain",
"type_def": "variable_gain",
"gain_flatmax": 26,
"gain_min": 15,
"p_max": 21,
"nf_min": 6,
"nf_max": 10,
"out_voa_auto": false,
"allowed_for_design": true
}, {
"type_variety": "std_low_gain",
"type_def": "variable_gain",
"gain_flatmax": 16,
"gain_min": 8,
"p_max": 21,
"nf_min": 7,
"nf_max": 11,
"out_voa_auto": false,
"allowed_for_design": true
}, {
"type_variety": "test",
"type_def": "variable_gain",
"gain_flatmax": 25,
"gain_min": 15,
"p_max": 21,
"nf_min": 5.8,
"nf_max": 10,
"out_voa_auto": false,
"allowed_for_design": true
}, {
"type_variety": "test_fixed_gain",
"type_def": "fixed_gain",
"gain_flatmax": 21,
"gain_min": 20,
"p_max": 21,
"nf0": 5,
"allowed_for_design": true
}, {
"type_variety": "std_booster",
"type_def": "fixed_gain",
"gain_flatmax": 21,
"gain_min": 20,
"p_max": 21,
"nf0": 5,
"allowed_for_design": false
}
],
"Fiber": [{
"type_variety": "SSMF",
"dispersion": 1.67e-05,
"effective_area": 83e-12,
"pmd_coef": 1.265e-15
}
],
"Span": [{
"power_mode": true,
"delta_power_range_db": [0, 0, 0.5],
"max_fiber_lineic_loss_for_raman": 0.25,
"target_extended_gain": 2.5,
"max_length": 150,
"length_units": "km",
"max_loss": 28,
"padding": 10,
"EOL": 0,
"con_in": 0,
"con_out": 0
}
],
"Roadm": [{
"target_out_mWperSlotWidth": 2.0e-4,
"add_drop_osnr": 38,
"pmd": 0,
"pdl": 0,
"restrictions": {
"preamp_variety_list": [],
"booster_variety_list": []
}
}
],
"SI": [{
"f_min": 191.35e12,
"f_max": 196.1e12,
"baud_rate": 32e9,
"spacing": 50e9,
"power_dbm": 0,
"power_range_db": [0, 0, 0.5],
"roll_off": 0.15,
"tx_osnr": 100,
"sys_margins": 0
}
],
"Transceiver": [{
"type_variety": "vendorA_trx-type1",
"frequency": {
"min": 191.4e12,
"max": 196.1e12
},
"mode": [{
"format": "PS_SP64_1",
"baud_rate": 32e9,
"OSNR": 11,
"bit_rate": 100e9,
"roll_off": 0.15,
"tx_osnr": 100,
"min_spacing": 50e9,
"cost": 1
}, {
"format": "PS_SP64_2",
"baud_rate": 64e9,
"OSNR": 15,
"bit_rate": 200e9,
"roll_off": 0.15,
"tx_osnr": 100,
"min_spacing": 75e9,
"cost": 1
}, {
"format": "mode 1",
"baud_rate": 32e9,
"OSNR": 11,
"bit_rate": 100e9,
"roll_off": 0.15,
"tx_osnr": 100,
"min_spacing": 50e9,
"cost": 1
}, {
"format": "mode 2",
"baud_rate": 64e9,
"OSNR": 15,
"bit_rate": 200e9,
"roll_off": 0.15,
"tx_osnr": 100,
"min_spacing": 75e9,
"cost": 1
}
]
}, {
"type_variety": "Voyager_16QAM",
"frequency": {
"min": 191.4e12,
"max": 196.1e12
},
"mode": [{
"format": "16QAM",
"baud_rate": 32e9,
"OSNR": 19,
"bit_rate": 200e9,
"roll_off": 0.15,
"tx_osnr": 100,
"min_spacing": 50e9,
"cost": 1
}
]
}, {
"type_variety": "Voyager",
"frequency": {
"min": 191.4e12,
"max": 196.1e12
},
"mode": [{
"format": "mode 1",
"baud_rate": 32e9,
"OSNR": 12,
"bit_rate": 100e9,
"roll_off": 0.15,
"tx_osnr": 45,
"min_spacing": 50e9,
"cost": 1
}, {
"format": "mode 3",
"baud_rate": 44e9,
"OSNR": 18,
"bit_rate": 300e9,
"roll_off": 0.15,
"tx_osnr": 45,
"min_spacing": 62.5e9,
"cost": 1
}, {
"format": "mode 2",
"baud_rate": 66e9,
"OSNR": 21,
"bit_rate": 400e9,
"roll_off": 0.15,
"tx_osnr": 45,
"min_spacing": 75e9,
"cost": 1
}, {
"format": "mode 2 - fake",
"baud_rate": 66e9,
"OSNR": 21,
"bit_rate": 400e9,
"roll_off": 0.15,
"tx_osnr": 45,
"min_spacing": 75e9,
"cost": 1
}, {
"format": "mode 4",
"baud_rate": 66e9,
"OSNR": 16,
"bit_rate": 200e9,
"roll_off": 0.15,
"tx_osnr": 45,
"min_spacing": 75e9,
"cost": 1
}
]
}
]
}

View File

@@ -0,0 +1,238 @@
{
"Edfa": [{
"type_variety": "CienaDB_medium_gain",
"type_def": "advanced_model",
"gain_flatmax": 25,
"gain_min": 15,
"p_max": 21,
"advanced_config_from_json": "std_medium_gain_advanced_config.json",
"out_voa_auto": false,
"allowed_for_design": true
},
{
"type_variety": "std_medium_gain",
"type_def": "variable_gain",
"gain_flatmax": 26,
"gain_min": 15,
"p_max": 21,
"nf_min": 6,
"nf_max": 10,
"out_voa_auto": false,
"allowed_for_design": true
},
{
"type_variety": "std_low_gain",
"type_def": "variable_gain",
"gain_flatmax": 16,
"gain_min": 8,
"p_max": 21,
"nf_min": 7,
"nf_max": 11,
"out_voa_auto": false,
"allowed_for_design": true
},
{
"type_variety": "test",
"type_def": "variable_gain",
"gain_flatmax": 25,
"gain_min": 15,
"p_max": 21,
"nf_min": 5.8,
"nf_max": 10,
"out_voa_auto": false,
"allowed_for_design": true
},
{
"type_variety": "test_fixed_gain",
"type_def": "fixed_gain",
"gain_flatmax": 21,
"gain_min": 20,
"p_max": 21,
"nf0": 5,
"allowed_for_design": true
},
{
"type_variety": "std_booster",
"type_def": "fixed_gain",
"gain_flatmax": 21,
"gain_min": 20,
"p_max": 21,
"nf0": 5,
"allowed_for_design": false
}
],
"Fiber": [{
"type_variety": "SSMF",
"dispersion": 1.67e-05,
"effective_area": 83e-12,
"pmd_coef": 1.265e-15
}
],
"Span": [{
"power_mode":true,
"delta_power_range_db": [0,0,0.5],
"max_fiber_lineic_loss_for_raman": 0.25,
"target_extended_gain": 2.5,
"max_length": 150,
"length_units": "km",
"max_loss": 28,
"padding": 10,
"EOL": 0,
"con_in": 0,
"con_out": 0
}
],
"Roadm": [{
"target_pch_out_db": -20,
"add_drop_osnr": 38,
"pmd": 0,
"pdl": 0,
"restrictions": {
"preamp_variety_list":[],
"booster_variety_list":[]
}
}
],
"SI": [{
"f_min": 191.35e12,
"f_max": 196.1e12,
"baud_rate": 32e9,
"spacing": 50e9,
"power_dbm": 0,
"power_range_db": [-6,0,0.5],
"roll_off": 0.15,
"tx_osnr": 100,
"sys_margins": 0
}
],
"Transceiver":[
{
"type_variety": "vendorA_trx-type1",
"frequency":{
"min": 191.4e12,
"max": 196.1e12
},
"mode":[
{
"format": "PS_SP64_1",
"baud_rate": 32e9,
"OSNR": 11,
"bit_rate": 100e9,
"roll_off": 0.15,
"tx_osnr": 100,
"min_spacing": 50e9,
"cost": 1
},
{
"format": "PS_SP64_2",
"baud_rate": 64e9,
"OSNR": 15,
"bit_rate": 200e9,
"roll_off": 0.15,
"tx_osnr": 100,
"min_spacing": 75e9,
"cost": 1
},
{
"format": "mode 1",
"baud_rate": 32e9,
"OSNR": 11,
"bit_rate": 100e9,
"roll_off": 0.15,
"tx_osnr": 100,
"min_spacing": 50e9,
"cost": 1
},
{
"format": "mode 2",
"baud_rate": 64e9,
"OSNR": 15,
"bit_rate": 200e9,
"roll_off": 0.15,
"tx_osnr": 100,
"min_spacing": 75e9,
"cost": 1
}
]
},
{
"type_variety": "Voyager_16QAM",
"frequency": {
"min": 191.4e12,
"max": 196.1e12
},
"mode": [
{
"format": "16QAM",
"baud_rate": 32e9,
"OSNR": 19,
"bit_rate": 200e9,
"roll_off": 0.15,
"tx_osnr": 100,
"min_spacing": 50e9,
"cost": 1
}
]
},
{
"type_variety": "Voyager",
"frequency": {
"min": 191.4e12,
"max": 196.1e12
},
"mode": [
{
"format": "mode 1",
"baud_rate": 32e9,
"OSNR": 12,
"bit_rate": 100e9,
"roll_off": 0.15,
"tx_osnr": 45,
"min_spacing": 50e9,
"cost": 1
},
{
"format": "mode 3",
"baud_rate": 44e9,
"OSNR": 18,
"bit_rate": 300e9,
"roll_off": 0.15,
"tx_osnr": 45,
"min_spacing": 62.5e9,
"cost": 1
},
{
"format": "mode 2",
"baud_rate": 66e9,
"OSNR": 21,
"bit_rate": 400e9,
"roll_off": 0.15,
"tx_osnr": 45,
"min_spacing": 75e9,
"cost": 1
},
{
"format": "mode 2 - fake",
"baud_rate": 66e9,
"OSNR": 21,
"bit_rate": 400e9,
"roll_off": 0.15,
"tx_osnr": 45,
"min_spacing": 75e9,
"cost": 1
},
{
"format": "mode 4",
"baud_rate": 66e9,
"OSNR": 16,
"bit_rate": 200e9,
"roll_off": 0.15,
"tx_osnr": 45,
"min_spacing": 75e9,
"cost": 1
}
]
}
]
}

View File

@@ -240,7 +240,6 @@
"east edfa in Rennes_STA to Stbrieuc": -20, "east edfa in Rennes_STA to Stbrieuc": -20,
"east edfa in Rennes_STA to Ploermel": -20 "east edfa in Rennes_STA to Ploermel": -20
} }
}, },
"metadata": { "metadata": {
"location": { "location": {
@@ -310,7 +309,7 @@
], ],
"booster_variety_list": [] "booster_variety_list": []
}, },
"per_degree_pch_out_db":{ "per_degree_pch_out_db": {
"east edfa in b to a": -20, "east edfa in b to a": -20,
"east edfa in b to f": -20 "east edfa in b to f": -20
} }
@@ -333,7 +332,7 @@
"preamp_variety_list": [], "preamp_variety_list": [],
"booster_variety_list": [] "booster_variety_list": []
}, },
"per_degree_pch_out_db":{ "per_degree_pch_out_db": {
"east edfa in c to a": -20, "east edfa in c to a": -20,
"east edfa in c to d": -20, "east edfa in c to d": -20,
"east edfa in c to f": -20 "east edfa in c to f": -20
@@ -430,7 +429,7 @@
"per_degree_pch_out_db": { "per_degree_pch_out_db": {
"east edfa in g to e": -20, "east edfa in g to e": -20,
"east edfa in g to h": -20 "east edfa in g to h": -20
} }
}, },
"metadata": { "metadata": {
"location": { "location": {
@@ -1593,7 +1592,7 @@
"type": "Edfa", "type": "Edfa",
"type_variety": "std_medium_gain", "type_variety": "std_medium_gain",
"operational": { "operational": {
"gain_target": 18.5, "gain_target": 13.177288,
"delta_p": null, "delta_p": null,
"tilt_target": 0, "tilt_target": 0,
"out_voa": 0 "out_voa": 0
@@ -2235,7 +2234,7 @@
"type": "Edfa", "type": "Edfa",
"type_variety": "std_low_gain", "type_variety": "std_low_gain",
"operational": { "operational": {
"gain_target": 6.5, "gain_target": 11.822712,
"delta_p": null, "delta_p": null,
"tilt_target": 0, "tilt_target": 0,
"out_voa": 0 "out_voa": 0
@@ -2292,7 +2291,7 @@
"type": "Edfa", "type": "Edfa",
"type_variety": "std_low_gain", "type_variety": "std_low_gain",
"operational": { "operational": {
"gain_target": 13.82, "gain_target": 13.822712,
"delta_p": null, "delta_p": null,
"tilt_target": 0, "tilt_target": 0,
"out_voa": 0 "out_voa": 0
@@ -2311,7 +2310,7 @@
"type": "Edfa", "type": "Edfa",
"type_variety": "test_fixed_gain", "type_variety": "test_fixed_gain",
"operational": { "operational": {
"gain_target": 15.18, "gain_target": 15.177288,
"delta_p": null, "delta_p": null,
"tilt_target": 0, "tilt_target": 0,
"out_voa": 0 "out_voa": 0

View File

@@ -0,0 +1,307 @@
INFO gnpy.tools.cli_examples:cli_examples.py source = 'brest'
INFO gnpy.tools.cli_examples:cli_examples.py destination = 'rennes'
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in Lorient_KMA to Loudeac
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: effective gain in Node east edfa in Lannion_CAS to Stbrieuc
is above user specified amplifier std_low_gain
max flat gain: 16dB ; required gain: 21.22dB. Please check amplifier type.
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in Rennes_STA to Stbrieuc
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: effective gain in Node east edfa in Lannion_CAS to Morlaix
is above user specified amplifier std_low_gain
max flat gain: 16dB ; required gain: 21.22dB. Please check amplifier type.
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in Brest_KLA to Morlaix
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in Lorient_KMA to Loudeac
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: effective gain in Node west edfa in Lannion_CAS to Corlay
is above user specified amplifier test
max flat gain: 25dB ; required gain: 28.0dB. Please check amplifier type.
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in Lorient_KMA to Vannes_KBE
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in Vannes_KBE to Lorient_KMA
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in Lorient_KMA to Quimper
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in Quimper to Lorient_KMA
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in Brest_KLA to Quimper
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in Vannes_KBE to Lorient_KMA
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in Lorient_KMA to Vannes_KBE
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in Vannes_KBE to Ploermel
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in Ploermel to Vannes_KBE
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in Rennes_STA to Ploermel
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in Rennes_STA to Stbrieuc
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in Stbrieuc to Rennes_STA
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in Lannion_CAS to Stbrieuc
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in Rennes_STA to Ploermel
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in Vannes_KBE to Ploermel
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in Brest_KLA to Morlaix
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: effective gain in Node east edfa in Brest_KLA to Quimper
is above user specified amplifier std_low_gain
max flat gain: 16dB ; required gain: 21.22dB. Please check amplifier type.
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in Quimper to Lorient_KMA
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in Lorient_KMA to Quimper
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in a to b
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in b to a
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in a to c
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in c to a
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in b to a
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in a to b
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in b to f
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in f to b
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in c to a
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in a to c
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in d to c
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in c to f
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in f to c
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in d to c
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in c to d
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in d to e
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in e to d
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in e to d
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in d to e
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in e to g
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in g to e
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in f to c
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in c to f
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in f to b
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in b to f
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in f to h
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in h to f
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in g to e
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in e to g
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in g to h
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in h to g
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in h to f
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in f to h
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in h to g
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied
WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in g to h
is beyond all available amplifiers capabilities and/or extended_gain_range:
a power reduction of -1.78 is applied

View File

@@ -8,7 +8,7 @@ WARNING gnpy.core.network:network.py
WARNING gnpy.core.network:network.py WARNING gnpy.core.network:network.py
WARNING: effective gain in Node east edfa in Lannion_CAS to Stbrieuc WARNING: effective gain in Node east edfa in Lannion_CAS to Stbrieuc
is above user specified amplifier std_low_gain is above user specified amplifier std_low_gain
max flat gain: 16dB ; required gain: 23.0dB. Please check amplifier type. max flat gain: 16dB ; required gain: 21.18dB. Please check amplifier type.
WARNING gnpy.core.network:network.py WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in Rennes_STA to Stbrieuc WARNING: target gain and power in node west edfa in Rennes_STA to Stbrieuc
@@ -18,7 +18,7 @@ WARNING gnpy.core.network:network.py
WARNING gnpy.core.network:network.py WARNING gnpy.core.network:network.py
WARNING: effective gain in Node east edfa in Lannion_CAS to Morlaix WARNING: effective gain in Node east edfa in Lannion_CAS to Morlaix
is above user specified amplifier std_low_gain is above user specified amplifier std_low_gain
max flat gain: 16dB ; required gain: 23.5dB. Please check amplifier type. max flat gain: 16dB ; required gain: 21.18dB. Please check amplifier type.
WARNING gnpy.core.network:network.py WARNING gnpy.core.network:network.py
WARNING: target gain and power in node west edfa in Brest_KLA to Morlaix WARNING: target gain and power in node west edfa in Brest_KLA to Morlaix
@@ -33,7 +33,7 @@ WARNING gnpy.core.network:network.py
WARNING gnpy.core.network:network.py WARNING gnpy.core.network:network.py
WARNING: effective gain in Node west edfa in Lannion_CAS to Corlay WARNING: effective gain in Node west edfa in Lannion_CAS to Corlay
is above user specified amplifier test is above user specified amplifier test
max flat gain: 25dB ; required gain: 29.82dB. Please check amplifier type. max flat gain: 25dB ; required gain: 28.0dB. Please check amplifier type.
WARNING gnpy.core.network:network.py WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in Lorient_KMA to Vannes_KBE WARNING: target gain and power in node east edfa in Lorient_KMA to Vannes_KBE
@@ -118,7 +118,7 @@ WARNING gnpy.core.network:network.py
WARNING gnpy.core.network:network.py WARNING gnpy.core.network:network.py
WARNING: effective gain in Node east edfa in Brest_KLA to Quimper WARNING: effective gain in Node east edfa in Brest_KLA to Quimper
is above user specified amplifier std_low_gain is above user specified amplifier std_low_gain
max flat gain: 16dB ; required gain: 23.0dB. Please check amplifier type. max flat gain: 16dB ; required gain: 21.18dB. Please check amplifier type.
WARNING gnpy.core.network:network.py WARNING gnpy.core.network:network.py
WARNING: target gain and power in node east edfa in Quimper to Lorient_KMA WARNING: target gain and power in node east edfa in Quimper to Lorient_KMA

View File

@@ -31,7 +31,6 @@ Edfa Edfa_booster_roadm_Stockholm_to_fiber (Stockholm → Norrköping)_(1/2)
Power Out (dBm): 21.82 Power Out (dBm): 21.82
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 2.00 target pch (dBm): 2.00
effective pch (dBm): 2.00
actual pch out (dBm): 2.00 actual pch out (dBm): 2.00
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber fiber (Stockholm → Norrköping)_(1/2) Fiber fiber (Stockholm → Norrköping)_(1/2)
@@ -54,8 +53,7 @@ Edfa Edfa_fiber (Stockholm → Norrköping)_(1/2)
Power Out (dBm): 21.84 Power Out (dBm): 21.84
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 2.00 target pch (dBm): 2.00
effective pch (dBm): 2.00 actual pch out (dBm): 2.01
actual pch out (dBm): 2.02
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber fiber (Stockholm → Norrköping)_(2/2) Fiber fiber (Stockholm → Norrköping)_(2/2)
type_variety: SSMF type_variety: SSMF
@@ -65,7 +63,7 @@ Fiber fiber (Stockholm → Norrköping)_(2/2)
(includes conn loss (dB) in: 0.00 out: 0.00) (includes conn loss (dB) in: 0.00 out: 0.00)
(conn loss out includes EOL margin defined in eqpt_config.json) (conn loss out includes EOL margin defined in eqpt_config.json)
reference pch out (dBm): -14.33 reference pch out (dBm): -14.33
actual pch out (dBm): -14.29 actual pch out (dBm): -14.30
Edfa Edfa_preamp_roadm_Norrköping_from_fiber (Stockholm → Norrköping)_(2/2) Edfa Edfa_preamp_roadm_Norrköping_from_fiber (Stockholm → Norrköping)_(2/2)
type_variety: openroadm_mw_mw_preamp type_variety: openroadm_mw_mw_preamp
effective gain(dB): 16.33 effective gain(dB): 16.33
@@ -73,12 +71,11 @@ Edfa Edfa_preamp_roadm_Norrköping_from_fiber (Stockholm → Norrköping)_(2/2)
noise figure (dB): 12.59 noise figure (dB): 12.59
(including att_in) (including att_in)
pad att_in (dB): 0.00 pad att_in (dB): 0.00
Power In (dBm): 5.53 Power In (dBm): 5.52
Power Out (dBm): 21.87 Power Out (dBm): 21.86
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 2.00 target pch (dBm): 2.00
effective pch (dBm): 2.00 actual pch out (dBm): 2.03
actual pch out (dBm): 2.04
output VOA (dB): 0.00 output VOA (dB): 0.00
Roadm roadm_Norrköping Roadm roadm_Norrköping
effective loss (dB): 22.00 effective loss (dB): 22.00
@@ -95,7 +92,6 @@ Edfa Edfa_booster_roadm_Norrköping_to_fiber (Norrköping → Linköping)
Power Out (dBm): 21.82 Power Out (dBm): 21.82
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 2.00 target pch (dBm): 2.00
effective pch (dBm): 2.00
actual pch out (dBm): 2.00 actual pch out (dBm): 2.00
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber fiber (Norrköping → Linköping) Fiber fiber (Norrköping → Linköping)
@@ -118,7 +114,6 @@ Edfa Edfa_preamp_roadm_Linköping_from_fiber (Norrköping → Linköping)
Power Out (dBm): 21.83 Power Out (dBm): 21.83
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 2.00 target pch (dBm): 2.00
effective pch (dBm): 2.00
actual pch out (dBm): 2.01 actual pch out (dBm): 2.01
output VOA (dB): 0.00 output VOA (dB): 0.00
Roadm roadm_Linköping Roadm roadm_Linköping
@@ -136,7 +131,6 @@ Edfa Edfa_booster_roadm_Linköping_to_fiber (Linköping → Jönköping)
Power Out (dBm): 21.82 Power Out (dBm): 21.82
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 2.00 target pch (dBm): 2.00
effective pch (dBm): 2.00
actual pch out (dBm): 2.00 actual pch out (dBm): 2.00
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber fiber (Linköping → Jönköping) Fiber fiber (Linköping → Jönköping)
@@ -156,11 +150,10 @@ Edfa Edfa_preamp_roadm_Jönköping_from_fiber (Linköping → Jönköping)
(including att_in) (including att_in)
pad att_in (dB): 0.00 pad att_in (dB): 0.00
Power In (dBm): -4.97 Power In (dBm): -4.97
Power Out (dBm): 21.86 Power Out (dBm): 21.87
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 2.00 target pch (dBm): 2.00
effective pch (dBm): 2.00 actual pch out (dBm): 2.05
actual pch out (dBm): 2.04
output VOA (dB): 0.00 output VOA (dB): 0.00
Roadm roadm_Jönköping Roadm roadm_Jönköping
effective loss (dB): 22.00 effective loss (dB): 22.00
@@ -177,7 +170,6 @@ Edfa Edfa_booster_roadm_Jönköping_to_fiber (Jönköping → Borås)
Power Out (dBm): 21.82 Power Out (dBm): 21.82
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 2.00 target pch (dBm): 2.00
effective pch (dBm): 2.00
actual pch out (dBm): 2.00 actual pch out (dBm): 2.00
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber fiber (Jönköping → Borås) Fiber fiber (Jönköping → Borås)
@@ -200,7 +192,6 @@ Edfa Edfa_preamp_roadm_Borås_from_fiber (Jönköping → Borås)
Power Out (dBm): 21.84 Power Out (dBm): 21.84
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 2.00 target pch (dBm): 2.00
effective pch (dBm): 2.00
actual pch out (dBm): 2.02 actual pch out (dBm): 2.02
output VOA (dB): 0.00 output VOA (dB): 0.00
Roadm roadm_Borås Roadm roadm_Borås
@@ -218,7 +209,6 @@ Edfa Edfa_booster_roadm_Borås_to_fiber (Borås → Gothenburg)
Power Out (dBm): 21.82 Power Out (dBm): 21.82
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 2.00 target pch (dBm): 2.00
effective pch (dBm): 2.00
actual pch out (dBm): 2.00 actual pch out (dBm): 2.00
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber fiber (Borås → Gothenburg) Fiber fiber (Borås → Gothenburg)
@@ -241,7 +231,6 @@ Edfa Edfa_preamp_roadm_Gothenburg_from_fiber (Borås → Gothenburg)
Power Out (dBm): 21.84 Power Out (dBm): 21.84
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 2.00 target pch (dBm): 2.00
effective pch (dBm): 2.00
actual pch out (dBm): 2.02 actual pch out (dBm): 2.02
output VOA (dB): 0.00 output VOA (dB): 0.00
Roadm roadm_Gothenburg Roadm roadm_Gothenburg

View File

@@ -31,7 +31,6 @@ Edfa Edfa_booster_roadm_Stockholm_to_fiber (Stockholm → Norrköping)_(1/2)
Power Out (dBm): 21.82 Power Out (dBm): 21.82
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 2.00 target pch (dBm): 2.00
effective pch (dBm): 2.00
actual pch out (dBm): 2.00 actual pch out (dBm): 2.00
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber fiber (Stockholm → Norrköping)_(1/2) Fiber fiber (Stockholm → Norrköping)_(1/2)
@@ -54,8 +53,7 @@ Edfa Edfa_fiber (Stockholm → Norrköping)_(1/2)
Power Out (dBm): 21.84 Power Out (dBm): 21.84
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 2.00 target pch (dBm): 2.00
effective pch (dBm): 2.00 actual pch out (dBm): 2.01
actual pch out (dBm): 2.02
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber fiber (Stockholm → Norrköping)_(2/2) Fiber fiber (Stockholm → Norrköping)_(2/2)
type_variety: SSMF type_variety: SSMF
@@ -65,20 +63,19 @@ Fiber fiber (Stockholm → Norrköping)_(2/2)
(includes conn loss (dB) in: 0.00 out: 0.00) (includes conn loss (dB) in: 0.00 out: 0.00)
(conn loss out includes EOL margin defined in eqpt_config.json) (conn loss out includes EOL margin defined in eqpt_config.json)
reference pch out (dBm): -14.33 reference pch out (dBm): -14.33
actual pch out (dBm): -14.29 actual pch out (dBm): -14.30
Edfa Edfa_preamp_roadm_Norrköping_from_fiber (Stockholm → Norrköping)_(2/2) Edfa Edfa_preamp_roadm_Norrköping_from_fiber (Stockholm → Norrköping)_(2/2)
type_variety: openroadm_mw_mw_preamp_worstcase_ver5 type_variety: openroadm_mw_mw_preamp_worstcase_ver5
effective gain(dB): 16.33 effective gain(dB): 16.33
(before att_in and before output VOA) (before att_in and before output VOA)
noise figure (dB): 11.44 noise figure (dB): 11.43
(including att_in) (including att_in)
pad att_in (dB): 0.00 pad att_in (dB): 0.00
Power In (dBm): 5.53 Power In (dBm): 5.52
Power Out (dBm): 21.86 Power Out (dBm): 21.85
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 2.00 target pch (dBm): 2.00
effective pch (dBm): 2.00 actual pch out (dBm): 2.03
actual pch out (dBm): 2.04
output VOA (dB): 0.00 output VOA (dB): 0.00
Roadm roadm_Norrköping Roadm roadm_Norrköping
effective loss (dB): 22.00 effective loss (dB): 22.00
@@ -95,7 +92,6 @@ Edfa Edfa_booster_roadm_Norrköping_to_fiber (Norrköping → Linköping)
Power Out (dBm): 21.82 Power Out (dBm): 21.82
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 2.00 target pch (dBm): 2.00
effective pch (dBm): 2.00
actual pch out (dBm): 2.00 actual pch out (dBm): 2.00
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber fiber (Norrköping → Linköping) Fiber fiber (Norrköping → Linköping)
@@ -118,7 +114,6 @@ Edfa Edfa_preamp_roadm_Linköping_from_fiber (Norrköping → Linköping)
Power Out (dBm): 21.83 Power Out (dBm): 21.83
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 2.00 target pch (dBm): 2.00
effective pch (dBm): 2.00
actual pch out (dBm): 2.01 actual pch out (dBm): 2.01
output VOA (dB): 0.00 output VOA (dB): 0.00
Roadm roadm_Linköping Roadm roadm_Linköping
@@ -136,7 +131,6 @@ Edfa Edfa_booster_roadm_Linköping_to_fiber (Linköping → Jönköping)
Power Out (dBm): 21.82 Power Out (dBm): 21.82
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 2.00 target pch (dBm): 2.00
effective pch (dBm): 2.00
actual pch out (dBm): 2.00 actual pch out (dBm): 2.00
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber fiber (Linköping → Jönköping) Fiber fiber (Linköping → Jönköping)
@@ -156,10 +150,9 @@ Edfa Edfa_preamp_roadm_Jönköping_from_fiber (Linköping → Jönköping)
(including att_in) (including att_in)
pad att_in (dB): 0.00 pad att_in (dB): 0.00
Power In (dBm): -4.97 Power In (dBm): -4.97
Power Out (dBm): 21.86 Power Out (dBm): 21.87
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 2.00 target pch (dBm): 2.00
effective pch (dBm): 2.00
actual pch out (dBm): 2.04 actual pch out (dBm): 2.04
output VOA (dB): 0.00 output VOA (dB): 0.00
Roadm roadm_Jönköping Roadm roadm_Jönköping
@@ -177,7 +170,6 @@ Edfa Edfa_booster_roadm_Jönköping_to_fiber (Jönköping → Borås)
Power Out (dBm): 21.82 Power Out (dBm): 21.82
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 2.00 target pch (dBm): 2.00
effective pch (dBm): 2.00
actual pch out (dBm): 2.00 actual pch out (dBm): 2.00
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber fiber (Jönköping → Borås) Fiber fiber (Jönköping → Borås)
@@ -200,8 +192,7 @@ Edfa Edfa_preamp_roadm_Borås_from_fiber (Jönköping → Borås)
Power Out (dBm): 21.84 Power Out (dBm): 21.84
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 2.00 target pch (dBm): 2.00
effective pch (dBm): 2.00 actual pch out (dBm): 2.02
actual pch out (dBm): 2.01
output VOA (dB): 0.00 output VOA (dB): 0.00
Roadm roadm_Borås Roadm roadm_Borås
effective loss (dB): 22.00 effective loss (dB): 22.00
@@ -218,7 +209,6 @@ Edfa Edfa_booster_roadm_Borås_to_fiber (Borås → Gothenburg)
Power Out (dBm): 21.82 Power Out (dBm): 21.82
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 2.00 target pch (dBm): 2.00
effective pch (dBm): 2.00
actual pch out (dBm): 2.00 actual pch out (dBm): 2.00
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber fiber (Borås → Gothenburg) Fiber fiber (Borås → Gothenburg)
@@ -241,7 +231,6 @@ Edfa Edfa_preamp_roadm_Gothenburg_from_fiber (Borås → Gothenburg)
Power Out (dBm): 21.84 Power Out (dBm): 21.84
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 2.00 target pch (dBm): 2.00
effective pch (dBm): 2.00
actual pch out (dBm): 2.02 actual pch out (dBm): 2.02
output VOA (dB): 0.00 output VOA (dB): 0.00
Roadm roadm_Gothenburg Roadm roadm_Gothenburg

View File

@@ -0,0 +1,154 @@
There are 95 channels propagating
Power mode is set to True
=> it can be modified in eqpt_config.json - Span
There are 4 fiber spans over 200 km between trx Brest_KLA and trx Rennes_STA
Now propagating between trx Brest_KLA and trx Rennes_STA:
Propagating with input power = -3.00 dBm:
Transceiver trx Rennes_STA
GSNR (0.1nm, dB): 23.73
GSNR (signal bw, dB): 19.65
OSNR ASE (0.1nm, dB): 23.99
OSNR ASE (signal bw, dB): 19.91
CD (ps/nm): 3340.00
PMD (ps): 0.57
PDL (dB): 0.00
Latency (ms): 0.98
Propagating with input power = -2.50 dBm:
Transceiver trx Rennes_STA
GSNR (0.1nm, dB): 24.01
GSNR (signal bw, dB): 19.93
OSNR ASE (0.1nm, dB): 24.37
OSNR ASE (signal bw, dB): 20.29
CD (ps/nm): 3340.00
PMD (ps): 0.57
PDL (dB): 0.00
Latency (ms): 0.98
Propagating with input power = -2.00 dBm:
Transceiver trx Rennes_STA
GSNR (0.1nm, dB): 24.25
GSNR (signal bw, dB): 20.17
OSNR ASE (0.1nm, dB): 24.74
OSNR ASE (signal bw, dB): 20.66
CD (ps/nm): 3340.00
PMD (ps): 0.57
PDL (dB): 0.00
Latency (ms): 0.98
Propagating with input power = -1.50 dBm:
Transceiver trx Rennes_STA
GSNR (0.1nm, dB): 24.44
GSNR (signal bw, dB): 20.36
OSNR ASE (0.1nm, dB): 25.10
OSNR ASE (signal bw, dB): 21.01
CD (ps/nm): 3340.00
PMD (ps): 0.57
PDL (dB): 0.00
Latency (ms): 0.98
Propagating with input power = -1.00 dBm:
Transceiver trx Rennes_STA
GSNR (0.1nm, dB): 24.57
GSNR (signal bw, dB): 20.49
OSNR ASE (0.1nm, dB): 25.44
OSNR ASE (signal bw, dB): 21.36
CD (ps/nm): 3340.00
PMD (ps): 0.57
PDL (dB): 0.00
Latency (ms): 0.98
Propagating with input power = -0.50 dBm:
Transceiver trx Rennes_STA
GSNR (0.1nm, dB): 24.63
GSNR (signal bw, dB): 20.55
OSNR ASE (0.1nm, dB): 25.77
OSNR ASE (signal bw, dB): 21.69
CD (ps/nm): 3340.00
PMD (ps): 0.57
PDL (dB): 0.00
Latency (ms): 0.98
Propagating with input power = -0.00 dBm:
Transceiver trx Rennes_STA
GSNR (0.1nm, dB): 24.60
GSNR (signal bw, dB): 20.52
OSNR ASE (0.1nm, dB): 26.09
OSNR ASE (signal bw, dB): 22.00
CD (ps/nm): 3340.00
PMD (ps): 0.57
PDL (dB): 0.00
Latency (ms): 0.98
Propagating with input power = 0.50 dBm:
Transceiver trx Rennes_STA
GSNR (0.1nm, dB): 24.42
GSNR (signal bw, dB): 20.34
OSNR ASE (0.1nm, dB): 26.29
OSNR ASE (signal bw, dB): 22.20
CD (ps/nm): 3340.00
PMD (ps): 0.57
PDL (dB): 0.00
Latency (ms): 0.98
Propagating with input power = 1.00 dBm:
Transceiver trx Rennes_STA
GSNR (0.1nm, dB): 24.16
GSNR (signal bw, dB): 20.08
OSNR ASE (0.1nm, dB): 26.47
OSNR ASE (signal bw, dB): 22.39
CD (ps/nm): 3340.00
PMD (ps): 0.57
PDL (dB): 0.00
Latency (ms): 0.98
Propagating with input power = 1.50 dBm:
Transceiver trx Rennes_STA
GSNR (0.1nm, dB): 24.02
GSNR (signal bw, dB): 19.93
OSNR ASE (0.1nm, dB): 26.55
OSNR ASE (signal bw, dB): 22.47
CD (ps/nm): 3340.00
PMD (ps): 0.57
PDL (dB): 0.00
Latency (ms): 0.98
Propagating with input power = 2.00 dBm:
Transceiver trx Rennes_STA
GSNR (0.1nm, dB): 24.02
GSNR (signal bw, dB): 19.93
OSNR ASE (0.1nm, dB): 26.55
OSNR ASE (signal bw, dB): 22.47
CD (ps/nm): 3340.00
PMD (ps): 0.57
PDL (dB): 0.00
Latency (ms): 0.98
Propagating with input power = 2.50 dBm:
Transceiver trx Rennes_STA
GSNR (0.1nm, dB): 24.02
GSNR (signal bw, dB): 19.93
OSNR ASE (0.1nm, dB): 26.55
OSNR ASE (signal bw, dB): 22.47
CD (ps/nm): 3340.00
PMD (ps): 0.57
PDL (dB): 0.00
Latency (ms): 0.98
Propagating with input power = 3.00 dBm:
Transceiver trx Rennes_STA
GSNR (0.1nm, dB): 24.02
GSNR (signal bw, dB): 19.93
OSNR ASE (0.1nm, dB): 26.55
OSNR ASE (signal bw, dB): 22.47
CD (ps/nm): 3340.00
PMD (ps): 0.57
PDL (dB): 0.00
Latency (ms): 0.98
(Invalid source node 'brest' replaced with trx Brest_KLA)
(Invalid destination node 'rennes' replaced with trx Rennes_STA)

View File

@@ -32,7 +32,6 @@ Edfa east edfa in Lannion_CAS to Corlay
Power Out (dBm): 19.82 Power Out (dBm): 19.82
Delta_P (dB): 1.00 Delta_P (dB): 1.00
target pch (dBm): 1.00 target pch (dBm): 1.00
effective pch (dBm): 1.00
actual pch out (dBm): 1.01 actual pch out (dBm): 1.01
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber fiber (Lannion_CAS → Corlay)-F061 Fiber fiber (Lannion_CAS → Corlay)-F061
@@ -77,7 +76,6 @@ Edfa west edfa in Lorient_KMA to Loudeac
Power Out (dBm): 19.85 Power Out (dBm): 19.85
Delta_P (dB): 1.00 Delta_P (dB): 1.00
target pch (dBm): 1.00 target pch (dBm): 1.00
effective pch (dBm): 1.00
actual pch out (dBm): 1.05 actual pch out (dBm): 1.05
output VOA (dB): 0.00 output VOA (dB): 0.00
Roadm roadm Lorient_KMA Roadm roadm Lorient_KMA

View File

@@ -32,7 +32,6 @@ Edfa east edfa in Lannion_CAS to Corlay
Power Out (dBm): 18.79 Power Out (dBm): 18.79
Delta_P (dB): 1.00 Delta_P (dB): 1.00
target pch (dBm): 1.00 target pch (dBm): 1.00
effective pch (dBm): 1.00
actual pch out (dBm): mode_1: 1.01, mode_2: 1.02 actual pch out (dBm): mode_1: 1.01, mode_2: 1.02
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber fiber (Lannion_CAS → Corlay)-F061 Fiber fiber (Lannion_CAS → Corlay)-F061
@@ -77,7 +76,6 @@ Edfa west edfa in Lorient_KMA to Loudeac
Power Out (dBm): 18.84 Power Out (dBm): 18.84
Delta_P (dB): 1.00 Delta_P (dB): 1.00
target pch (dBm): 1.00 target pch (dBm): 1.00
effective pch (dBm): 1.00
actual pch out (dBm): mode_1: 1.04, mode_2: 1.09 actual pch out (dBm): mode_1: 1.04, mode_2: 1.09
output VOA (dB): 0.00 output VOA (dB): 0.00
Roadm roadm Lorient_KMA Roadm roadm Lorient_KMA

View File

@@ -0,0 +1,437 @@
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 15 fiber spans over 1200 km between Site_A and Site_B
Now propagating between Site_A and Site_B:
Propagating with input power = 0.00 dBm:
Transceiver Site_A
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
Latency (ms): 0.00
Roadm roadm Site A
effective loss (dB): 20.00
reference pch out (dBm): -20.00
actual pch out (dBm): mode_1: -20.00, mode_2: -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): -2.22
Power Out (dBm): 17.79
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.01, mode_2: 0.02
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): mode_1: -15.99, mode_2: -15.98
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): 1.80
Power Out (dBm): 17.80
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.02, mode_2: 0.03
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): mode_1: -15.98, mode_2: -15.97
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): 1.81
Power Out (dBm): 17.81
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.03, mode_2: 0.04
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): mode_1: -15.97, mode_2: -15.96
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): 1.82
Power Out (dBm): 17.82
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.04, mode_2: 0.05
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): mode_1: -15.96, mode_2: -15.94
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): 1.83
Power Out (dBm): 17.84
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.04, mode_2: 0.07
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): mode_1: -15.95, mode_2: -15.93
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): 1.84
Power Out (dBm): 17.85
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.05, mode_2: 0.08
output VOA (dB): 0.00
Roadm roadm Site C
effective loss (dB): 20.00
reference pch out (dBm): -20.00
actual pch out (dBm): mode_1: -20.00, mode_2: -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): -2.22
Power Out (dBm): 17.79
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.01, mode_2: 0.02
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): mode_1: -15.99, mode_2: -15.98
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): 1.80
Power Out (dBm): 17.80
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.02, mode_2: 0.03
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): mode_1: -15.98, mode_2: -15.97
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): 1.81
Power Out (dBm): 17.81
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.03, mode_2: 0.04
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): mode_1: -15.97, mode_2: -15.96
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): 1.82
Power Out (dBm): 17.82
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.03, mode_2: 0.05
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): mode_1: -15.96, mode_2: -15.94
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): 1.83
Power Out (dBm): 17.83
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.04, mode_2: 0.07
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): mode_1: -15.95, mode_2: -15.93
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): 1.84
Power Out (dBm): 17.85
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.05, mode_2: 0.08
output VOA (dB): 0.00
Roadm roadm Site D
effective loss (dB): 20.00
reference pch out (dBm): -20.00
actual pch out (dBm): mode_1: -20.00, mode_2: -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): -2.22
Power Out (dBm): 17.79
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.01, mode_2: 0.02
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): mode_1: -15.99, mode_2: -15.98
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): 1.80
Power Out (dBm): 17.80
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.02, mode_2: 0.03
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): mode_1: -15.98, mode_2: -15.97
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): 1.81
Power Out (dBm): 17.81
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.03, mode_2: 0.04
output VOA (dB): 0.00
Roadm roadm Site E
effective loss (dB): 20.00
reference pch out (dBm): -20.00
actual pch out (dBm): mode_1: -20.00, mode_2: -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): -2.22
Power Out (dBm): 17.79
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.01, mode_2: 0.02
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): mode_1: -15.99, mode_2: -15.98
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): 1.80
Power Out (dBm): 17.80
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.02, mode_2: 0.03
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): mode_1: -15.98, mode_2: -15.97
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): 1.81
Power Out (dBm): 17.81
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.03, mode_2: 0.04
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): mode_1: -15.97, mode_2: -15.96
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): 1.82
Power Out (dBm): 17.82
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.03, mode_2: 0.05
output VOA (dB): 0.00
Roadm roadm Site B
effective loss (dB): 20.00
reference pch out (dBm): -20.00
actual pch out (dBm): mode_1: -20.00, mode_2: -20.00
Transceiver Site_B
GSNR (0.1nm, dB): mode_1: 18.11, mode_2: 19.18
GSNR (signal bw, dB): mode_1: 14.02, mode_2: 12.09
OSNR ASE (0.1nm, dB): mode_1: 19.69, mode_2: 19.62
OSNR ASE (signal bw, dB): mode_1: 15.61, mode_2: 12.53
CD (ps/nm): 20040.00
PMD (ps): 1.39
PDL (dB): 0.00
Latency (ms): 5.88
Transmission result for input power = 0.00 dBm:
Final GSNR (0.1 nm): 18.56 dB
(No source node specified: picked Site_A)
(No destination node specified: picked Site_B)

View File

@@ -0,0 +1,437 @@
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 15 fiber spans over 1200 km between Site_A and Site_B
Now propagating between Site_A and Site_B:
Propagating with input power = 0.00 dBm:
Transceiver Site_A
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
Latency (ms): 0.00
Roadm roadm Site A
effective loss (dB): 20.00
reference pch out (dBm): -20.00
actual pch out (dBm): mode_1: -20.00, mode_2: -16.99
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.71
Power Out (dBm): 19.30
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.01, mode_2: 3.02
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): mode_1: -15.99, mode_2: -12.98
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.31
Power Out (dBm): 19.31
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.02, mode_2: 3.03
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): mode_1: -15.98, mode_2: -12.97
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.32
Power Out (dBm): 19.32
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.03, mode_2: 3.04
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): mode_1: -15.97, mode_2: -12.95
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.33
Power Out (dBm): 19.33
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.04, mode_2: 3.05
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): mode_1: -15.96, mode_2: -12.94
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.34
Power Out (dBm): 19.34
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.05, mode_2: 3.06
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): mode_1: -15.95, mode_2: -12.93
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.35
Power Out (dBm): 19.35
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.06, mode_2: 3.07
output VOA (dB): 0.00
Roadm roadm Site C
effective loss (dB): 20.00
reference pch out (dBm): -20.00
actual pch out (dBm): mode_1: -20.00, mode_2: -16.99
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.71
Power Out (dBm): 19.30
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.01, mode_2: 3.02
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): mode_1: -15.99, mode_2: -12.98
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.31
Power Out (dBm): 19.31
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.02, mode_2: 3.03
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): mode_1: -15.98, mode_2: -12.97
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.32
Power Out (dBm): 19.32
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.03, mode_2: 3.04
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): mode_1: -15.97, mode_2: -12.95
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.33
Power Out (dBm): 19.33
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.04, mode_2: 3.05
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): mode_1: -15.96, mode_2: -12.94
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.34
Power Out (dBm): 19.34
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.05, mode_2: 3.06
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): mode_1: -15.95, mode_2: -12.93
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.35
Power Out (dBm): 19.35
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.06, mode_2: 3.07
output VOA (dB): 0.00
Roadm roadm Site D
effective loss (dB): 20.00
reference pch out (dBm): -20.00
actual pch out (dBm): mode_1: -20.00, mode_2: -16.99
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.71
Power Out (dBm): 19.30
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.01, mode_2: 3.02
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): mode_1: -15.99, mode_2: -12.98
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.31
Power Out (dBm): 19.31
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.02, mode_2: 3.03
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): mode_1: -15.98, mode_2: -12.97
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.32
Power Out (dBm): 19.32
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.03, mode_2: 3.04
output VOA (dB): 0.00
Roadm roadm Site E
effective loss (dB): 20.00
reference pch out (dBm): -20.00
actual pch out (dBm): mode_1: -20.00, mode_2: -16.99
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.71
Power Out (dBm): 19.30
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.01, mode_2: 3.02
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): mode_1: -15.99, mode_2: -12.98
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.31
Power Out (dBm): 19.31
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.02, mode_2: 3.03
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): mode_1: -15.98, mode_2: -12.97
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.32
Power Out (dBm): 19.32
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.03, mode_2: 3.04
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): mode_1: -15.97, mode_2: -12.96
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.33
Power Out (dBm): 19.33
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.04, mode_2: 3.05
output VOA (dB): 0.00
Roadm roadm Site B
effective loss (dB): 20.00
reference pch out (dBm): -20.00
actual pch out (dBm): mode_1: -20.00, mode_2: -16.99
Transceiver Site_B
GSNR (0.1nm, dB): mode_1: 17.91, mode_2: 20.37
GSNR (signal bw, dB): mode_1: 13.83, mode_2: 13.28
OSNR ASE (0.1nm, dB): mode_1: 19.69, mode_2: 22.55
OSNR ASE (signal bw, dB): mode_1: 15.61, mode_2: 15.46
CD (ps/nm): 20040.00
PMD (ps): 1.39
PDL (dB): 0.00
Latency (ms): 5.88
Transmission result for input power = 0.00 dBm:
Final GSNR (0.1 nm): 18.94 dB
(No source node specified: picked Site_A)
(No destination node specified: picked Site_B)

View File

@@ -0,0 +1,437 @@
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 15 fiber spans over 1200 km between Site_A and Site_B
Now propagating between Site_A and Site_B:
Propagating with input power = 0.00 dBm:
Transceiver Site_A
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
Latency (ms): 0.00
Roadm roadm Site A
effective loss (dB): 20.00
reference pch out (dBm): -20.00
actual pch out (dBm): mode_1: -20.00, mode_2: -18.24
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): -1.40
Power Out (dBm): 18.61
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.01, mode_2: 1.77
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): mode_1: -15.99, mode_2: -14.22
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): 2.62
Power Out (dBm): 18.62
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.02, mode_2: 1.78
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): mode_1: -15.98, mode_2: -14.21
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): 2.63
Power Out (dBm): 18.63
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.03, mode_2: 1.79
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): mode_1: -15.97, mode_2: -14.20
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): 2.64
Power Out (dBm): 18.64
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.04, mode_2: 1.80
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): mode_1: -15.96, mode_2: -14.19
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): 2.65
Power Out (dBm): 18.65
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.05, mode_2: 1.81
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): mode_1: -15.95, mode_2: -14.18
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): 2.66
Power Out (dBm): 18.66
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.05, mode_2: 1.82
output VOA (dB): 0.00
Roadm roadm Site C
effective loss (dB): 20.00
reference pch out (dBm): -20.00
actual pch out (dBm): mode_1: -20.00, mode_2: -18.24
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): -1.40
Power Out (dBm): 18.61
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.01, mode_2: 1.77
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): mode_1: -15.99, mode_2: -14.23
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): 2.62
Power Out (dBm): 18.62
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.02, mode_2: 1.78
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): mode_1: -15.98, mode_2: -14.21
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): 2.63
Power Out (dBm): 18.63
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.03, mode_2: 1.79
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): mode_1: -15.97, mode_2: -14.20
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): 2.64
Power Out (dBm): 18.64
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.04, mode_2: 1.80
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): mode_1: -15.96, mode_2: -14.19
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): 2.65
Power Out (dBm): 18.65
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.04, mode_2: 1.81
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): mode_1: -15.95, mode_2: -14.18
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): 2.66
Power Out (dBm): 18.66
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.05, mode_2: 1.82
output VOA (dB): 0.00
Roadm roadm Site D
effective loss (dB): 20.00
reference pch out (dBm): -20.00
actual pch out (dBm): mode_1: -20.00, mode_2: -18.24
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): -1.40
Power Out (dBm): 18.61
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.01, mode_2: 1.77
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): mode_1: -15.99, mode_2: -14.23
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): 2.62
Power Out (dBm): 18.62
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.02, mode_2: 1.78
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): mode_1: -15.98, mode_2: -14.21
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): 2.63
Power Out (dBm): 18.63
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.03, mode_2: 1.79
output VOA (dB): 0.00
Roadm roadm Site E
effective loss (dB): 20.00
reference pch out (dBm): -20.00
actual pch out (dBm): mode_1: -20.00, mode_2: -18.24
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): -1.40
Power Out (dBm): 18.61
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.01, mode_2: 1.77
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): mode_1: -15.99, mode_2: -14.23
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): 2.62
Power Out (dBm): 18.62
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.02, mode_2: 1.78
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): mode_1: -15.98, mode_2: -14.22
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): 2.63
Power Out (dBm): 18.63
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.03, mode_2: 1.79
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): mode_1: -15.97, mode_2: -14.20
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): 2.64
Power Out (dBm): 18.64
Delta_P (dB): 0.00
target pch (dBm): 0.00
actual pch out (dBm): mode_1: 0.03, mode_2: 1.80
output VOA (dB): 0.00
Roadm roadm Site B
effective loss (dB): 20.00
reference pch out (dBm): -20.00
actual pch out (dBm): mode_1: -20.00, mode_2: -18.24
Transceiver Site_B
GSNR (0.1nm, dB): mode_1: 18.02, mode_2: 20.22
GSNR (signal bw, dB): mode_1: 13.94, mode_2: 13.12
OSNR ASE (0.1nm, dB): mode_1: 19.69, mode_2: 21.35
OSNR ASE (signal bw, dB): mode_1: 15.61, mode_2: 14.26
CD (ps/nm): 20040.00
PMD (ps): 1.39
PDL (dB): 0.00
Latency (ms): 5.88
Transmission result for input power = 0.00 dBm:
Final GSNR (0.1 nm): 18.94 dB
(No source node specified: picked Site_A)
(No destination node specified: picked Site_B)

View File

@@ -36,7 +36,6 @@ Edfa Edfa1
Power Out (dBm): 16.82 Power Out (dBm): 16.82
Delta_P (dB): -2.00 Delta_P (dB): -2.00
target pch (dBm): -2.00 target pch (dBm): -2.00
effective pch (dBm): -2.00
actual pch out (dBm): -1.99 actual pch out (dBm): -1.99
output VOA (dB): 0.00 output VOA (dB): 0.00
Transceiver Site_B Transceiver Site_B

View File

@@ -38,7 +38,6 @@ Edfa Edfa1
Power Out (dBm): 16.81 Power Out (dBm): 16.81
Delta_P (dB): -2.00 Delta_P (dB): -2.00
target pch (dBm): -2.00 target pch (dBm): -2.00
effective pch (dBm): -2.00
actual pch out (dBm): -2.26 actual pch out (dBm): -2.26
output VOA (dB): 0.00 output VOA (dB): 0.00
Transceiver Site_B Transceiver Site_B

View File

@@ -31,7 +31,6 @@ Edfa booster A
Power Out (dBm): 19.83 Power Out (dBm): 19.83
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 0.00 target pch (dBm): 0.00
effective pch (dBm): 0.00
actual pch out (dBm): 0.01 actual pch out (dBm): 0.01
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber Span1 Fiber Span1
@@ -54,7 +53,6 @@ Edfa Edfa1
Power Out (dBm): 19.84 Power Out (dBm): 19.84
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 0.00 target pch (dBm): 0.00
effective pch (dBm): 0.00
actual pch out (dBm): 0.02 actual pch out (dBm): 0.02
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber Span2 Fiber Span2
@@ -77,7 +75,6 @@ Edfa Edfa2
Power Out (dBm): 19.85 Power Out (dBm): 19.85
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 0.00 target pch (dBm): 0.00
effective pch (dBm): 0.00
actual pch out (dBm): 0.03 actual pch out (dBm): 0.03
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber Span3 Fiber Span3
@@ -100,7 +97,6 @@ Edfa Edfa3
Power Out (dBm): 19.86 Power Out (dBm): 19.86
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 0.00 target pch (dBm): 0.00
effective pch (dBm): 0.00
actual pch out (dBm): 0.04 actual pch out (dBm): 0.04
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber Span4 Fiber Span4
@@ -123,7 +119,6 @@ Edfa Edfa4
Power Out (dBm): 19.87 Power Out (dBm): 19.87
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 0.00 target pch (dBm): 0.00
effective pch (dBm): 0.00
actual pch out (dBm): 0.05 actual pch out (dBm): 0.05
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber Span5 Fiber Span5
@@ -146,7 +141,6 @@ Edfa Edfa5
Power Out (dBm): 19.88 Power Out (dBm): 19.88
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 0.00 target pch (dBm): 0.00
effective pch (dBm): 0.00
actual pch out (dBm): 0.06 actual pch out (dBm): 0.06
output VOA (dB): 0.00 output VOA (dB): 0.00
Roadm roadm Site C Roadm roadm Site C
@@ -164,7 +158,6 @@ Edfa booster C
Power Out (dBm): 19.83 Power Out (dBm): 19.83
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 0.00 target pch (dBm): 0.00
effective pch (dBm): 0.00
actual pch out (dBm): 0.01 actual pch out (dBm): 0.01
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber Span6 Fiber Span6
@@ -187,7 +180,6 @@ Edfa Edfa6
Power Out (dBm): 19.84 Power Out (dBm): 19.84
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 0.00 target pch (dBm): 0.00
effective pch (dBm): 0.00
actual pch out (dBm): 0.02 actual pch out (dBm): 0.02
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber Span7 Fiber Span7
@@ -210,7 +202,6 @@ Edfa Edfa7
Power Out (dBm): 19.85 Power Out (dBm): 19.85
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 0.00 target pch (dBm): 0.00
effective pch (dBm): 0.00
actual pch out (dBm): 0.03 actual pch out (dBm): 0.03
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber Span8 Fiber Span8
@@ -233,7 +224,6 @@ Edfa Edfa8
Power Out (dBm): 19.86 Power Out (dBm): 19.86
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 0.00 target pch (dBm): 0.00
effective pch (dBm): 0.00
actual pch out (dBm): 0.04 actual pch out (dBm): 0.04
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber Span9 Fiber Span9
@@ -256,7 +246,6 @@ Edfa Edfa9
Power Out (dBm): 19.87 Power Out (dBm): 19.87
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 0.00 target pch (dBm): 0.00
effective pch (dBm): 0.00
actual pch out (dBm): 0.05 actual pch out (dBm): 0.05
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber Span10 Fiber Span10
@@ -279,7 +268,6 @@ Edfa Edfa10
Power Out (dBm): 19.88 Power Out (dBm): 19.88
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 0.00 target pch (dBm): 0.00
effective pch (dBm): 0.00
actual pch out (dBm): 0.06 actual pch out (dBm): 0.06
output VOA (dB): 0.00 output VOA (dB): 0.00
Roadm roadm Site D Roadm roadm Site D
@@ -297,7 +285,6 @@ Edfa booster D
Power Out (dBm): 19.83 Power Out (dBm): 19.83
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 0.00 target pch (dBm): 0.00
effective pch (dBm): 0.00
actual pch out (dBm): 0.01 actual pch out (dBm): 0.01
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber Span11 Fiber Span11
@@ -320,7 +307,6 @@ Edfa Edfa11
Power Out (dBm): 19.84 Power Out (dBm): 19.84
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 0.00 target pch (dBm): 0.00
effective pch (dBm): 0.00
actual pch out (dBm): 0.02 actual pch out (dBm): 0.02
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber Span12 Fiber Span12
@@ -343,7 +329,6 @@ Edfa Edfa12
Power Out (dBm): 19.85 Power Out (dBm): 19.85
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 0.00 target pch (dBm): 0.00
effective pch (dBm): 0.00
actual pch out (dBm): 0.03 actual pch out (dBm): 0.03
output VOA (dB): 0.00 output VOA (dB): 0.00
Roadm roadm Site E Roadm roadm Site E
@@ -361,7 +346,6 @@ Edfa booster E
Power Out (dBm): 19.83 Power Out (dBm): 19.83
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 0.00 target pch (dBm): 0.00
effective pch (dBm): 0.00
actual pch out (dBm): 0.01 actual pch out (dBm): 0.01
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber Span13 Fiber Span13
@@ -384,7 +368,6 @@ Edfa Edfa13
Power Out (dBm): 19.84 Power Out (dBm): 19.84
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 0.00 target pch (dBm): 0.00
effective pch (dBm): 0.00
actual pch out (dBm): 0.02 actual pch out (dBm): 0.02
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber Span14 Fiber Span14
@@ -407,7 +390,6 @@ Edfa Edfa14
Power Out (dBm): 19.85 Power Out (dBm): 19.85
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 0.00 target pch (dBm): 0.00
effective pch (dBm): 0.00
actual pch out (dBm): 0.03 actual pch out (dBm): 0.03
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber Span15 Fiber Span15
@@ -430,7 +412,6 @@ Edfa Edfa15
Power Out (dBm): 19.86 Power Out (dBm): 19.86
Delta_P (dB): 0.00 Delta_P (dB): 0.00
target pch (dBm): 0.00 target pch (dBm): 0.00
effective pch (dBm): 0.00
actual pch out (dBm): 0.04 actual pch out (dBm): 0.04
output VOA (dB): 0.00 output VOA (dB): 0.00
Roadm roadm Site B Roadm roadm Site B

View File

@@ -29,9 +29,8 @@ Edfa east edfa in Lannion_CAS to Corlay
pad att_in (dB): 0.00 pad att_in (dB): 0.00
Power In (dBm): -0.18 Power In (dBm): -0.18
Power Out (dBm): 21.01 Power Out (dBm): 21.01
Delta_P (dB): 0.00 Delta_P (dB): -1.82
target pch (dBm): 3.00 target pch (dBm): 1.18
effective pch (dBm): 1.18
actual pch out (dBm): 1.18 actual pch out (dBm): 1.18
output VOA (dB): 0.00 output VOA (dB): 0.00
Fiber fiber (Lannion_CAS → Corlay)-F061 Fiber fiber (Lannion_CAS → Corlay)-F061
@@ -66,35 +65,34 @@ Fiber fiber (Loudeac → Lorient_KMA)-F054
reference pch out (dBm): -26.82 reference pch out (dBm): -26.82
actual pch out (dBm): -26.81 actual pch out (dBm): -26.81
Edfa west edfa in Lorient_KMA to Loudeac Edfa west edfa in Lorient_KMA to Loudeac
type_variety: test type_variety: std_medium_gain
effective gain(dB): 27.99 effective gain(dB): 27.99
(before att_in and before output VOA) (before att_in and before output VOA)
noise figure (dB): 5.76 noise figure (dB): 5.98
(including att_in) (including att_in)
pad att_in (dB): 0.00 pad att_in (dB): 0.00
Power In (dBm): -6.99 Power In (dBm): -6.99
Power Out (dBm): 21.03 Power Out (dBm): 21.03
Delta_P (dB): -1.82 Delta_P (dB): -1.82
target pch (dBm): 1.18 target pch (dBm): 1.18
effective pch (dBm): 1.17
actual pch out (dBm): 1.21 actual pch out (dBm): 1.21
output VOA (dB): 0.00 output VOA (dB): 0.00
Roadm roadm Lorient_KMA Roadm roadm Lorient_KMA
effective loss (dB): 21.17 effective loss (dB): 21.18
reference pch out (dBm): -20.00 reference pch out (dBm): -20.00
actual pch out (dBm): -20.00 actual pch out (dBm): -20.00
Transceiver trx Lorient_KMA Transceiver trx Lorient_KMA
GSNR (0.1nm, dB): 23.93 GSNR (0.1nm, dB): 23.77
GSNR (signal bw, dB): 19.85 GSNR (signal bw, dB): 19.69
OSNR ASE (0.1nm, dB): 24.29 OSNR ASE (0.1nm, dB): 24.11
OSNR ASE (signal bw, dB): 20.20 OSNR ASE (signal bw, dB): 20.03
CD (ps/nm): 2171.00 CD (ps/nm): 2171.00
PMD (ps): 0.46 PMD (ps): 0.46
PDL (dB): 0.00 PDL (dB): 0.00
Latency (ms): 0.64 Latency (ms): 0.64
Transmission result for input power = 3.00 dBm: Transmission result for input power = 3.00 dBm:
Final GSNR (0.1 nm): 23.93 dB Final GSNR (0.1 nm): 23.77 dB
(Invalid source node 'lannion' replaced with trx Lannion_CAS) (Invalid source node 'lannion' replaced with trx Lannion_CAS)

View File

@@ -1,7 +0,0 @@
build>=1.0.3,<2
pytest>=7.4.3,<8
# pandas 2.1 removed support for Python 3.8
pandas>=2.0.3,<3
# flake v6 killed the --diff option
flake8>=5.0.4,<6

View File

@@ -4,11 +4,12 @@
# @Date: 2018-02-02 14:06:55 # @Date: 2018-02-02 14:06:55
from numpy import zeros, array from numpy import zeros, array
from gnpy.core.elements import Transceiver, Edfa from numpy.testing import assert_allclose
from gnpy.core.utils import automatic_fmax, lin2db, db2lin, merge_amplifier_restrictions from gnpy.core.elements import Transceiver, Edfa, Fiber
from gnpy.core.info import create_input_spectral_information, ReferenceCarrier from gnpy.core.utils import automatic_fmax, lin2db, db2lin, merge_amplifier_restrictions, dbm2watt, watt2dbm
from gnpy.core.network import build_network from gnpy.core.info import create_input_spectral_information, create_arbitrary_spectral_information
from gnpy.tools.json_io import load_network, load_equipment from gnpy.core.network import build_network, set_amplifier_voa
from gnpy.tools.json_io import load_network, load_equipment, network_from_json
from pathlib import Path from pathlib import Path
import pytest import pytest
@@ -74,8 +75,7 @@ def si(nch_and_spacing, bw):
f_min = 191.3e12 f_min = 191.3e12
f_max = automatic_fmax(f_min, spacing, nb_channel) f_max = automatic_fmax(f_min, spacing, nb_channel)
return create_input_spectral_information(f_min=f_min, f_max=f_max, roll_off=0.15, baud_rate=bw, power=1e-3, 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, 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)]) @pytest.mark.parametrize("gain, nf_expected", [(10, 15), (15, 10), (25, 5.8)])
@@ -86,7 +86,7 @@ def test_variable_gain_nf(gain, nf_expected, setup_edfa_variable_gain, si):
si.nli /= db2lin(gain) si.nli /= db2lin(gain)
si.ase /= db2lin(gain) si.ase /= db2lin(gain)
edfa.operational.gain_target = gain edfa.operational.gain_target = gain
si.pref = si.pref._replace(p_span0=0, p_spani=-gain) edfa.effective_gain = gain
edfa.interpol_params(si) edfa.interpol_params(si)
result = edfa.nf result = edfa.nf
assert pytest.approx(nf_expected, abs=0.01) == result[0] assert pytest.approx(nf_expected, abs=0.01) == result[0]
@@ -100,7 +100,7 @@ def test_fixed_gain_nf(gain, nf_expected, setup_edfa_fixed_gain, si):
si.nli /= db2lin(gain) si.nli /= db2lin(gain)
si.ase /= db2lin(gain) si.ase /= db2lin(gain)
edfa.operational.gain_target = gain edfa.operational.gain_target = gain
si.pref = si.pref._replace(p_span0=0, p_spani=-gain) edfa.effective_gain = gain
edfa.interpol_params(si) edfa.interpol_params(si)
assert pytest.approx(nf_expected, abs=0.01) == edfa.nf[0] assert pytest.approx(nf_expected, abs=0.01) == edfa.nf[0]
@@ -124,8 +124,8 @@ def test_compare_nf_models(gain, setup_edfa_variable_gain, si):
si.nli /= db2lin(gain) si.nli /= db2lin(gain)
si.ase /= db2lin(gain) si.ase /= db2lin(gain)
edfa.operational.gain_target = gain edfa.operational.gain_target = gain
edfa.effective_gain = gain
# edfa is variable gain type # edfa is variable gain type
si.pref = si.pref._replace(p_span0=0, p_spani=-gain)
edfa.interpol_params(si) edfa.interpol_params(si)
nf_model = edfa.nf[0] nf_model = edfa.nf[0]
@@ -180,7 +180,6 @@ def test_ase_noise(gain, si, setup_trx, bw):
si = span(si) si = span(si)
print(span) print(span)
si.pref = si.pref._replace(p_span0=0, p_spani=-gain)
edfa.interpol_params(si) edfa.interpol_params(si)
nf = edfa.nf nf = edfa.nf
print('nf', nf) print('nf', nf)
@@ -196,3 +195,173 @@ def test_ase_noise(gain, si, setup_trx, bw):
si = trx(si) si = trx(si)
osnr = trx.osnr_ase_01nm[0] osnr = trx.osnr_ase_01nm[0]
assert pytest.approx(osnr_expected, abs=0.01) == osnr assert pytest.approx(osnr_expected, abs=0.01) == osnr
@pytest.mark.parametrize('delta_p', [0, None, 2])
@pytest.mark.parametrize('tilt_target', [0, -4])
def test_amp_behaviour(tilt_target, delta_p):
"""Check that amp correctly applies saturation, when there is tilt
"""
json_data = {
"elements": [{
"uid": "Edfa1",
"type": "Edfa",
"type_variety": "test",
"operational": {
"delta_p": delta_p,
"gain_target": 20 + delta_p if delta_p else 20,
"tilt_target": tilt_target,
"out_voa": 0
}
}, {
"uid": "Span1",
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 100,
"loss_coef": 0.2,
"length_units": "km"
}
}],
"connections": []
}
equipment = load_equipment(eqpt_library)
network = network_from_json(json_data, equipment)
edfa = [n for n in network.nodes() if isinstance(n, Edfa)][0]
fiber = [n for n in network.nodes() if isinstance(n, Fiber)][0]
fiber.params.con_in = 0
fiber.params.con_out = 0
fiber.ref_pch_in_dbm = 0.0
si = create_input_spectral_information(f_min=191.3e12, f_max=196.05e12, roll_off=0.15, baud_rate=64e9, power=0.001,
spacing=75e9, tx_osnr=None)
si = fiber(si)
total_sig_powerin = sum(si.signal)
sig_in = lin2db(si.signal)
si = edfa(si)
sig_out = lin2db(si.signal)
total_sig_powerout = sum(si.signal)
gain = lin2db(total_sig_powerout / total_sig_powerin)
expected_total_power_out = total_sig_powerin * 100 * db2lin(delta_p) if delta_p else total_sig_powerin * 100
assert pytest.approx(total_sig_powerout, abs=1e-6) == min(expected_total_power_out, dbm2watt(21))
assert pytest.approx(edfa.effective_gain, 1e-5) == gain
assert watt2dbm(sum(si.signal + si.nli + si.ase)) <= 21.01
# If there is no tilt on the amp: the gain is identical for all carriers
if tilt_target == 0:
assert_allclose(sig_in + gain, sig_out, rtol=1e-13)
else:
if delta_p != 2:
expected_sig_out = [
-32.00529182, -31.93540907, -31.86554231, -31.79417979, -31.71903263,
-31.6424009, -31.56531159, -31.48775435, -31.41468382, -31.35973323,
-31.32286555, -31.28602346, -31.2472908, -31.20086569, -31.14671746,
-31.08702653, -31.01341963, -30.93430243, -30.87791656, -30.84413339,
-30.81605918, -30.78824936, -30.76071036, -30.73319161, -30.70494101,
-30.67368479, -30.63941012, -30.60178381, -30.55585766, -30.5066561,
-30.43426575, -30.33848379, -30.24471112, -30.18220815, -30.15076699,
-30.11934744, -30.08776718, -30.05548097, -30.02250068, -29.98954302,
-29.95661362, -29.92370274, -29.8854762, -29.84193785, -29.79238328,
-29.72452662, -29.6385071, -29.54788144, -29.44581202, -29.33924103,
-29.23276107, -29.10289365, -28.91425473, -28.70204648, -28.50670713,
-28.3282514, -28.15895225, -28.009065, -27.87864672, -27.76315964,
-27.68523133, -27.62260405, -27.58076622]
else:
expected_sig_out = [
-30.00529182, -29.93540907, -29.86554231, -29.79417979, -29.71903263,
-29.6424009, -29.56531159, -29.48775435, -29.41468382, -29.35973323,
-29.32286555, -29.28602346, -29.2472908, -29.20086569, -29.14671746,
-29.08702653, -29.01341963, -28.93430243, -28.87791656, -28.84413339,
-28.81605918, -28.78824936, -28.76071036, -28.73319161, -28.70494101,
-28.67368479, -28.63941012, -28.60178381, -28.55585766, -28.5066561,
-28.43426575, -28.33848379, -28.24471112, -28.18220815, -28.15076699,
-28.11934744, -28.08776718, -28.05548097, -28.02250068, -27.98954302,
-27.95661362, -27.92370274, -27.8854762, -27.84193785, -27.79238328,
-27.72452662, -27.6385071, -27.54788144, -27.44581202, -27.33924103,
-27.23276107, -27.10289365, -26.91425473, -26.70204648, -26.50670713,
-26.3282514, -26.15895225, -26.009065, -25.87864672, -25.76315964,
-25.68523133, -25.62260405, -25.58076622]
print(sig_out)
assert_allclose(sig_out, expected_sig_out, rtol=1e-9)
@pytest.mark.parametrize('delta_p', [0, None, 20])
@pytest.mark.parametrize('base_power', [0, 20])
@pytest.mark.parametrize('delta_pdb_per_channel',
[[0, 1, 3, 0.5, -2],
[0, 0, 0, 0, 0],
[-2, -2, -2, -2, -2],
[0, 2, -2, -5, 4],
[0, 1, 3, 0.5, -2], ])
def test_amp_saturation(delta_pdb_per_channel, base_power, delta_p):
"""Check that amp correctly applies saturation
"""
json_data = {
"elements": [{
"uid": "Edfa1",
"type": "Edfa",
"type_variety": "test",
"operational": {
"delta_p": delta_p,
"gain_target": 20,
"tilt_target": 0,
"out_voa": 0
}
}],
"connections": []
}
equipment = load_equipment(eqpt_library)
network = network_from_json(json_data, equipment)
edfa = [n for n in network.nodes()][0]
frequency = 193e12 + 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]) + array(delta_pdb_per_channel) + base_power)
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)
total_sig_powerin = sum(si.signal)
sig_in = lin2db(si.signal)
si = edfa(si)
sig_out = lin2db(si.signal)
total_sig_powerout = sum(si.signal)
gain = lin2db(total_sig_powerout / total_sig_powerin)
assert watt2dbm(sum(si.signal + si.nli + si.ase)) <= 21.02
assert pytest.approx(edfa.effective_gain, 1e-13) == gain
assert_allclose(sig_in + gain, sig_out, rtol=1e-13)
def test_set_out_voa():
"""Check that out_voa is correctly set if out_voa_auto is true
gain is maximized to obtain better NF:
if optimum input power in next span is -3 + pref_ch_db then total power at optimum is 19 -3 = 16dBm.
since amp has 21 dBm p_max, power out of amp can be set to 21dBm increasing out_voa by 5 to keep
same input power in the fiber. Since the optimisation contains a hard coded margin of 1 to account for
possible degradation on max power, the expected voa value is 4, and delta_p and gain are corrected
accordingly.
"""
json_data = {
"elements": [{
"uid": "Edfa1",
"type": "Edfa",
"type_variety": "test",
"operational": {
"delta_p": -3,
"gain_target": 20,
"tilt_target": 0
}
}],
"connections": []
}
equipment = load_equipment(eqpt_library)
network = network_from_json(json_data, equipment)
amp = [n for n in network.nodes()][0]
print(amp.out_voa)
power_target = 19 + amp.delta_p
power_mode = True
amp.params.out_voa_auto = True
set_amplifier_voa(amp, power_target, power_mode)
assert amp.out_voa == 4.0
assert amp.effective_gain == 20.0 + 4.0
assert amp.delta_p == -3.0 + 4.0

View File

@@ -17,8 +17,7 @@ from copy import deepcopy
from gnpy.core.utils import lin2db, automatic_nch, dbm2watt, power_dbm_to_psd_mw_ghz, watt2dbm, psd2powerdbm 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.network import build_network
from gnpy.core.elements import Roadm from gnpy.core.elements import Roadm
from gnpy.core.info import create_input_spectral_information, Pref, create_arbitrary_spectral_information, \ from gnpy.core.info import create_input_spectral_information, create_arbitrary_spectral_information, ReferenceCarrier
ReferenceCarrier
from gnpy.core.equipment import trx_mode_params from gnpy.core.equipment import trx_mode_params
from gnpy.core.exceptions import ConfigurationError 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.tools.json_io import network_from_json, load_equipment, load_network, _spectrum_from_json, load_json, \
@@ -73,16 +72,16 @@ def test_equalization_combination_degree(delta_pdb_per_channel, degree, equaliza
} }
} }
roadm = Roadm(**roadm_config) roadm = Roadm(**roadm_config)
roadm.ref_pch_in_dbm['tata'] = 0
roadm.ref_carrier = ReferenceCarrier(baud_rate=32e9, slot_width=50e9)
frequency = 191e12 + array([0, 50e9, 150e9, 225e9, 275e9]) frequency = 191e12 + array([0, 50e9, 150e9, 225e9, 275e9])
slot_width = array([37.5e9, 50e9, 75e9, 50e9, 37.5e9]) slot_width = array([37.5e9, 50e9, 75e9, 50e9, 37.5e9])
baud_rate = array([32e9, 42e9, 64e9, 42e9, 32e9]) baud_rate = array([32e9, 42e9, 64e9, 42e9, 32e9])
signal = dbm2watt(array([-20.0, -18.0, -22.0, -25.0, -16.0])) 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, si = 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, delta_pdb_per_channel=delta_pdb_per_channel,
tx_osnr=None, ref_power=pref) tx_osnr=None)
to_json_before_propagation = { to_json_before_propagation = {
'uid': 'roadm Lannion_CAS', 'uid': 'roadm Lannion_CAS',
'type': 'Roadm', 'type': 'Roadm',
@@ -98,7 +97,7 @@ def test_equalization_combination_degree(delta_pdb_per_channel, degree, equaliza
'metadata': {'location': {'latitude': 0, 'longitude': 0, 'city': None, 'region': None}} 'metadata': {'location': {'latitude': 0, 'longitude': 0, 'city': None, 'region': None}}
} }
assert roadm.to_json == to_json_before_propagation assert roadm.to_json == to_json_before_propagation
si = roadm(si, degree) si = roadm(si, degree=degree, from_degree='tata')
assert roadm.ref_pch_out_dbm == pytest.approx(expected_pch_out_dbm, rel=1e-4) 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) assert_allclose(expected_si, roadm.get_per_degree_power(degree, spectral_info=si), rtol=1e-3)
@@ -215,12 +214,10 @@ def test_low_input_power(target_out, delta_pdb_per_channel, correction):
baud_rate = array([32e9, 42e9, 64e9, 42e9, 32e9]) baud_rate = array([32e9, 42e9, 64e9, 42e9, 32e9])
signal = dbm2watt(array([-20.0, -18.0, -22.0, -25.0, -16.0])) signal = dbm2watt(array([-20.0, -18.0, -22.0, -25.0, -16.0]))
target = target_out + array(delta_pdb_per_channel) 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, si = 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, delta_pdb_per_channel=delta_pdb_per_channel,
tx_osnr=None, ref_power=pref) tx_osnr=None)
roadm_config = { roadm_config = {
"uid": "roadm Brest_KLA", "uid": "roadm Brest_KLA",
"params": { "params": {
@@ -244,7 +241,9 @@ def test_low_input_power(target_out, delta_pdb_per_channel, correction):
} }
} }
roadm = Roadm(**roadm_config) roadm = Roadm(**roadm_config)
si = roadm(si, 'toto') roadm.ref_pch_in_dbm['tata'] = 0
roadm.ref_carrier = ReferenceCarrier(baud_rate=32e9, slot_width=50e9)
si = roadm(si, degree='toto', from_degree='tata')
assert_allclose(watt2dbm(si.signal), target - correction, rtol=1e-5) 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 # 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), assert_allclose((watt2dbm(signal) >= target) * target + (watt2dbm(signal) < target) * watt2dbm(signal),
@@ -267,12 +266,10 @@ def test_2low_input_power(target_out, delta_pdb_per_channel, correction):
baud_rate = array([32e9, 42e9, 64e9, 42e9, 32e9]) baud_rate = array([32e9, 42e9, 64e9, 42e9, 32e9])
signal = dbm2watt(array([-20.0, -18.0, -22.0, -25.0, -16.0])) signal = dbm2watt(array([-20.0, -18.0, -22.0, -25.0, -16.0]))
target = psd2powerdbm(target_out, baud_rate) + array(delta_pdb_per_channel) 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, si = 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, delta_pdb_per_channel=delta_pdb_per_channel,
tx_osnr=None, ref_power=pref) tx_osnr=None)
roadm_config = { roadm_config = {
"uid": "roadm Brest_KLA", "uid": "roadm Brest_KLA",
"params": { "params": {
@@ -296,15 +293,17 @@ def test_2low_input_power(target_out, delta_pdb_per_channel, correction):
} }
} }
roadm = Roadm(**roadm_config) roadm = Roadm(**roadm_config)
si = roadm(si, 'toto') roadm.ref_pch_in_dbm['tata'] = 0
roadm.ref_carrier = ReferenceCarrier(baud_rate=32e9, slot_width=50e9)
si = roadm(si, degree='toto', from_degree='tata')
assert_allclose(watt2dbm(si.signal), target - correction, rtol=1e-5) assert_allclose(watt2dbm(si.signal), target - correction, rtol=1e-5)
def net_setup(equipment): def net_setup(equipment, deltap=0):
"""common setup for tests: builds network, equipment and oms only once""" """common setup for tests: builds network, equipment and oms only once"""
network = load_network(NETWORK_FILENAME, equipment) network = load_network(NETWORK_FILENAME, equipment)
spectrum = equipment['SI']['default'] spectrum = equipment['SI']['default']
p_db = spectrum.power_dbm p_db = spectrum.power_dbm + deltap
p_total_db = p_db + lin2db(automatic_nch(spectrum.f_min, spectrum.f_max, spectrum.spacing)) 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) build_network(network, equipment, p_db, p_total_db)
return network return network
@@ -447,14 +446,14 @@ def ref_network():
return network return network
@pytest.mark.parametrize('deltap', [0, +1.2, -0.5]) @pytest.mark.parametrize('deltap', [0, +1.18, -0.5])
def test_target_psd_out_mwperghz_deltap(deltap): def test_target_psd_out_mwperghz_deltap(deltap):
"""checks that if target_psd_out_mWperGHz is defined, delta_p of amps is correctly updated """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 Power over 1.18dBm saturate amp with this test: TODO add a test on this saturation
""" """
equipment = load_equipment(EQPT_FILENAME) equipment = load_equipment(EQPT_FILENAME)
network = net_setup(equipment) network = net_setup(equipment, deltap)
req = create_voyager_req(equipment, 'trx Brest_KLA', 'trx Vannes_KBE', False, ['trx Vannes_KBE'], ['STRICT'], req = create_voyager_req(equipment, 'trx Brest_KLA', 'trx Vannes_KBE', False, ['trx Vannes_KBE'], ['STRICT'],
'mode 1', 50e9, deltap) 'mode 1', 50e9, deltap)
temp = [{ temp = [{
@@ -508,7 +507,6 @@ def test_equalization(case, deltap, target, mode, slot_width, equalization):
# boosters = ['east edfa in Brest_KLA to Quimper', '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'] # 'east edfa in Lannion_CAS to Stbrieuc']
target_psd = power_dbm_to_psd_mw_ghz(target, 32e9) target_psd = power_dbm_to_psd_mw_ghz(target, 32e9)
ref = ReferenceCarrier(baud_rate=32e9, slot_width=50e9)
if case == 'SI': if case == 'SI':
delattr(equipment['Roadm']['default'], 'target_pch_out_db') delattr(equipment['Roadm']['default'], 'target_pch_out_db')
setattr(equipment['Roadm']['default'], equalization, target_psd) setattr(equipment['Roadm']['default'], equalization, target_psd)
@@ -534,10 +532,10 @@ def test_equalization(case, deltap, target, mode, slot_width, equalization):
path = compute_constrained_path(network, req) path = compute_constrained_path(network, req)
si = create_input_spectral_information( 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, 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) spacing=req.spacing, tx_osnr=req.tx_osnr)
for i, el in enumerate(path): for i, el in enumerate(path):
if isinstance(el, Roadm): if isinstance(el, Roadm):
si = el(si, degree=path[i + 1].uid) si = el(si, degree=path[i + 1].uid, from_degree=path[i - 1].uid)
if case in ['SI', 'nodes', 'degrees']: if case in ['SI', 'nodes', 'degrees']:
if equalization == 'target_psd_out_mWperGHz': if equalization == 'target_psd_out_mWperGHz':
assert_allclose(power_dbm_to_psd_mw_ghz(watt2dbm(si.signal + si.ase + si.nli), si.baud_rate), assert_allclose(power_dbm_to_psd_mw_ghz(watt2dbm(si.signal + si.ase + si.nli), si.baud_rate),

97
tests/test_gain_mode.py Normal file
View File

@@ -0,0 +1,97 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Author: Esther Le Rouzic
# @Date: 2019-05-22
"""
@author: esther.lerouzic
checks behaviour of gain mode
- if all amps have their gains set, check that these gains are used, even if power_dbm or req_power change
- check that saturation is correct in gain mode
"""
from pathlib import Path
from numpy.testing import assert_array_equal, assert_allclose
import pytest
from gnpy.core.utils import lin2db, automatic_nch, dbm2watt
from gnpy.core.network import build_network
from gnpy.tools.json_io import load_equipment, load_network
from gnpy.core.equipment import trx_mode_params
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/perdegreemeshTopologyExampleV2_auto_design_expected.json'
def net_setup(equipment):
"""Common setup for tests: builds network, equipment
"""
network = load_network(NETWORK_FILENAME, equipment)
spectrum = equipment['SI']['default']
p_db = spectrum.power_dbm
p_total_db = p_db + lin2db(automatic_nch(spectrum.f_min, spectrum.f_max, spectrum.spacing))
build_network(network, equipment, p_db, p_total_db)
return network
def create_rq(equipment, srce, dest, bdir, nd_list, ls_list, mode, power_dbm):
"""Create the usual request list according to parameters
"""
params = {
'request_id': 'test_request',
'source': srce,
'bidir': bdir,
'destination': dest,
'trx_type': 'Voyager',
'trx_mode': mode,
'format': mode,
'nodes_list': nd_list,
'loose_list': ls_list,
'effective_freq_slot': None,
'path_bandwidth': 100000000000.0,
'spacing': 50e9 if mode == 'mode 1' else 75e9,
'power': dbm2watt(power_dbm)
}
trx_params = trx_mode_params(equipment, params['trx_type'], params['trx_mode'], True)
params.update(trx_params)
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, -2, 3])
@pytest.mark.parametrize("req_power", [1e-3, 0.5e-3, 2e-3])
def test_gain_mode(req_power, power_dbm):
""" Gains are all set on the selected path, so that since the design is made for 0dBm,
in gain mode, whatever the value of equipment power_dbm or request power, the network is unchanged
and the propagation remains the same as for power mode and 0dBm
"""
equipment = load_equipment(EQPT_FILENAME)
network = net_setup(equipment)
req = create_rq(equipment, 'trx Brest_KLA', 'trx Rennes_STA', False,
['Edfa0_roadm Brest_KLA', 'roadm Lannion_CAS', 'trx Rennes_STA'],
['STRICT', 'STRICT', 'STRICT'], 'mode 1', 0)
path = compute_constrained_path(network, req)
# Propagation in power_mode
infos_expected = propagate(path, req, equipment)
# Now set to gain mode
setattr(equipment['Span']['default'], 'power_mode', False)
setattr(equipment['SI']['default'], 'power_dbm', power_dbm)
req.power = req_power
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_allclose(infos_expected.signal, infos_actual.signal, rtol=1e-14)
assert_allclose(infos_expected.nli, infos_actual.nli, rtol=1e-14)
assert_allclose(infos_expected.ase, infos_actual.ase, rtol=1e-14)
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)

View File

@@ -4,7 +4,7 @@
import pytest import pytest
from numpy import array, zeros, ones from numpy import array, zeros, ones
from numpy.testing import assert_array_equal from numpy.testing import assert_array_equal
from gnpy.core.info import create_arbitrary_spectral_information, Pref from gnpy.core.info import create_arbitrary_spectral_information
from gnpy.core.exceptions import SpectrumError from gnpy.core.exceptions import SpectrumError
@@ -12,8 +12,7 @@ def test_create_arbitrary_spectral_information():
si = create_arbitrary_spectral_information(frequency=[193.25e12, 193.3e12, 193.35e12], 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], delta_pdb_per_channel=[1, 1, 1],
tx_osnr=40.0, tx_osnr=40.0)
ref_power=Pref(1, 1, None))
assert_array_equal(si.baud_rate, array([32e9, 32e9, 32e9])) 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.slot_width, array([37.5e9, 37.5e9, 37.5e9]))
assert_array_equal(si.signal, ones(3)) assert_array_equal(si.signal, ones(3))
@@ -34,8 +33,7 @@ def test_create_arbitrary_spectral_information():
si = create_arbitrary_spectral_information(frequency=array([193.35e12, 193.3e12, 193.25e12]), si = create_arbitrary_spectral_information(frequency=array([193.35e12, 193.3e12, 193.25e12]),
slot_width=array([50e9, 50e9, 50e9]), 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, tx_osnr=40.0)
ref_power=Pref(1, 1, None))
assert_array_equal(si.signal, array([3, 2, 1])) assert_array_equal(si.signal, array([3, 2, 1]))
@@ -43,17 +41,16 @@ def test_create_arbitrary_spectral_information():
r'larger than the slot width for channels: \[1, 3\].'): r'larger than the slot width for channels: \[1, 3\].'):
create_arbitrary_spectral_information(frequency=[193.25e12, 193.3e12, 193.35e12], signal=1, 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, tx_osnr=40.0)
ref_power=Pref(1, 1, None))
with pytest.raises(SpectrumError, match='Spectrum required slot widths larger than the frequency spectral ' with pytest.raises(SpectrumError, match='Spectrum required slot widths larger than the frequency spectral '
r'distances between channels: \[\(1, 2\), \(3, 4\)\].'): r'distances between channels: \[\(1, 2\), \(3, 4\)\].'):
create_arbitrary_spectral_information(frequency=[193.26e12, 193.3e12, 193.35e12, 193.39e12], signal=1, create_arbitrary_spectral_information(frequency=[193.26e12, 193.3e12, 193.35e12, 193.39e12], signal=1,
tx_osnr=40.0, baud_rate=32e9, slot_width=50e9, ref_power=Pref(1, 1, None)) tx_osnr=40.0, baud_rate=32e9, slot_width=50e9)
with pytest.raises(SpectrumError, match='Spectrum required slot widths larger than the frequency spectral ' with pytest.raises(SpectrumError, match='Spectrum required slot widths larger than the frequency spectral '
r'distances between channels: \[\(1, 2\), \(2, 3\)\].'): r'distances between channels: \[\(1, 2\), \(2, 3\)\].'):
create_arbitrary_spectral_information(frequency=[193.25e12, 193.3e12, 193.35e12], signal=1, baud_rate=49e9, create_arbitrary_spectral_information(frequency=[193.25e12, 193.3e12, 193.35e12], signal=1, baud_rate=49e9,
tx_osnr=40.0, roll_off=0.1, ref_power=Pref(1, 1, None)) tx_osnr=40.0, roll_off=0.1)
with pytest.raises(SpectrumError, with pytest.raises(SpectrumError,
match='Dimension mismatch in input fields.'): 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)) tx_osnr=40.0)

View File

@@ -29,6 +29,14 @@ SRC_ROOT = Path(__file__).parent.parent
['--spectrum', 'gnpy/example-data/initial_spectrum2.json', 'gnpy/example-data/meshTopologyExampleV2.xls', '--show-channels', ]), ['--spectrum', 'gnpy/example-data/initial_spectrum2.json', 'gnpy/example-data/meshTopologyExampleV2.xls', '--show-channels', ]),
('path_requests_run_CD_PMD_PDL_missing', 'logs_path_requests_run_CD_PMD_PDL_missing', path_requests_run, ('path_requests_run_CD_PMD_PDL_missing', 'logs_path_requests_run_CD_PMD_PDL_missing', path_requests_run,
['tests/data/CORONET_Global_Topology_expected.json', 'tests/data/CORONET_services.json', '-v']), ['tests/data/CORONET_Global_Topology_expected.json', 'tests/data/CORONET_services.json', '-v']),
('power_sweep_example', 'logs_power_sweep_example', transmission_main_example,
['tests/data/testTopology_expected.json', 'brest', 'rennes', '-e', 'tests/data/eqpt_config_sweep.json', '--pow', '3']),
('transmission_long_pow', None, transmission_main_example,
['-e', 'tests/data/eqpt_config.json', 'tests/data/test_long_network.json', '--spectrum', 'gnpy/example-data/initial_spectrum2.json']),
('transmission_long_psd', None, transmission_main_example,
['-e', 'tests/data/eqpt_config_psd.json', 'tests/data/test_long_network.json', '--spectrum', 'gnpy/example-data/initial_spectrum2.json', ]),
('transmission_long_psw', None, transmission_main_example,
['-e', 'tests/data/eqpt_config_psw.json', 'tests/data/test_long_network.json', '--spectrum', 'gnpy/example-data/initial_spectrum2.json', ]),
)) ))
def test_example_invocation(capfd, caplog, output, log, handler, args): def test_example_invocation(capfd, caplog, output, log, handler, args):
"""Make sure that our examples produce useful output""" """Make sure that our examples produce useful output"""

View File

@@ -7,8 +7,10 @@
from pathlib import Path from pathlib import Path
import pytest import pytest
from gnpy.core.exceptions import NetworkTopologyError from gnpy.core.exceptions import NetworkTopologyError
from gnpy.core.network import span_loss from gnpy.core.network import span_loss, build_network
from gnpy.tools.json_io import load_equipment, load_network from gnpy.tools.json_io import load_equipment, load_network, network_from_json
from gnpy.core.utils import lin2db, automatic_nch
from gnpy.core.elements import Fiber, Edfa
TEST_DIR = Path(__file__).parent TEST_DIR = Path(__file__).parent
@@ -49,7 +51,7 @@ def test_span_loss(node, attenuation):
network = load_network(NETWORK_FILENAME, equipment) network = load_network(NETWORK_FILENAME, equipment)
for x in network.nodes(): for x in network.nodes():
if x.uid == node: if x.uid == node:
assert attenuation == span_loss(network, x) assert attenuation == span_loss(network, x, equipment)
return return
assert not f'node "{node}" referenced from test but not found in the topology' # pragma: no cover assert not f'node "{node}" referenced from test but not found in the topology' # pragma: no cover
@@ -61,4 +63,180 @@ def test_span_loss_unconnected(node):
network = load_network(NETWORK_FILENAME, equipment) network = load_network(NETWORK_FILENAME, equipment)
x = next(x for x in network.nodes() if x.uid == node) x = next(x for x in network.nodes() if x.uid == node)
with pytest.raises(NetworkTopologyError): with pytest.raises(NetworkTopologyError):
span_loss(network, x) span_loss(network, x, equipment)
@pytest.mark.parametrize('typ, expected_loss',
[('Edfa', [11, 11]),
('Fused', [11, 10])])
def test_eol(typ, expected_loss):
"""Check that EOL is added only once on spans. One span can be one fiber or several fused fibers
EOL is then added on the first fiber only.
"""
json_data = {
"elements": [
{
"uid": "trx SITE1",
"type": "Transceiver"
},
{
"uid": "trx SITE2",
"type": "Transceiver"
},
{
"uid": "roadm SITE1",
"type": "Roadm"
},
{
"uid": "roadm SITE2",
"type": "Roadm"
},
{
"uid": "fiber (SITE1 → ILA1)",
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 50.0,
"loss_coef": 0.2,
"length_units": "km"
}
},
{
"uid": "fiber (ILA1 → SITE2)",
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 50.0,
"loss_coef": 0.2,
"length_units": "km"
}
},
{
"uid": "east edfa in SITE1 to ILA1",
"type": "Edfa"
},
{
"uid": "west edfa in SITE2 to ILA1",
"type": typ
},
{
"uid": "east edfa in ILA1 to SITE2",
"type": "Edfa"
}
],
"connections": [
{
"from_node": "trx SITE1",
"to_node": "roadm SITE1"
},
{
"from_node": "roadm SITE1",
"to_node": "east edfa in SITE1 to ILA1"
},
{
"from_node": "east edfa in SITE1 to ILA1",
"to_node": "fiber (SITE1 → ILA1)"
},
{
"from_node": "fiber (SITE1 → ILA1)",
"to_node": "east edfa in ILA1 to SITE2"
},
{
"from_node": "east edfa in ILA1 to SITE2",
"to_node": "fiber (ILA1 → SITE2)"
},
{
"from_node": "fiber (ILA1 → SITE2)",
"to_node": "west edfa in SITE2 to ILA1"
},
{
"from_node": "west edfa in SITE2 to ILA1",
"to_node": "roadm SITE2"
},
{
"from_node": "roadm SITE2",
"to_node": "trx SITE2"
}
]
}
equipment = load_equipment(EQPT_FILENAME)
equipment['Span']['default'].EOL = 1
network = network_from_json(json_data, equipment)
p_db = equipment['SI']['default'].power_dbm
p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing))
build_network(network, equipment, p_db, p_total_db)
fibers = [f for f in network.nodes() if isinstance(f, Fiber)]
for i in range(2):
assert fibers[i].loss == expected_loss[i]
@pytest.mark.parametrize('p_db, power_mode, elem1, elem2, expected_gain, expected_delta_p, expected_voa', [
(-17, True, 'edfa', 'fiber', 15.0, 15, 15.0),
(-17, True, 'fiber', 'edfa', 15.0, 5.0, 5.0),
(-17, False, 'edfa', 'fiber', 0.0, None, 0.0),
(-17, False, 'fiber', 'edfa', 10.0, None, 0.0),
(10, True, 'edfa', 'fiber', -9.0, -9.0, 0.0),
(10, True, 'fiber', 'edfa', 1.0, -9.0, 0.0),
(10, False, 'edfa', 'fiber', -9.0, None, 0.0),
(10, False, 'fiber', 'edfa', 1.0, None, 0.0)])
def test_design_non_amplified_link(elem1, elem2, expected_gain, expected_delta_p, expected_voa, power_mode, p_db):
"""Check that the delta_p, gain computed on an amplified link that starts from a transceiver are correct
"""
json_data = {
"elements": [
{
"uid": "trx SITE1",
"type": "Transceiver"
},
{
"uid": "trx SITE2",
"type": "Transceiver"
},
{
"uid": "edfa",
"type": "Edfa",
"type_variety": "std_low_gain"
},
{
"uid": "fiber",
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 50.0,
"loss_coef": 0.2,
"length_units": "km"
}
}
],
"connections": [
{
"from_node": "trx SITE1",
"to_node": elem1
},
{
"from_node": elem1,
"to_node": elem2
},
{
"from_node": elem2,
"to_node": "trx SITE2"
}
]
}
equipment = load_equipment(EQPT_FILENAME)
equipment['Span']['default'].power_mode = power_mode
equipment['SI']['default'].power_dbm = p_db
network = network_from_json(json_data, equipment)
edfa = next(a for a in network.nodes() if a.uid == 'edfa')
edfa.params.out_voa_auto = True
p_total_db = p_db + 20.0
build_network(network, equipment, p_db, p_total_db)
amps = [a for a in network.nodes() if isinstance(a, Edfa)]
for amp in amps:
assert amp.out_voa == expected_voa
assert amp.delta_p == expected_delta_p
# max power of std_low_gain is 21 dBm
assert amp.effective_gain == expected_gain

View File

@@ -24,7 +24,7 @@ from xlrd import open_workbook
import pytest import pytest
from copy import deepcopy from copy import deepcopy
from gnpy.core.utils import automatic_nch, lin2db from gnpy.core.utils import automatic_nch, lin2db
from gnpy.core.network import build_network from gnpy.core.network import build_network, add_missing_elements_in_network
from gnpy.core.exceptions import ServiceError from gnpy.core.exceptions import ServiceError
from gnpy.topology.request import (jsontocsv, requests_aggregation, compute_path_dsjctn, deduplicate_disjunctions, from gnpy.topology.request import (jsontocsv, requests_aggregation, compute_path_dsjctn, deduplicate_disjunctions,
compute_path_with_disjunction, ResultElement, PathRequest) compute_path_with_disjunction, ResultElement, PathRequest)
@@ -71,6 +71,7 @@ def test_auto_design_generation_fromxlsgainmode(tmpdir, xls_input, expected_json
"""tests generation of topology json and that the build network gives correct results in gain mode""" """tests generation of topology json and that the build network gives correct results in gain mode"""
equipment = load_equipment(eqpt_filename) equipment = load_equipment(eqpt_filename)
network = load_network(xls_input, equipment) network = load_network(xls_input, equipment)
add_missing_elements_in_network(network, equipment)
# in order to test the Eqpt sheet and load gain target, # in order to test the Eqpt sheet and load gain target,
# change the power-mode to False (to be in gain mode) # change the power-mode to False (to be in gain mode)
equipment['Span']['default'].power_mode = False equipment['Span']['default'].power_mode = False
@@ -109,6 +110,7 @@ def test_auto_design_generation_fromjson(tmpdir, json_input, power_mode):
p_db = equipment['SI']['default'].power_dbm p_db = equipment['SI']['default'].power_dbm
p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min, p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing)) equipment['SI']['default'].f_max, equipment['SI']['default'].spacing))
add_missing_elements_in_network(network, equipment)
build_network(network, equipment, p_db, p_total_db) build_network(network, equipment, p_db, p_total_db)
actual_json_output = tmpdir / json_input.with_name(json_input.stem + '_auto_design').with_suffix('.json').name actual_json_output = tmpdir / json_input.with_name(json_input.stem + '_auto_design').with_suffix('.json').name
save_network(network, actual_json_output) save_network(network, actual_json_output)

View File

@@ -4,14 +4,19 @@
# @Date: 2018-02-02 14:06:55 # @Date: 2018-02-02 14:06:55
import pytest 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, ReferenceCarrier
from gnpy.core.network import build_network
from gnpy.tools.json_io import load_network, load_equipment
from pathlib import Path from pathlib import Path
from networkx import dijkstra_path from networkx import dijkstra_path
from numpy import mean, sqrt, ones from numpy import mean, sqrt, ones
import re
from gnpy.core.exceptions import SpectrumError
from gnpy.core.elements import Transceiver, Fiber, Edfa, Roadm
from gnpy.core.utils import db2lin
from gnpy.core.info import create_input_spectral_information
from gnpy.core.network import build_network
from gnpy.tools.json_io import load_network, load_equipment, network_from_json
network_file_name = Path(__file__).parent.parent / 'tests/LinkforTest.json' network_file_name = Path(__file__).parent.parent / 'tests/LinkforTest.json'
eqpt_library_name = Path(__file__).parent.parent / 'tests/data/eqpt_config.json' eqpt_library_name = Path(__file__).parent.parent / 'tests/data/eqpt_config.json'
@@ -28,7 +33,6 @@ def nch_and_spacing(request):
def propagation(input_power, con_in, con_out, dest): def propagation(input_power, con_in, con_out, dest):
equipment = load_equipment(eqpt_library_name) equipment = load_equipment(eqpt_library_name)
network = load_network(network_file_name, equipment) network = load_network(network_file_name, equipment)
build_network(network, equipment, 0, 20)
# parametrize the network elements with the con losses and adapt gain # parametrize the network elements with the con losses and adapt gain
# (assumes all spans are identical) # (assumes all spans are identical)
@@ -40,14 +44,15 @@ def propagation(input_power, con_in, con_out, dest):
if isinstance(e, Edfa): if isinstance(e, Edfa):
e.operational.gain_target = loss + con_in + con_out e.operational.gain_target = loss + con_in + con_out
build_network(network, equipment, 0, 20)
transceivers = {n.uid: n for n in network.nodes() if isinstance(n, Transceiver)} transceivers = {n.uid: n for n in network.nodes() if isinstance(n, Transceiver)}
p = input_power p = input_power
p = db2lin(p) * 1e-3 p = db2lin(p) * 1e-3
spacing = 50e9 # THz spacing = 50e9 # THz
si = create_input_spectral_information(f_min=191.3e12, f_max=191.3e12 + 79 * spacing, roll_off=0.15, 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, 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') source = next(transceivers[uid] for uid in transceivers if uid == 'trx A')
sink = next(transceivers[uid] for uid in transceivers if uid == dest) sink = next(transceivers[uid] for uid in transceivers if uid == dest)
path = dijkstra_path(network, source, sink) path = dijkstra_path(network, source, sink)
@@ -125,6 +130,62 @@ def test_dgd(dgd_test, dest):
assert pmd == pytest.approx(expected_pmd) assert pmd == pytest.approx(expected_pmd)
def wrong_element_propagate():
"""
"""
data = []
data.append({
"error": SpectrumError,
"json_data": {
"elements": [{
"uid": "Elem",
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"dispersion_per_frequency": {
"frequency": [
185.49234135667396e12,
186.05251641137855e12,
188.01312910284463e12,
189.99124726477024e12],
"value": [
1.60e-05,
1.67e-05,
1.7e-05,
1.8e-05]
},
"length": 1.02,
"loss_coef": 2.85,
"length_units": "km",
"att_in": 0.0,
"con_in": 0.0,
"con_out": 0.0
}
}],
"connections": []
},
"expected_msg": 'The spectrum bandwidth exceeds the frequency interval used to define the fiber Chromatic '
+ 'Dispersion in "Fiber Elem".\nSpectrum f_min-f_max: 191.35-196.1\nChromatic Dispersion '
+ 'f_min-f_max: 185.49-189.99'
})
return data
@pytest.mark.parametrize('error, json_data, expected_msg',
[(e['error'], e['json_data'], e['expected_msg']) for e in wrong_element_propagate()])
def test_json_element(error, json_data, expected_msg):
"""
Check that a missing key is correctly raisong the logger
"""
equipment = load_equipment(eqpt_library_name)
network = network_from_json(json_data, equipment)
elem = next(e for e in network.nodes() if e.uid == 'Elem')
si = create_input_spectral_information(f_min=191.3e12, f_max=196.1e12, roll_off=0.15,
baud_rate=32e9, power=1.0e-3, spacing=50.0e9, tx_osnr=45)
with pytest.raises(error, match=re.escape(expected_msg)):
_ = elem(si)
if __name__ == '__main__': if __name__ == '__main__':
from logging import getLogger, basicConfig, INFO from logging import getLogger, basicConfig, INFO
logger = getLogger(__name__) logger = getLogger(__name__)

View File

@@ -13,15 +13,18 @@ checks that restrictions in roadms are correctly applied during autodesign
from pathlib import Path from pathlib import Path
import pytest import pytest
from numpy.testing import assert_allclose from numpy.testing import assert_allclose
from numpy import ndarray, mean
from copy import deepcopy
from gnpy.core.utils import lin2db, automatic_nch from gnpy.core.utils import lin2db, automatic_nch
from gnpy.core.elements import Fused, Roadm, Edfa from gnpy.core.elements import Fused, Roadm, Edfa, Transceiver, EdfaOperational, EdfaParams, Fiber
from gnpy.core.network import build_network from gnpy.core.parameters import FiberParams, RoadmParams, FusedParams
from gnpy.core.network import build_network, design_network
from gnpy.tools.json_io import network_from_json, load_equipment, load_json, Amp from gnpy.tools.json_io import network_from_json, load_equipment, load_json, Amp
from gnpy.core.equipment import trx_mode_params from gnpy.core.equipment import trx_mode_params
from gnpy.topology.request import PathRequest, compute_constrained_path, ref_carrier from gnpy.topology.request import PathRequest, compute_constrained_path, propagate
from gnpy.core.info import create_input_spectral_information from gnpy.core.info import create_input_spectral_information, Carrier
from gnpy.core.utils import db2lin from gnpy.core.utils import db2lin, dbm2watt
TEST_DIR = Path(__file__).parent TEST_DIR = Path(__file__).parent
EQPT_LIBRARY_NAME = TEST_DIR / 'data/eqpt_config.json' EQPT_LIBRARY_NAME = TEST_DIR / 'data/eqpt_config.json'
@@ -218,6 +221,7 @@ def test_roadm_target_power(prev_node_type, effective_pch_out_db, power_dbm):
power can not be met in this last case. power can not be met in this last case.
""" """
equipment = load_equipment(EQPT_LIBRARY_NAME) equipment = load_equipment(EQPT_LIBRARY_NAME)
equipment['SI']['default'].power_dbm = power_dbm
json_network = load_json(TEST_DIR / 'data/twohops_roadm_power_test.json') json_network = load_json(TEST_DIR / 'data/twohops_roadm_power_test.json')
prev_node = next(n for n in json_network['elements'] if n['uid'] == 'west edfa in node B to ila2') prev_node = next(n for n in json_network['elements'] if n['uid'] == 'west edfa in node B to ila2')
json_network['elements'].remove(prev_node) json_network['elements'].remove(prev_node)
@@ -254,11 +258,11 @@ def test_roadm_target_power(prev_node_type, effective_pch_out_db, power_dbm):
path = compute_constrained_path(network, req) path = compute_constrained_path(network, req)
si = create_input_spectral_information( 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, 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)) power=req.power, spacing=req.spacing, tx_osnr=req.tx_osnr)
for i, el in enumerate(path): for i, el in enumerate(path):
if isinstance(el, Roadm): if isinstance(el, Roadm):
power_in_roadm = si.signal + si.ase + si.nli power_in_roadm = si.signal + si.ase + si.nli
si = el(si, degree=path[i + 1].uid) si = el(si, degree=path[i + 1].uid, from_degree=path[i - 1].uid)
power_out_roadm = si.signal + si.ase + si.nli power_out_roadm = si.signal + si.ase + si.nli
if el.uid == 'roadm node B': if el.uid == 'roadm node B':
# if previous was an EDFA, power level at ROADM input is enough for the ROADM to apply its # if previous was an EDFA, power level at ROADM input is enough for the ROADM to apply its
@@ -274,12 +278,252 @@ def test_roadm_target_power(prev_node_type, effective_pch_out_db, power_dbm):
assert_allclose(el.ref_pch_out_dbm, effective_pch_out_db, rtol=1e-3) assert_allclose(el.ref_pch_out_dbm, effective_pch_out_db, rtol=1e-3)
# Check that egress power of roadm is equal to target power # Check that egress power of roadm is equal to target power
assert_allclose(power_out_roadm, db2lin(effective_pch_out_db - 30), rtol=1e-3) assert_allclose(power_out_roadm, db2lin(effective_pch_out_db - 30), rtol=1e-3)
elif prev_node_type == 'fused': if prev_node_type == 'fused':
# fused prev_node does reamplfy power after fiber propagation, so input power # fused prev_node does not reamplify power after fiber propagation, so input power
# to roadm is low. # to roadm is low.
# check that target power correctly reports power_dbm from previous propagation # 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) assert_allclose(el.ref_pch_out_dbm, effective_pch_out_db + power_dbm, rtol=1e-3)
# Check that egress power of roadm is not equalized power out is the same as power in. # 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) assert_allclose(power_out_roadm, power_in_roadm, rtol=1e-3)
assert effective_pch_out_db + power_dbm ==\
pytest.approx(lin2db(min(power_in_roadm) * 1e3), rel=1e-3)
else: else:
si = el(si) si = el(si)
def create_per_oms_request(network, eqpt, req_power):
"""Create requests between every adjacent ROADMs + one additional request crossing several ROADMs
"""
nb_channel = automatic_nch(eqpt['SI']['default'].f_min, eqpt['SI']['default'].f_max,
eqpt['SI']['default'].spacing)
params = {
'trx_type': '',
'trx_mode': '',
'bidir': False,
'loose_list': ['strict', 'strict'],
'format': '',
'path_bandwidth': 100e9,
'effective_freq_slot': None,
'nb_channel': nb_channel
}
trx_params = trx_mode_params(eqpt)
params.update(trx_params)
trxs = [e for e in network if isinstance(e, Transceiver)]
req_list = []
req_id = 0
for trx in trxs:
source = trx.uid
roadm = next(n for n in network.successors(trx) if isinstance(n, Roadm))
for degree in roadm.per_degree_pch_out_dbm.keys():
node = next(n for n in network.nodes() if n.uid == degree)
# find next roadm
while not isinstance(node, Roadm):
node = next(n for n in network.successors(node))
next_roadm = node
destination = next(n.uid for n in network.successors(next_roadm) if isinstance(n, Transceiver))
params['request_id'] = req_id
req_id += 1
params['source'] = source
params['destination'] = destination
params['nodes_list'] = [degree, destination]
req = PathRequest(**params)
req.power = dbm2watt(req_power)
carrier = {key: getattr(req, key) for key in ['baud_rate', 'roll_off', 'tx_osnr']}
carrier['label'] = ""
carrier['slot_width'] = req.spacing
carrier['delta_pdb'] = 0
req.initial_spectrum = {(req.f_min + req.spacing * f): Carrier(**carrier)
for f in range(1, req.nb_channel + 1)}
req_list.append(req)
# add one additional request crossing several roadms to have a complete view
params['source'] = 'trx Rennes_STA'
params['destination'] = 'trx Vannes_KBE'
params['nodes_list'] = ['roadm Lannion_CAS', 'trx Vannes_KBE']
params['bidir'] = True
req = PathRequest(**params)
req.power = dbm2watt(req_power)
carrier = {key: getattr(req, key) for key in ['baud_rate', 'roll_off', 'tx_osnr']}
carrier['label'] = ""
carrier['slot_width'] = req.spacing
carrier['delta_pdb'] = 0
req.initial_spectrum = {(req.f_min + req.spacing * f): Carrier(**carrier) for f in range(1, req.nb_channel + 1)}
req_list.append(req)
return req_list
def list_element_attr(element):
"""Return the list of keys to be checked depending on element type. List only the keys that are not
created upon element effective propagation
"""
if isinstance(element, Roadm):
return ['uid', 'name', 'metadata', 'operational', 'type_variety', 'target_pch_out_dbm',
'passive', 'restrictions', 'per_degree_pch_out_dbm',
'target_psd_out_mWperGHz', 'per_degree_pch_psd']
# Dynamically created: 'effective_loss',
if isinstance(element, RoadmParams):
return ['target_pch_out_dbm', 'target_psd_out_mWperGHz', 'per_degree_pch_out_db', 'per_degree_pch_psd',
'add_drop_osnr', 'pmd', 'restrictions']
if isinstance(element, Edfa):
return ['variety_list', 'uid', 'name', 'params', 'metadata', 'operational',
'passive', 'effective_gain', 'delta_p', 'tilt_target', 'out_voa']
# TODO this exhaustive test highlighted that type_variety is not correctly updated from EdfaParams to
# attributes in preamps
# Dynamically created only with channel propagation: 'att_in', 'channel_freq', 'effective_pch_out_db'
# 'gprofile', 'interpol_dgt', 'interpol_gain_ripple', 'interpol_nf_ripple', 'nch', 'nf', 'pin_db', 'pout_db',
# 'target_pch_out_db',
if isinstance(element, FusedParams):
return ['loss']
if isinstance(element, EdfaOperational):
return ['delta_p', 'gain_target', 'out_voa', 'tilt_target']
if isinstance(element, EdfaParams):
return ['f_min', 'f_max', 'type_variety', 'type_def', 'gain_flatmax', 'gain_min', 'p_max', 'nf_model',
'dual_stage_model', 'nf_fit_coeff', 'nf_ripple', 'dgt', 'gain_ripple', 'out_voa_auto',
'allowed_for_design', 'raman']
if isinstance(element, Fiber):
return ['uid', 'name', 'params', 'metadata', 'operational', 'type_variety', 'passive',
'lumped_losses', 'z_lumped_losses']
# Dynamically created 'output_total_power', 'pch_out_db'
if isinstance(element, FiberParams):
return ['_length', '_att_in', '_con_in', '_con_out', '_ref_frequency', '_ref_wavelength',
'_dispersion', '_dispersion_slope', '_dispersion', '_f_dispersion_ref',
'_gamma', '_pmd_coef', '_loss_coef',
'_f_loss_ref', '_lumped_losses']
if isinstance(element, Fused):
return ['uid', 'name', 'params', 'metadata', 'operational', 'loss', 'passive']
if isinstance(element, FusedParams):
return ['loss']
return ['should never come here']
# all initial delta_p are null in topo file, so add random places to change this value
@pytest.mark.parametrize('amp_with_deltap_one', [[],
['east edfa in Lorient_KMA to Vannes_KBE',
'east edfa in Stbrieuc to Rennes_STA',
'west edfa in Lannion_CAS to Morlaix',
'east edfa in a to b',
'west edfa in b to a']])
@pytest.mark.parametrize('power_dbm, req_power', [(0, 0), (0, -3), (3, 3), (0, 3), (3, 0),
(3, 1), (3, 5), (3, 2), (3, 4), (2, 4)])
def test_compare_design_propagation_settings(power_dbm, req_power, amp_with_deltap_one):
"""Check that network design does not change after propagation except for gain in
case of power_saturation during design and/or during propagation:
- in power mode only:
expected behaviour: target power out of roadm does not change
so gain of booster should be reduced/augmented by the exact power difference;
the following amplifiers on the OMS have unchanged gain except if augmentation
of channel power on booster leads to total_power above amplifier max power,
ie if amplifier saturates.
roadm -----booster (pmax 21dBm, 96 channels= 19.82dB)
pdesign=0dBm pch= 0dBm, ^ -20dBm ^G=20dB, Pch=0dBm, Ptot=19.82dBm
pdesign=0dBm pch= -3dBm ^ -20dBm ^G=17dB, Pch=-3dBm, Ptot=16.82dBm
pdesign=3dBm pch= 3dBm ^ -20dBm ^G=23-1.82dB, Pch=1.18dBm, Ptot=21dBm
amplifier can not handle 96x3dBm channels, amplifier saturation is considered
for the choice of amplifier during design
pdesign=0dBm pch= 3dBm ^ -20dBm ^G=23-1.82dB, Pch=1.18dBm, Ptot=21dBm
amplifier can not handle 96x3dBm channels during propagation, amplifier selection
has been done for 0dBm. Saturation is applied for all amps only during propagation
Design applies a saturation verification on amplifiers.
This saturation leads to a power reduction to the max power in the amp library, which
is also applied on the amp delta_p and independantly from propagation.
After design, upon propagation, the amplifier gain and applied delta_p may also change
if total power exceeds max power (eg not the same nb of channels, not the same power per channel
compared to design).
This test also checks all the possible combinations and expected before/after propagation
gain differences. It also checks delta_p applied due to saturation during design.
"""
eqpt = load_equipment(EQPT_LIBRARY_NAME)
eqpt['SI']['default'].power_dbm = power_dbm
json_network = load_json(NETWORK_FILE_NAME)
for element in json_network['elements']:
# Initialize a value for delta_p
if element['type'] == 'Edfa':
element['operational']['delta_p'] = 0 + element['operational']['out_voa'] \
if element['operational']['out_voa'] is not None else 0
# apply a 1 dB delta_p on the set of amps
if element['uid'] in amp_with_deltap_one:
element['operational']['delta_p'] = 1
network = network_from_json(json_network, eqpt)
# Build the network once using the default power defined in SI in eqpt config
p_db = power_dbm
p_total_db = p_db + lin2db(automatic_nch(eqpt['SI']['default'].f_min,
eqpt['SI']['default'].f_max,
eqpt['SI']['default'].spacing))
build_network(network, eqpt, p_db, p_total_db, verbose=False)
# record network settings before propagating
# propagate on each oms
req_list = create_per_oms_request(network, eqpt, req_power)
paths = [compute_constrained_path(network, r) for r in req_list]
# systematic comparison of elements settings before and after propagation
# all amps have 21 dBm max power
pch_max = 21 - lin2db(96)
for path, req in zip(paths, req_list):
# check all elements except source and destination trx
# in order to have clean initialization, use deecopy of paths
design_network(req, network, eqpt, verbose=False)
network_copy = deepcopy(network)
pth = deepcopy(path)
_ = propagate(pth, req, eqpt)
for i, element in enumerate(pth[1:-1]):
element_is_first_amp = False
# index of previous element in path is i
if (isinstance(element, Edfa) and isinstance(pth[i], Roadm)) or element.uid == 'west edfa in d to c':
# oms c to d has no booster but one preamp: the power difference is hold there
element_is_first_amp = True
# find the element with the same id in the network_copy
element_copy = next(n for n in network_copy.nodes() if n.uid == element.uid)
for key in list_element_attr(element):
if not isinstance(getattr(element, key),
(EdfaOperational, EdfaParams, FiberParams, RoadmParams, FusedParams)):
if not key == 'effective_gain':
# for all keys, before and after design should be the same except for gain (in power mode)
if isinstance(getattr(element, key), ndarray):
if len(getattr(element, key)) > 0:
assert getattr(element, key) == getattr(element_copy, key)
else:
assert len(getattr(element_copy, key)) == 0
else:
assert getattr(element, key) == getattr(element_copy, key)
else:
dp = element.out_voa if element.uid not in amp_with_deltap_one else element.out_voa + 1
# check that target power is correctly set
assert element.target_pch_out_dbm == req_power + dp
# check that designed gain is exactly applied except if target power exceeds max power, then
# gain is slightly less than the one computed during design for the noiseless reference,
# because during propagation, noise has accumulated, additing to signal.
# check that delta_p is unchanged unless for saturation
if element.target_pch_out_dbm > pch_max:
assert element.effective_gain == pytest.approx(element_copy.effective_gain, abs=2e-2)
else:
assert element.effective_gain == element_copy.effective_gain
# check that delta_p is unchanged unless for saturation
assert element.delta_p == element_copy.delta_p
if element_is_first_amp:
# if element is first amp on path, then it is the one that will saturate if req_power is
# too high
assert mean(element.pch_out_dbm) ==\
pytest.approx(min(pch_max, req_power + element.delta_p - element.out_voa), abs=2e-2)
# check that delta_p is unchanged unless due to saturation
assert element.delta_p == pytest.approx(min(req_power + dp, pch_max) - req_power, abs=1e-2)
# check that delta_p is unchanged unless for saturation
else:
# for all subkeys, before and after design should be the same
for subkey in list_element_attr(getattr(element, key)):
if isinstance(getattr(getattr(element, key), subkey), list):
assert getattr(getattr(element, key), subkey) == getattr(getattr(element_copy, key), subkey)
elif isinstance(getattr(getattr(element, key), subkey), dict):
for value1, value2 in zip(getattr(getattr(element, key), subkey).values(),
getattr(getattr(element_copy, key), subkey).values()):
assert all(value1 == value2)
elif isinstance(getattr(getattr(element, key), subkey), ndarray):
assert_allclose(getattr(getattr(element, key), subkey),
getattr(getattr(element_copy, key), subkey), rtol=1e-12)
else:
assert getattr(getattr(element, key), subkey) == getattr(getattr(element_copy, key), subkey)

View File

@@ -12,8 +12,7 @@ from numpy.testing import assert_allclose
from numpy import array from numpy import array
import pytest import pytest
from gnpy.core.info import create_input_spectral_information, create_arbitrary_spectral_information, Pref, \ from gnpy.core.info import create_input_spectral_information, create_arbitrary_spectral_information
ReferenceCarrier
from gnpy.core.elements import Fiber, RamanFiber from gnpy.core.elements import Fiber, RamanFiber
from gnpy.core.parameters import SimParams from gnpy.core.parameters import SimParams
from gnpy.tools.json_io import load_json from gnpy.tools.json_io import load_json
@@ -26,12 +25,10 @@ TEST_DIR = Path(__file__).parent
def test_fiber(): def test_fiber():
"""Test the accuracy of propagating the Fiber.""" """Test the accuracy of propagating the Fiber."""
fiber = Fiber(**load_json(TEST_DIR / 'data' / 'test_science_utils_fiber_config.json')) fiber = Fiber(**load_json(TEST_DIR / 'data' / 'test_science_utils_fiber_config.json'))
fiber.ref_pch_in_dbm = 0.0
# fix grid spectral information generation # fix grid spectral information generation
spectral_info_input = create_input_spectral_information(f_min=191.3e12, f_max=196.1e12, roll_off=0.15, 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, tx_osnr=40.0, baud_rate=32e9, power=1e-3, spacing=50e9, tx_osnr=40.0)
ref_carrier=
ReferenceCarrier(baud_rate=32e9, slot_width=50e9))
# propagation # propagation
spectral_info_out = fiber(spectral_info_input) spectral_info_out = fiber(spectral_info_input)
@@ -48,11 +45,10 @@ def test_fiber():
baud_rate = array([32e9, 42e9, 64e9, 42e9, 32e9]) baud_rate = array([32e9, 42e9, 64e9, 42e9, 32e9])
signal = 1e-3 + array([0, -1e-4, 3e-4, -2e-4, +2e-4]) signal = 1e-3 + array([0, -1e-4, 3e-4, -2e-4, +2e-4])
delta_pdb_per_channel = [0, 0, 0, 0, 0] 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, 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, delta_pdb_per_channel=delta_pdb_per_channel,
tx_osnr=40.0, ref_power=pref) tx_osnr=40.0)
# propagation # propagation
spectral_info_out = fiber(spectral_info_input) spectral_info_out = fiber(spectral_info_input)
@@ -70,11 +66,10 @@ def test_raman_fiber():
"""Test the accuracy of propagating the RamanFiber.""" """Test the accuracy of propagating the RamanFiber."""
# spectral information generation # spectral information generation
spectral_info_input = create_input_spectral_information(f_min=191.3e12, f_max=196.1e12, roll_off=0.15, 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, tx_osnr=40.0, 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')) SimParams.set_params(load_json(TEST_DIR / 'data' / 'sim_params.json'))
fiber = RamanFiber(**load_json(TEST_DIR / 'data' / 'test_science_utils_fiber_config.json')) fiber = RamanFiber(**load_json(TEST_DIR / 'data' / 'test_science_utils_fiber_config.json'))
fiber.ref_pch_in_dbm = 0.0
# propagation # propagation
spectral_info_out = fiber(spectral_info_input) spectral_info_out = fiber(spectral_info_input)
@@ -108,9 +103,7 @@ def test_fiber_lumped_losses_srs(set_sim_params):
"""Test the accuracy of Fiber with lumped losses propagation.""" """Test the accuracy of Fiber with lumped losses propagation."""
# spectral information generation # spectral information generation
spectral_info_input = create_input_spectral_information(f_min=191.3e12, f_max=196.1e12, roll_off=0.15, 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, tx_osnr=40.0, 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')) 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')) fiber = Fiber(**load_json(TEST_DIR / 'data' / 'test_lumped_losses_raman_fiber_config.json'))

10
tox.ini
View File

@@ -2,9 +2,8 @@
skipsdist = True skipsdist = True
[testenv] [testenv]
extras = tests
deps = deps =
-r{toxinidir}/requirements.txt
-r{toxinidir}/tests/requirements.txt
cover: pytest-cov cover: pytest-cov
linters: flake8 linters: flake8
linters: pep8-naming linters: pep8-naming
@@ -22,9 +21,8 @@ commands =
python -m build python -m build
[testenv:docs] [testenv:docs]
deps = extras = docs
-r{toxinidir}/docs/requirements.txt allowlist_externals =
whitelist_externals =
/bin/sh /bin/sh
commands = commands =
sphinx-build -E -W --keep-going -q -b html docs/ doc/build/html sphinx-build -E -W --keep-going -q -b html docs/ doc/build/html
@@ -35,7 +33,7 @@ commands =
flake8 {posargs} flake8 {posargs}
[testenv:linters-diff-ci] [testenv:linters-diff-ci]
whitelist_externals = bash allowlist_externals = bash
commands = commands =
flake8 {posargs} --format html --htmldir linters --exit-zero flake8 {posargs} --format html --htmldir linters --exit-zero
bash -c "git diff -U0 origin/$(git rev-parse --abbrev-ref HEAD) | flake8 --diff {posargs}" bash -c "git diff -U0 origin/$(git rev-parse --abbrev-ref HEAD) | flake8 --diff {posargs}"