Oops. We are not using gating, which means that changes are tested
against the "current tip of the branch" and might pass fine there, but
once they are merged, there can well be a conflict between them. This
has just happened.
The EDFA which reported a difference had its VOA set to 0.5. Previously,
this was not taken into assumption.
Fixes: ce51a4d1 Take explicitly set out_voa value into account in power calculation
Fixes: 280443f1 add an invocation test with power saturation
Change-Id: Icebbb16d2ef5886d2c9c04cc9a300a6aa08bf245
* changes:
tests: add OpenROADMv5 example propagation
OpenROADM: mark example config files as v4 explicitly
Add an eqpt config file matching latest OpenROADM MSA version
Add updated openroadm amp specifications to eqpt config
add several power reference setting tests to the existing test
the test only checks the power level out of roadm B.
if previous node is a preamp, power level is the one specified in
target_pch_out_db.
if previous node is a fused , power level at roadm input is below
target_pch_out_db and roadm can not increase this power (no amp).
then expected outpower is in_power, which should be equal to -22 + power_dBm
on this particular node.
nota bene
currently, no minimum losss is coded on roadm, so that the applied loss
is 0 dB, and roadm does not affect power in this case.
This behaviour is not correct and should be changed in the future.
But for now, I am only concentrating on existing behaviour tests.
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I34fe2dcf2d355b291c27745ab511d3d77057dd94
The recent commit has added support for OpenROADM v5, the latest
published optical spec sheet. Given that the upstream project has
released v10 YANG files (but still just v3, v4 and v5 XLS sheets with
optical performance numbers), I think it would be rather misleading to
have both versioned and non-versioned config files -- especially when
the unversioned one refers to the oldest release, not the newest one.
Change-Id: I04109341724b51d276660d400c923dc28561aef2
The compare_reqs function checks if N and M values of the requests are
None but these attributes may not exist e.g. if a service file does not
define an "effective-freq-slot" for a request.
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Change-Id: I786aad97ed658cd703694f164a87525d77b51fe1
We've been accidentally not updating the `latest` tag on Docker hub
after switching from Travis CI to GitHub actions. Traditionally, we've
assumed the `latest` points to the "latest release", so this patch makes
it simple and will call any pushed "version tag" as the `latest`. This
will become a problem if/when we start maintaining multiple releases,
but I think it's a safe approach for now.
As before, there's also the `master` tag which always points to the,
well, master branch of the repo.
Change-Id: I14c08b12010986d4327bd9d685619a98cfec370f
The docs used to point to in-the-tree source code of the documentation
in the RST format. When navigating from the landing page on GitHub, this
led to GitHub's rendering of the RST, which is rather incomplete. Just
point to readthedocs to get a nice doc format.
Change-Id: I985a8fd1688337b4e0e47cdb09b666cf4e96cc1b
- if specified, they must be used except:
- if N and M are not consistant (eg M smaller than the required
spectrum for the demand)
- if N value and M value lead to occupation outside of the band
- if spectrum is occupied
- if any of them is None, the program uses the first fit strategy for M and
the path_bandwidth value to compute minimum required M
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I9160ffb116dd9d7d53ad80638826b609a1367446
this sort of verification should be covered by automatic tests
since this is a verification of the correct behaviour of the
spectrum_selection function
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I76dd3bcad74085e1cd36ecb6503dad0271b61b80
Change tests based on M==0 value for response creation and use
instead the blocking_reason attribute existence
result element should have non null M value if request is not blocked.
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I67e4222cf9d014201e91d3aefd3624b001264e03
in case spectrum can not be assigned default value for N
was set to 0, which is not correct (N is a meaningfull value for
center frequency index). This changes replaces this default
value with None
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: Ibe642682e48d09f340d53e2092f172de6aa7cc90
use the new function compute_spectrum_slot_vs_bandwidth
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: If045fe53550dbde57c56fd4e8b99275c0757ea2b
In case user defines trx_mode, it is possible to check consistency of
nb of required slots and the total requested path_bandwidth and raise
a service error, before staring any propagation computation.
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I543cab581280faef5d6072eb172da136f2542492
before 'effective-freq-slot' was just ignored, and filled with "null" strings.
this is no longer supported
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I24d30de91b8b29d37f6ba81220d3cad5aabb6781
For this commit only the first element from the {N, M} list is read
and assigned.
This is better than not reading this value at all.
the commit also updates test_files and test data files with correct
values for the effective_freq_slot attribute
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I1e60fe833ca1092b40de27c8cbfb13083810414e
if the user has specified a nb of slot and has not specified a mode
it may happen that the nb of slot is finally not large enough to support
the requested traffic: then blocking reason is 'NOT_ENOUGH_RESERVED_SPECTRUM'
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I8d4c4df5fa97e37aefac8d9ee0d93c901505fa55
When a path is blocked for 'NO_FEASIBLE_MODE' reason, and bidir is true,
the request attributes are filled with the last explored mode values
(baudrate notably), and the reversed path is propagated with this last
explored mode specs. if this reversed path is also not feasible the blocking
reason was overwritten with a 'MODE_NOT_FESIBLE' reasonn, because
baudrate is filled in the request attribute.
This change ensure that the blocking reason (if it exists) is not overwritten.
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: If80a37d77e2b967a327562c733a44e7f78f1c544
This adds a separate OpenROADM eqpt config file corresponding to the
latest version of the MSA:
https://0201.nccdn.net/4_2/000/000/071/260/20210629_open-roadm_msa_specification_ver5.0.xlsx
The existing config file corresponding to the old version is kept for
backward compatibility. The new version introduces the following
changes:
* New definition of incremental OSNR for a ROADM based on polynomial
(see also previous commit).
* ROADM add path OSNR changed from 30 dB to 33 dB
* New transceiver mode: 200 Gbit/s, 31.57 Gbaud, DP-16QAM
* Tx OSNR for transceiver mode 100 Gbit/s, 31.57 Gbaud, DP-QPSK changed
from 35 dB to 36 dB
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Change-Id: Ieb7d33bd448ed9d0cb8320ed190019c9aa94c9ef
The latest version 5.0 of the OpenROADM MSA changes the definition
of the incremental OSNR mask of a ROADM to a polynomial:
https://0201.nccdn.net/4_2/000/000/071/260/20210629_open-roadm_msa_specification_ver5.0.xlsx
A new preamp type variety corresponding to the updated specification is
added to the default eqpt config file while also keeping the type
variety corresponding to the old specification for backward
compatibility.
The updated specification includes both typical and worst case values.
These are added as separate type varieties to let the user choose which
values to use. Note that the specification with typical values is
identical to the existing OpenROADM ILA standard type variety but a new
type variety is still added for clarity.
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Change-Id: I2de5e9db69f9ae3b218e30a3b246bd9b83cef458
Auto-design tries to split fibers longer than the max_length parameter
specified in the eqpt config file. When calculating new fiber lengths,
it uses a target_length parameter, which is currently hardcoded to 90
km. If the user specifies a max_length that is shorter than the
target_length and the topology includes any fiber that is longer than
the max_length but shorter than the hardcoded target_length, the
calculation crashes with a ZeroDivisionError. This patch limits the
target_length parameter so that it can't be longer than max_length.
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Change-Id: Id0851fcf79ab0b1a05832e22ee7e9cf63691446c
Previous set of tests did not correctly check the combinations of
disjunction and route constraint. This new set tests specific cases
with several demands in one synchronization vector with and without
route constraint, and the case where both disjunction constraint and
route can not be met (STRICT and LOOSE cases)
+ minor refactor on test_disjunction
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: Id5a5902e6945185922ce5743ac97d15dbc777af2
When delta_p or target_pch_out_db is None (resulting e.g. from
operating in gain mode) the current logic replaces a whole printed
line with 'None' which does not look very nice in the script outputs.
With this patch, the parameter information is kept in the printout
like this:
Delta_P (dB): None
target pch (dBm): None
Change-Id: Ie52ce7353a708a174cf9d769918a6136eefbf444
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Fixes: 225cafa8 (Floating point formatting of elements' operational parameters)
I've been getting reports that the test suite is broken on Windows (the
usual set of problems such as CRLF line endings and backslashes in path
names), so let's make sure we have a way of reproducing this.
Unfortunately, we don't have a Windows image in Zuul, so this will be a
post-merge CI I'm afraid :(.
Change-Id: Ibd539764d6e40693b95a9b231324bd0216e4a207
Let's use the text mode everywhere because Unicode codepoints is what
matters. The only catch on Windows turned out to be the default file IO
encoding; forcing UTF-8 there fixes all issues in the CI (and it makes
sense because that file was written out in a UTF-8 locale, and the
system which runs the test suite might be set to something else.
This was a rather interesting debugging experience; passing logs over
the web and handling "strange" characters as utf-8 did not help.
Change-Id: I1fdbe3a115458558b27a81f9eab8e58c9605bae7
Bug: https://github.com/Telecominfraproject/oopt-gnpy/issues/358
We have a test which compares the raw output of GNPy against a fixed
expected output. That comparison of course chokes when forward slashes
and backslashes are used, which breaks the test suite on Windows. Let's
try to solve this by always using forward slashes if possible. The way
to go is via pathlib's as_posix(), but that one can possibly return an
absolute path -- which cannot work in a test suite, obviously. So one
can workaround that via calling a Path.relative_to(), but that one
chokes on paths which require at least one "path up" component (`..`).
I posted a patch which use brute force here, but Jonas is right, better
just don't print that output in the test suite in the first place.
Change-Id: I762ddb58a2042120c7b20414152a06a3ed72048d
Bug: https://github.com/Telecominfraproject/oopt-gnpy/issues/358
As mentioned in GitHub issue #409, an out_voa value for an EDFA
explicitly set in the topology file is not taken into account by
auto-design when calculating target power and gain. I think it is
more logical if the target power resulting from the optimization
algorithm represents the desired power into the fiber. This is also
more consistent with the behaviour for an automatically set out_voa
value when out_voa_auto is set to true.
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Change-Id: I7e58b61d0bf30728c39d36404619dbe370c12f2b
When `pytest` is run with `-vv`, it shows a diff of multiline strings
and dict just fine. The only drawback is that there's the raw string
with newlines shown as "\n", however, *then* the nice diff pretty
printing kicks in, and the result is:
E Common items:
E {'response-id': '5'}
E Differing items:
E {'path-properties': {'path-metric': [{'accumulative-value': 21.68, 'metric-type': 'SNR-bandwidth'}, {'accumulative-val...EDFA', 'link-tp-id': 'east edfa in Rennes_STA to Stbrieuc', 'node-id': 'east edfa in Rennes_STA to Stbrieuc'}}}, ...]}} != {'path-properties': {'path-metric': [{'accumulative-value': 21.68, 'metric-type': 'SNR-bandwidth'}, {'accumulative-val...EDFA', 'link-tp-id': 'east edfa in Rennes_STA to Stbrieuc', 'node-id': 'east edfa in Rennes_STA to Stbrieuc'}}}, ...]}}
E Full diff:
E {
E 'path-properties': {'path-metric': [{'accumulative-value': 21.68,
E 'metric-type': 'SNR-bandwidth'},
E {'accumulative-value': 28.77,
E 'metric-type': 'SNR-0.1nm'},
E {'accumulative-value': 23.7,
E 'metric-type': 'OSNR-bandwidth'},
E {'accumulative-value': 30.79,
E 'metric-type': 'OSNR-0.1nm'},
E {'accumulative-value': 0.0019952623149688794,
E 'metric-type': 'reference_power'},
E {'accumulative-value': 20000000000.0,
E 'metric-type': 'path_bandwidth'}],
...
... now, it's a bit annoying that there's too much output, but
... that's just for context; the offending lines will be properly
... marked, see --\
... |
... v
...
E {'path-route-object': {'index': 17,
E - 'num-unnum-hop': {'gnpy-node-type': 'transceiver',
E ? ^ ^^^^^^^ - ^ ^^^^^^^^^ -
E + 'num-unnum-hop': {'link-tp-id': 'trx '
E ? ^^ ^ ^^^ ^^
E - 'link-tp-id': 'trx '
E 'Lannion_CAS',
E 'node-id': 'trx '
E 'Lannion_CAS'}}},
E {'path-route-object': {'index': 18,
E 'label-hop': {'M': 6,
E 'N': -274}}},
E {'path-route-object': {'index': 19,
E 'transponder': {'transponder-mode': 'mode '
E '2',
E 'transponder-type': 'vendorA_trx-type1'}}}]},
E 'response-id': '5',
E }
tests/test_parser.py:312: AssertionError
Change-Id: I60b4e3bfa432a720a381bf2c0a9f0288e989dab2
GNPy 2.3.1
Just some release automation on top of v2.3. If you're already on v2.3,
there's no need to update; this release does not contain any
user-visible changes.
Change-Id: I0473a0bb43be596cf376cf18eb8a546b53aa0214
Pushes to master should create a "development" tag. Tags should create
something prettier.
We need the git checkout for proper package versioning, hence that magic
`context` thing, and also that magic `echo`.
Change-Id: I79fcb800cc079e8486c3795f36aa1993676cee49
Our landing page on PyPI was not displaying the longer version of the
README, just a one-sentence summary. It turns out that `pbr` can indeed
read the README file, but specifying the `description` overrides that
with no warning. Yay.
Change-Id: Ic03412928fe09f5edab4a7b9f4297a485a740cd0
We're using PBR, so let's make sure we don't get a package that's marked
as version 0.0.0.
Bug: https://github.com/actions/checkout/issues/217
Change-Id: Icd8264a798f9a1a404e21a9b64317c57662d53fe
This might be a wee bit controversial, I guess, because the Zuul jobs
look like there's a dedicated playbook for that
(playbooks/python/release.yaml). However, that would be one extra VM
launch, which feels wasteful. Let's waste the CPU cycles elsewhere --
during each "regular test build", produce a wheel as well.
It looks that these "wheels" are *the* format for distributing Python
packages now -- including the source code, of course. Since there's no
real support for tag review in Gerrit, I don't think I need Zuul for
release management, either, so I'll just rely on GitHub actions for
release upload, I guess. And for that, I need to "somehow" create a
wheel anyway, so let's just do this all the time to ensure that it
really works and never stops working.
Change-Id: Ib86852a386673cd4929a8059b19fa527cd4d5955
We have Zuul, and we're happy with it; however, every now and then
there's a problem with the managed infrastructure, and there's also
people who contribute patches as GitHub PRs.
Change-Id: I405c5806ed9ad2e7f59f9b2394daf068b373e425
Our landing page on PyPI was not displaying the longer version of the
README, just a one-sentence summary. It turns out that `pbr` can indeed
read the README file, but specifying the `description` overrides that
with no warning. Yay.
Change-Id: Ic03412928fe09f5edab4a7b9f4297a485a740cd0
We're using PBR, so let's make sure we don't get a package that's marked
as version 0.0.0.
Bug: https://github.com/actions/checkout/issues/217
Change-Id: Icd8264a798f9a1a404e21a9b64317c57662d53fe
This might be a wee bit controversial, I guess, because the Zuul jobs
look like there's a dedicated playbook for that
(playbooks/python/release.yaml). However, that would be one extra VM
launch, which feels wasteful. Let's waste the CPU cycles elsewhere --
during each "regular test build", produce a wheel as well.
It looks that these "wheels" are *the* format for distributing Python
packages now -- including the source code, of course. Since there's no
real support for tag review in Gerrit, I don't think I need Zuul for
release management, either, so I'll just rely on GitHub actions for
release upload, I guess. And for that, I need to "somehow" create a
wheel anyway, so let's just do this all the time to ensure that it
really works and never stops working.
Change-Id: Ib86852a386673cd4929a8059b19fa527cd4d5955
We have Zuul, and we're happy with it; however, every now and then
there's a problem with the managed infrastructure, and there's also
people who contribute patches as GitHub PRs.
Change-Id: I405c5806ed9ad2e7f59f9b2394daf068b373e425
We discussed this at one of the recent coder calls; the motivation
includes better mypy type hint support, especially in numpy, but also in
the language core, and of course the dataclasses.
Change-Id: I8ffee28c33f167cbcba978c85486e58a1b8c99be
All other noise models set the `nf_def` variable, so let's make the YANG
code simpler by remembering the amplifier NF model like that.
Change-Id: I341e4ac296c25bf9f27a98a7e4e92e0fd1546021
The current JSON data loader preserves (some) integers as integers. When
printed, the value might not contain any decimal points. The YANG patch
series, however, forces floats when floats are expected (while still
allowing None). This makes the output subtly different.
Change-Id: I0e0c013eb3abddb4aeac1ba43bf0d473fed731d4
The term "GSNR" is well established by now. I think it's time we start
using it in our own result outputs instead of alternatives like "total
SNR" or just "SNR".
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Change-Id: I1fc65f6db1e3b2d7cfe974875174132fe5b28d3b
Well, sleeping ain't fun. A red warning is plenty. In case of API
access, there's none, but that's just the APIs are.
Change-Id: I2fb0c051a9c3bb7f2ef2264083686e929c27ec2c
Fixes: 6a6591e4 (Add a warning message when attributes are missing in eqpt_config.json)
We ship "some" DGT values which effectively mask this, but it's possible
to provide a "trivial" DGT vector such as [0, 0]. When that happens, the
code was failing with a numpy-level warning related to a division by
zero.
The code tried to be ready for this by trying to catch an exception, but
this relied on a particular numpy behavior upon zero division which was
not set up properly. For the added fun, there are two possible cases of
division by zero:
- on a zero tilt, it's a case of `0.0 / np.float64(0.)`, which is
controlled via "invalid",
- on a non-zero tilt, it's a case of `<float> / np.float64(0.)`, which
leads to "divide".
Let's just check for zero instead of wrestling exceptions.
Change-Id: I7a3c0b6b9b85e90a8a7201b7c7a56a5a44c27d69
I dig through the git log, and it looks like something which was never
used after some refactorings 3+ years ago.
Change-Id: I3633a59d8f2720932fa32c885ee5be643e640a46
In the past, we had some manual version info in this file, but
apparently it never got updated past the 0.1 release (yay). The, in
4d5d10935 I changed this to retrieve the version information via PBR's
existing magic. That worked well, showing the abbreviated commit hash at
the footer on ReadTheDocs, but I don't think it was terribly useful:
- it was just a hash, nothing like the output of `git describe` (i.e.,
no tag info was there),
- it wasn't showing up in local docs builds which use the Alabaster
default theme.
Now, in 1b2eb9a5 I split the dependency handling. The idea was to make
sure that a "regular installation" would not pull the docs in
needlessly. Unfortunately, the way I set up the RTD builds, the common
dependencies were skipped, and as a result, the `pbr` package was not
available to RTD, and stuff failed.
I could have configured RTD to *also* install from the main deps, but I
don't think this is actually needed. Given that the version info is
rather subtle, let's skip it altogether. Instead, it's better to use
RTD's built-in features for switching between docs for a particular
release (via a git tag) and for the generic "master branch".
Change-Id: Iab0cc9608fa6c24eba93d772370ecd379cf65b1e
Fixes: 1b2eb9a5 (docs: separate out dependencies)
The auto-design feature inserts EDFAs after ROADMs and fibers when they
are not already present in the input topology file. This functionality
can be locally disabled by manually adding a Fused element in the
topology. This patch adds an option to the cli example scripts,
"--no-insert-edfas", which globally disables insertion of EDFAs as well
as automatic splitting of fibers.
Change-Id: If40aa6ac6d8b47d5e7b6f8eabfe389e8258cbce6
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
The intention is to separate "stuff that's needed by this package" from
"stuff that's needed to build the docs".
Change-Id: I7baf27e6f814880ea241ccbd3de4b87a6e7c4d1b
It was only assigned to in `read_service_sheet`, and it's safe to remove
it also in `convert_service_sheet`.
Change-Id: Ia832cd8fea2d864e920907e455e834a3c3a724dd
The README should be just that, a README. Ours was about four pages
long, that's a bit too much I'm afraid.
Change-Id: I646e9d09e512384898271e10ff628906299b75a9
We've been testing with Python 3.9 via Travis since this February, so
let's mark the project accordingly. Once a release which contains this
commit gets uploaded to PyPI, it will be propagated to the pip's web
interface.
Change-Id: I84635157565f1dbe9936231fa32ef3f6a0605e2f
The config file has the following properties:
* Includes only OpenROADM EDFA types (ILA / booster / preamp) and sets
allowed_for_design to true for ILAs.
* Sets ROADM restrictions to OpenROADM booster and preamp.
* Adds an OpenROADM transceiver type_variety with mode parameters
following the MSA spec.
* Sets other parameters (power_dbm, padding, add_drop_osnr, etc.)
according to OpenROADM MSA spec.
Using this config file together with auto-design should result in an
"OpenROADM compliant" network. Specifically, compliant fiber input
power levels for 50 GHz spacing are obtained by setting power_dbm = 2
and padding = 11. For other spacings than 50 GHz, power_dbm should be
changed accordingly.
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Change-Id: I3b182f1abcc22fd77d7ec073a6c87fad320957ae
...because it's ignored by the CI, and it's kind of up to the invoker to
specify which env they want. We have not relied upon the multiple
environment feature of tox.
Change-Id: Icf9a33dbb5e3df641bd85e3aa7482dfb85f13e5f
The error message was refering to method_nli which does not exist. The
correct parameter name is nli_method_name.
Change-Id: I24f24a2c5251317e1a80dda60aa27ec151628172
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
The __str__ method of the Fiber element class rounded the fiber length
to an integer but then formatted it with two decimal places, which
doesn't make sense. With this patch, two decimal places are kept.
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Change-Id: I03b886dff7ba624929ccc85b4d77d8d6a7cbcfb4
The Raman solver gave the wrong loss profile when the fiber length was
not a multiple of the simulation parameter space_resolution as,
in this case, the fiber termination position was not included within
the considered z position array and the output loss profile was
evaluated at the wrong position.
Additionally, the Raman solver failed when the simulation parameter
space_resolution was greater than the fiber length as the z position
array contained only one element.
With this version the fiber termination position is always included
in the z position array and is composed of multiple uniformly spaced
positions and the final position (in general, the latter is not
uniformly spaced).
Example:
* fiber_length = 5, space_resolution = 4 => old version z = [0, 4]
=> new version z = [0, 4, 5]
* fiber_length = 5, space_resolution = 6 => old version z = [0]
=> new version z = [0, 5]
Alternative:
z = linespace(0, fiber_length, int(ceil(fiber_length/space_resolution)))
PROS
* Solves the first issue
* Returns a uniformly spaced z position array (there is not a
straightforward advantage in the simulation)
CONS
* Does not solve the second issue
* It is slightly more involved
Change-Id: I8886c3563ac7305c49cb5915712777ef561c5d4f
Bug: https://github.com/Telecominfraproject/oopt-gnpy/discussions/400
without this change if a request was blocked on main path due to 'NO_FEASIBLE_BAUDRATE_WITH_SPACING'
and if the request was bidir, there was a propagation tentative on the reversed path
despite the fact that no baudrate was selected, which ended up with a program crash.
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: Ie4e578aab944e534d8b2d99fb02c4e28a242e717
The dashboards have changed in Gerrit 3.4 which got deployed to
GerritHub earlier today. Now there's no pagination and no is:mergeable
operator. Let's just link to a (paginated) list of all open changes,
that's probably better value for now.
Change-Id: I22ad68becfc33d3829bcd8aaccb5203e76faeded
ParametersError is a sub class of ConfigurationError so the
corresponding except clause should be placed before. Otherwise the
ConfigurationError will be matched first instead of the more specific
ParametersError.
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Change-Id: I67156dd7321101693fdf061d77937d4e75462593
It turns out that my text editor has been warning about "excessive code
complexity" via the python-language-server plugin that uses pycodestyle
underneath. As the test suite is configured to use `flake8` instead,
let's make sure that the results are consistent, and configure the code
complexity threshold for the CI linter run as well.
I'm not sure if this is usable when run incrementally, though (such as
in the CI). I *think* that `flake8 --diff` disregards warnings issued on
lines which have not been changed in the corresponding diff, while
mccabe reports its warnings for the line with the function signature --
and that one is not included in the output of `git diff -U0`. As a
result, I suspect that if a patch increases the code complexity of a
function over the threshold, our CI setup might not report that.
However, a non-diff run of the linters via `flake8` will now start
reporting C901 warnings. For those using `python-language-server` to
integrate with their IDEs and text editors, install `pyls-flake8` to
preserve the existing functionality.
Change-Id: If02e7f189514077aca3e865e1882a4a3fabb4dba
There are some (unmerged) patches which selectively mute some linter
warnings via the `# noqa: something` stanza. It makes sense to configure
the linter in such a way that it checks the format of that `something`
to make sure that the linter override is valid and selective.
Change-Id: I9eec3a1024d3df88f4f44d4df746ff514670f71f
make sure that their loss is not concatenated
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I63678dd5b72f7f6984101c4367320f3f981cb573
I believe a previous commit, 3ac08f5, changed the behaviour of span
loss calculation in an unintended way, since now it adds the loss of
consecutive fiber elements even when there is no fused element in
between. This means for example that no padding is added when the loss
of consecutive fibers is higher than the padding specified in the
equipment file even though inline amplifiers will be added between the
fibers in a later step. This patch changes the conditions in the next_
and prev_node_generator so that they stop when two consecutive fibers
are found.
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Change-Id: I42c9188c789a98a9b3d7e51d5aae15774d40dde7
Fix GitHub issue #217
Currently, if a user specifies an ILA node in an xls file, including
city name and coordinates, but does not specify type of amplifier,
etc., in the Eqpt sheet, the ILA node is not preserved when converting
to json. This patch proposes to include all ILA nodes to prevent loss
of information.
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Change-Id: Id169348cce185e4d33d5b80068270b36043e3353
* changes:
equipment: make sure all OpenROADM EDFAs have "openroadm" in their names
Introduce OpenROADM preamp and booster models
The "openroadm" NF model only applies to inline amps
docs: OpenROADM-ILA parameters in the JSON equipment library
docs: JSON: do not claim that the default NF implementation is "advanced_model"
docs: line wrapping
Currently, calculated new fiber coordinates, after splitting a fiber by
auto-design, are evenly distibuted. Since coordinates for added inline
edfas are the midpoint between neighboring nodes, this makes the edfas
"look" non-equidistant even if all spans have the same length. I think
it would make more sense to have the fiber coordinates represent the
midpoint of the fiber. That way, the edfa positions will look more
"natural". Here is an attempt to illustrate the difference for a link
with three fiber spans:
Before this patch:
r-----f--e--f--e--f-----r
After this patch:
r---f---e---f---e---f---r
r = roadm
e = edfa
f = fiber
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Change-Id: I6eafe3fcd4c718b0b995a046dbff0fd04bdc42d7
This could be (potentially) annoying to those users who rely on the
default equipment library. However, it brings at least some order into
the current state -- which was rather disorganized.
Suggested-by: Jonas Mårtensson <jonas.martensson@ri.se>
Change-Id: Ifc3ec5f9e0e2526b8621d905160fc82af6a469f2
The NF calculated by the preamp model is compliant with the MW-MW noise
mask in the OpenROADM MSA spec. The booster is noise-free, which is
modeled by setting the NF to zero (-inf in dB units). This is obviously
unphysical but it is the simplest way to model the total noise
contribution from a ROADM, including preamp and booster, that is
compliant with the the OpenROADM MSA.
This also introduces two new EDFA type varieties,
"openroadm_mw_mw_preamp" and "openroadm_mw_mw_booster" in the equipment
library. I would prefer to also change the names of the existing
"openroadm" type_def and "standard"/"low_noise" type_variety,
representing an OpenROADM inline-amplifier, for better consistency but
this probably needs to be discussed first.
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Change-Id: I7344ff53623f166649efb389c95c04ff92718e35
Signed-off-by: Jan Kundrát <jan.kundrat@telecominfraproject.com>
Co-authored-by: Jan Kundrát <jan.kundrat@telecominfraproject.com>
As Jonas pointed out in Ia2ee3fdde1c4eed0b7ef1de77153959230ba1c01, the
documentation was wrong and the default NF implementation was not the
advanced_model. Let's not describe what the backwards-compatible
behavior is (we do not want our users to rely on that), and instead just
say that "adavnced_model" activates, well, the advanced model.
Change-Id: Ie57340d491a6f73d696d77c07091f85952cb4a08
The numbered list was very hard to read; split that into one sentence
per line. Also do that everywhere else but in the tables (in RST I'm
afraid this would be super-painful).
Change-Id: Ib80c05b66cbc98af2d0dda612943f91d923425b0
Right now the project homepage on GitHub shows an red failure due to
[1]. While I agree that coverage reports are a useful metric, they are
most relevant when considering patches (or changes) on their own. I do
not think it makes any sense to show them on branches. When we merged
that commit, the reviewer had the info about the coverage change, and we
just do not have 100% coverage. Let's not pretend that that is a
blocker.
[1] 924c56850d
Change-Id: I652ada3357e521c9a3351faac2f9c2e8e4aa5773
See GitHub issue #391
There has been a change in the networkx drawing API, which means
'figure' is no longer an accepted keyword argument.
Change-Id: I8600e8cd5eb2cb378a529c7857f664c1ebed8337
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
The old code assumed that the Fused node only connects Fiber nodes. In a
sequence of Fused - Amplifier - Fused - Fiber, the Amplifier would be
included by a mistake. In addition, the code was not that easy to read,
and it just instantiated StopIteration without raising that (which would
be an error in a generator context). It was also rather strict, failing
if the iterator was requested for an "edge node" (a transponder), and
one of the exceptions was not actually an f-string.
Finally, the span_loss function would occasionally report wrong values
(for example in the provided test case, span_loss("fused7") would say 1
instead of 17).
Fix this by making sure that prev_node_generator() and
next_node_generator() never return anything but Fiber and Fused nodes,
which made it possible to simplify the span_loss() function. This should
now properly account for the accumulated losses of an arbitrary sequence
of Fiber and Fused elements.
I went over this a few times because set_egress_amplifier() calls
span_loss() on a *ROADM* node type. That does not make any sense, and
the code deals with this "properly" by returning a loss of 0 dB. It was
a bit confusing for me to see that it's actually OK to ask for a "span
loss" that's identified by a ROADM.
A side effect of this code is that Fused instances that are isolated
from the rest of the topology no longer raise an exception. I was
thinking about preserving this (because for GNPy, the only element with
no previous or no next nodes are the transceivers, but then Esther's
test topology contains an isolated `fused4` element. If we want to make
this strict, we can do that easily like this:
--- a/gnpy/core/network.py
+++ b/gnpy/core/network.py
@@ -162,10 +162,12 @@ _fiber_fused_types = (elements.Fused, elements.Fiber)
def prev_node_generator(network, node):
"""fused spans interest:
iterate over all predecessors while they are Fused or Fiber type"""
try:
prev_node = next(network.predecessors(node))
except StopIteration:
- return
+ if isinstance(node, elements.Transceiver):
+ return
+ raise NetworkTopologyError(f'Node {node.uid} is not properly connected, please check network topology')
if isinstance(prev_node, _fiber_fused_types) and isinstance(node, _fiber_fused_types):
yield prev_node
yield from prev_node_generator(network, prev_node)
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Co-authored-by: Jan Kundrát <jan.kundrat@telecominfraproject.com>
Change-Id: I41a65e89eef763f82e41e52bc325ed2d488cb601
It is added to the Excel input files documentation.
(We should also have a topology json input file documentation but it
currently does not exist.)
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Change-Id: I3184e36090388155e826d1b09bc9c6bf28d623d0
As pointed out in GitHub issue #390, the normal convention for the sign
of amplifier tilt is to define it with regard to wavelength, i.e.
negative tilt means lower gain for longer wavelengths (lower
frequencies). Currently GNPy uses the opposite convention, which this
patch proposes to change.
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Change-Id: I8f7829a3b0b0b710f7da013c525630a60b22a2b5
Currently the tilt_target defined by a user is applied over the band of
propagating channels. This means for example that if only two channels
are propagated, the difference in gain between the two channels will be
equal to the tilt_target, independently of how close the two channels
are in frequency. I think it makes more sense to always define the
tilt_target over the full operational bandwidth of the amplifier.
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Change-Id: I4f29de2edc4d0de239b34e0d8d678d964b6a0af3
As identified in GitHub issue #390, the dgt values (as well as gain and
nf ripple values) in example config json files are listed in order of
increasing wavelength (decreasing frequency) while the code assumes
values listed in the opposite order. This patch reverses the order of
values in affected files so that they are consistent with existing use
in the code.
Also, the f_min value in the Juniper-BoosterHG.json file is updated to
match measurement data so that interpolation is performed correctly.
Change-Id: I97a9d2f9be81380d1658bee5fa1ef4def3e1c537
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Following the change of the corresponding xls file in 60b9256 we should
change also this json file for consistency and to avoid unnecessary
confusion.
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Change-Id: Iab12002544ad6b8489d8dfa0511fdce762cc1d7a
This is an old pull request rebased and restricted to only raising warning.
The initial work also limited gain, which is finally not a desired behaviour:
an advanced user might want to have this high gain.
the only impact on test is that it raises warnings on almost all amplifiers
on the mesh_topology_exampleV2.xls: indeed all of them are set to low_gain
but without gain specified and the result of autodesign results in higher gains
than supported by this amplifier variety.
This may be confusing for users to see these warnings on an example from gnpy
so I will push a new commit changing the amp types to avoid this.
The alternative would be to push the warnings into the logger, so they
remain invisible, but I think that the example change makes more sense.
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: Idf0c67137b5b466b07ddc7817f53a82f92a21a5b
Relative links within the source tree work, but they were not being
turned into nice usable hyperlink that go back to GitHub under the
generated documentation.
Reported-by: Melin, Stefan M. <Stefan.Melin@teliacompany.com>
Change-Id: I137ad95fa75a6ee5e1b03a252782e6357d36a3af
In the generated SVG files, there was a '%3' shown as a mouseover
tooltip on mouse hover. Apparently that's what ended up in the <title>
of the whole generated SVG document.
This turned out to be an internal thingy in graphviz/dot. In Sphinx
there's already some support for catching element IDs with this '%3'
madness, but apparently titles are not handled like that.
Solve this simply by providing a title for the whole `graph {}` stanza
in the embedded dot graphs.
Reported-by: Melin, Stefan M. <Stefan.Melin@teliacompany.com>
Bug: https://gitlab.com/graphviz/graphviz/-/issues/1327
See-also: https://github.com/sphinx-doc/sphinx/commit/8494638e45
Change-Id: Ia9f39d13748cdffe74f2cb5032f92c77babb20d8
I wanted to make sure that that funny SVG rendering is not a problem of
an outdated Sphinx. It is not, see the next commit. However, there's no
need to stay on a release from 2017, there's 3.5.0 already.
Change-Id: I181cc5d96eae3fadbf93711063e8f969a2f451cb
Previous implementation selected last candidate in case both routing
and disjunction constraints could not be applied. The new implementation
elaborates an alternate list where each feasible paths satisfyng
disjunction constraint but not route constraint is recorded. The algorithm
then preferably selects a feasible path that satisfies all constraints and
if none is found and route constraint is LOOSE, the first set of paths
that satisfy disjunction is selected (instead of the last one).
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: Iba44397d105006a98539494d821cc83dc3e3bbd9
...because that one obviously doesn't read bindep.txt, but it has its
own way of installing these dependencies.
Change-Id: I6c2a70095c57686228ae697a06bb82b8c6d47459
Patch 503833 (Fix calculation of gain for first Edfa after Roadm)
introduced a bug when it was rebased on top of the per degree power
feature since per_degree_pch_out_db used for propagation was actually
updated based on calculated prev_dp value.
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Change-Id: I39e8f5945d5035b99c70ef577011bba79bb89a72
This allows users to limit the choice of type_variety by auto-design
for an EDFA node by setting a "variety_list" attribute in the input
topology json file. One use-case is switchable gain EDFAs where the
two gain ranges can be modeled by two separate type varieties in the
equipment library. A user may know that such an EDFA will be used in
a node but not which gain range is optimal. The choice of gain range
can then be left to auto-design while not allowing any other
type_variety by specifying the node e.g. like this in the topology:
{
"uid": "Edfa1",
"type": "Edfa",
"variety_list": ["foo_gain_range_1", "foo_gain_range_2"],
...
}
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Change-Id: Ia69ef78f885e3a61310530b6b80da64e43758211
The sanity_check function in convert.py removes duplicate links in the
input XLS file. However, it doesn't remove them from the links_by_city
dict. This has two consequences. Firstly, the output json will still
have duplicate connections. Since networkx.DiGraph.add_edge will only
add one edge anyway, this has no major impact. Secondly, sanity_check
will think that a degree-2 ILA node with duplicate links is higher
degree and change it to a ROADM node.
With this patch, duplicate links are removed also from links_by_city.
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Change-Id: I4be9ab225bc89277aec467a5bd60216b4aa31993
I think it's "healthy" to sync up the list of minimal versions of our
dependencies with what the CI is actually checking, at least every now
and then. We're getting some variance via the list of different Python
interpreters, but still -- let's make sure that our dependencies match
what we're testing.
The only interesting case is scipy where the 1.6 release started
requiring Python 3.7. Let's stick with 1.5.x, which is the last version
supported on Python 3.6.
Change-Id: I4aa0a89e7c615f2095a951ff522a4838ef50178e
On Travis, builds with Python 3.7 started failing recently:
```
ERROR: pandas 1.2.0 has requirement numpy>=1.16.5, but you'll have numpy 1.16.4 which is incompatible.
ERROR: scipy 1.6.0 has requirement numpy>=1.16.5, but you'll have numpy 1.16.4 which is incompatible.
```
Apparently the version of numpy that gets used when under Travis is
rather different among their Python versions, and we get:
- numpy-1.19.4 in their Python 3.8.6 env,
- numpy-1.19.0 on 3.6.7,
- numpy-1.16.4 on 3.7.1
That's a bit insane to my liking, perhaps they're preloading popular
libs such as numpy into their images for speed ups? For comparison, on
Zuul CI we have this:
- numpy-1.19.4 with Python 3.8.6 on Fedora 32,
- numpy-1.19.4 with Python 3.6.8 on CentOS 8
Let's start requiring numpy 1.19.4 everywhere. This is the cost we're
paying for https://github.com/Telecominfraproject/oopt-gnpy/pull/268 .
Change-Id: I6f1167096cfadc415cf456ad09ff0a08b535fc08
Currently when an Edfa is inserted by auto-design after a Roadm (i.e.
booster) it gets the same city attribute as the Roadm while an Edfa
inserted before a Roadm (preamp) gets the city attribute from the
preceding fiber. This is illogical and confusing. Also both the Edfa
preamp and booster get coordinates different from the Roadm (halfway
between the Roadm and the neighbor node). Since in practice the preamp
and booster are always colocated with the Roadm I think it makes more
sense to give them the same coordinates.
Also change how uid is assigned to an Edfa connected to a Roadm so that
it indicates whether it is a booster or a preamp.
Change-Id: I98718fe1e2914b5628e7cfd23fc28fb5708a8889
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
When loading the equipment file in json_io.py we should raise an error
if an Edfa type_variety specifies a NF type_def that is not
implemented. This should also allow to remove the assert statement in
the _nf method in the Edfa class.
Change-Id: Ida0bb19829c0ee54ecbe3e2f74ea7c22eb24f6a2
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
I think it's better to raise an exception instead like we do for other
errors.
Change-Id: If6dd795bd76471b2534d873772e991d9ae0a4271
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Currently, auto-design does not work for an OMS starting from a Trx
that is not connected through a Roadm if the topology also contains one
or more Roadms. I don't see a good reason not to support this case,
since a Trx not connected through a Roadm can make sense, e.g. for a
degree-1 node. This is a proposal to remove the restriction.
Change-Id: I14686521a838b30249126b9bd403fa26c848875a
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Currently, the RamanFiber class does not implement its own to_json
method but inherits it from the parent Fiber class. This means that
operational parameters (temperature and raman_pumps) are not included
(and therefore not picked up by the network_to_json method in
json_io.py). So if a user saves the topology, e.g. using the
--save-network option, and later uses that saved topology as input,
the result will be wrong.
This patch includes the operational parameters in to_json.
Change-Id: I07c09a4d122858ff412373623d8c0a087a3e11ec
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Currently, if an input topology contains a loop in an OMS, the
set_egress_amplifier method in network.py will go into an infinite
loop. With this patch, such a loop is detected and an error is raised.
Change-Id: Id7cd0cc6d7eaff3af1d9e0309b5c2eb90aeb7454
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
In network.py we are already checking that fibers are properly
connected. Let's check Edfas and other node types as well.
Change-Id: I224b9046729197fef3eb172e9631969a2da13ab5
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
The equipment library has, so far, used completely different namespaces
for `Fiber` and `RamanFiber` definitions. It was possible to define a
"SSMF" fiber whose properties, such as CD or PMD, would differ when used
as a Fiber vs. the RamanFiber object in the networking topology. That is
likely a bug of the equipment library, so this patch makes sure that a
configuration like that cannot be used.
I came across this when working on the YANG support where both fiber
types are defined in a common namespace, and the difference between them
is determined by lack or presence of a sub-container with the Raman
properties.
Change-Id: I8e86bed80eb1794b8abd4e1ecd96398d395f81f2
The patch correction changing the params
from
per_degree_params: { to_node: xx , target_pch_out_db: yy}
to
per_degree_pch_out_db: {xx: yy}
had not been updated on convert.py for reading the excel input.
the commit also fixes the automatic tests with the correct version
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I17a5cfad18e1b570a7aaa218e932368fa80f2d37
A recent patch introduced the possibility to define an Edfa in the
topology file without specifying its type_variety:
https://review.gerrithub.io/c/Telecominfraproject/oopt-gnpy/+/488967
But with the current implementation, if a user specifies a type_variety
that is missing from the equipment configuration file (e.g. because of
a spelling mistake) this is silently ignored and the type_variety is
instead selected by auto design. I think this is not desired since it
can lead to confusing results. This patch proposes to raise an error
when the specified type_variety is missing while still allowing the user
to not specify type_variety or set type_variety = '' for selection by
auto design.
A recently introduced test actually does exactly this, i.e. it defines
Edfas with type_variety = 'std_high_gain' even though this type variety
does not exist in the equipment config file used by the test. Therefore
this patch also modifies the topology file used by that test.
Change-Id: I7d2a1aa6d633b62d51a99b07e8270cafcbad505f
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
This makes it possible to render at least something on tiny topologies
now that YANG doesn't support city labels.
Change-Id: I1431b557b2eecd34bf24557fdee0da0f2c2c0487
See GitHub issue #368
The out_voa attenuation of the previous Edfa is currently not taken
into account when calculating power target for an Edfa in gain mode.
This makes the calculated gain target (in case of autodesign) for
the following Edfa in the chain incorrect and also impacts automatic
amplifier selection.
Change-Id: Idc473762ccf7b021a0885c7ce20de1abb66eb075
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
See issue reported in #360
In autodesign, currently the calculation of gain for the first Edfa
after a Roadm is incorrect when the reference channel power is
different from 0 dBm. The bug is somewhat hidden by the fact that the
gain is anyway updated during propagation in power mode, taking the
reference channel power into account. But the gain reported by the
to_json function of Edfa elements before propagation will be wrong.
And more seriously, the incorrect gain will impact the Edfa selection
in autodesign.
Change-Id: I004de102832c3a0786435e21e71b0444d8901604
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Check that egress power of roadm is equal to target power if input power
is greater than target power else, that it is equal to input power.
Use a simple two hops A-B-C topology for the test where the prev_node
in ROADM B is either an amplifier or a fused. If it is a fused, the target
power can not be met.
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I3388f060a4f364055d58c8ca7c2b59143f784fa8
- add a test on the json conversion in case of a ROADM sheet
- test the per per_degree_pch_out_db is correctly created with specified
values or default.
- also tests that the convert correctly creates the correct equipment
only if the entry exists in eqpt sheet.
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: Ic006d9c741404b185d15678953d2801cd17bab97
This part only targets conversion from an xls input topology file.
In order to define per degree power, the convert function needs to know
the booster final name.
However before this change, the booster name may not be known if there
is no defined amplifier in eqpt sheet at this stage.
In order to solve this ambiguity, the final name are defined in the convert
function provided that the direction is defined in eqpt sheet and
even if the amp type is not defined.
Then the per degrre target power is defined in a new roadm sheet using
the same direction naming as for Eqpt sheet.
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I8f279aa880aa0a8ceb60e48e43bddb0f6ff06147
- add the per degree info using the EXACT next node uid as identifier
of the degree when a node is a roadm
- add the degree identifier on the propagate and on the call functions
- use the per degree target_pch_out_db defined in json entry for the
target power in network build
- verifies existence of the per degree power target in order to support
partial per degree target power definition
- correct test data files for expected auto design results that now
should include the per degree information, even if it is the same
for all degree.
- in order to enable per degree power definition on direction where
booster is not defined, enable the declaration of edfas in json without
specifying type variety
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I5004cbb250ca5fd6b6498ac9d4b9c4f28a65efee
In the previous implementation, when a constraint was added on top of
the disjunction, there could be an infinite loop because the test was
not correctly performed on the request_id but on a request class.
Moreover, there the loop was not needed since the first feasible
candidate is selected if it exist.
This patch removes the loop and adds some comments to explain the code.
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: Icdbee9032f28214b3e03cb62d55ea353477d94bf
Since 30234f913c, the code just added the
"system margins" to each transponder's minimal required OSNR. That's
simple and straightforward, but I think that mutating "equipment
library" in response to a "global simulation parameter" is not really
the right way to go.
Make this explicit; always check the resulting OSNR against the
transponder's minimum plus the margin.
I got into this when checking the fixups that are performed within the
JSON loader. I don't think that the JSON loader is an appropriate place
for this.
Change-Id: Ic8f8385cbbb29dc0d769462f17caad47c2b36940
- do not talk about just "Nodes" and "Links" when also checking "Eqpt"
- don't check for non-existing "Nodes" from "Links" when that's already
done elsewhere (and improve that check's error message)
- when checking "Eqpt", verify not just "from_city", but also "to_city"
Change-Id: I2e926049fa5e3c4dcb08cc29f18970a3b3b077d8
This was identified during today's coders call where Andrea asked what
the best place for documentation of `sim_params.json` is. Let's split
docs about tangible equipment from those of global "simulation options".
Of course these options are still done in `eqpt_config.json`, which
might get super-confusing to the user -- so please make sure that this
is correctly explained when adding docs for `sim_params.json` in future.
Change-Id: If43894e8f562ca8a768b0efb6cc6c1afeb4aa514
I've already updated the wiki pages, so the onboarding guide is
"correct", but a bit verbose. Let's just try to make the contributor
experience streamlined a wee bit.
Let's also use a GitHub PR template so that people are aware of Gerrit.
Change-Id: I44fb095f14396c7ba49494c32b6215f6a29ade2b
The current implementation based on scipy interp1d fails when
predecessor and successor of the fiber to be split have the same
longitude. In this case the new latitudes become NaN. This patch
fixes the bug.
Change-Id: I7c5dc4d410630a6b4b773d36cc192db8271a4346
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Since build_network can raise NetworkTopologyError and
ConfigurationError we should handle these in cli_examples instead of
crashing.
Change-Id: I4b84831c74be7f1c88253c938f3f67b2d204630e
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Other functions used be build_network raises NetworkTopologyError when
a fiber is not properly connected but this handling was missing from
add_connector_loss.
Change-Id: Id08cd4a9bad15f755d364a31ff3d38993d034447
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
The first build was much faster, there was about 50s in the actual
pytest invocation time. Overall, the total time is about a minute
quicker, which is nice. I cannot qualify whether the improvement is due
to a 1g-1c -> 2g-2c VM flavor underneath, or if it's that newer Python
*and* updated compile options in Fedora -- but it's a nice improvement.
The downside is twice the cost of the VM hour.
Depends-on: https://review.gerrithub.io/c/Telecominfraproject/oopt-zuul-jobs/+/497370
See-also: https://fedoraproject.org/wiki/Changes/PythonNoSemanticInterpositionSpeedup
Change-Id: I6f5db61e9481170515b2f7ff4f3358fae5daa68e
I kept wondering why installations on Python 3.8+ kept failing in the
CI, and I assumed that it was because the Pandas project somehow got
their homework wrong and did not provide a "wheel", which is a Python
thingy for prebuilt binaries. That's however not the case, and the
reason was simply that our Pandas version pin was too low, predating the
time when Python 3.8 was released.
Solve this by updating the Pandas requirement to the most recent one,
and now there's no need to mess with anything. Yay!
Thanks-to: https://github.com/mars-project/mars/pull/1332
Change-Id: Iceb31ae16aa911ebef67a938a3d2a524faad164f
Thanks to Stefan for reporting this.
Reported-by: Melin, Stefan M. <Stefan.Melin@teliacompany.com>
Change-Id: I9ab3aa5f829ffe3ef722df2d46f1393f748a52dc
sudo is a no-op these days, and let's put in that default linux OS
thingy to silence an info message, too.
Change-Id: I95d5b842932345025adbe20bd8775fb6dd83030e
There are several differences between `python setup.py develop` and `pip
install --editable .` ; one which became relevant a few days ago is the
fact that `python setup.py develop` is apparently happy to pull in
pre-releases of our dependencies -- perhaps due to the fact that this
package, when installed from git, is also considered a pre-release. This
has led to CI failures in Travis, and for some reason just on Python
3.7, not on Python 3.6.
This is of course rather ugly, and there's no need to start pulling in
pre-releases of various pieces of software that we're using, anyway. Fix
this by asking our users to use PIP, and adjusting the CI accordingly.
Zuul CI uses tox which is documented to call PIP behind the scenes, so
there's no change in there.
Fixes: https://travis-ci.com/github/Telecominfraproject/oopt-gnpy/jobs/353680894
Change-Id: I254066b8dc345e23c061a69d55546d48bac6761d
There are two propagation functions in request.py, propagate and
propagate2. The propagate2 function saves and returns spectral infos
from before and after every element of the path. In most cases only the
final spectral info after propagation is needed (there is currently
nothing in the code using anything more). On the other hand, the
propagate function just returns the path which is unnecessary since that
is modified in place. This patch proposes to instead return the final
spectral info from the propagate function.
Since propagate2 is now redundant, it can be removed.
Change-Id: I3a0f7310a7d5f9c93dc5f257e051c7d45e20c6fe
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
The parameter add_drop_osnr is specified in the Roadm section of
eqpt_config.json and represents noise added by amplifiers within the
add/drop block of ROADMs. Currently this noise is added to the signal
whether the propagation path includes any ROADMs or not, which does not
make sense to me. This patch proposes to only add the add_drop_osnr when
a path actually includes ROADMs.
See GitHub issue #274.
Change-Id: I58961772c049578eff8879dfb2e53265866d12c4
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
(Migrated from GitHub PR #311)
Currently the output of transmission_main_example shows the first
transceiver having ONSR = +inf even when a tx_osnr has been specified,
which is confusing.
This patch proposes to update the SNR of the first transceiver with
tx_osnr.
Change-Id: Idab7c92c2f5a12cc92ce5c1c551e5710f30e6a02
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Zenodo offers two kinds of DOIs for GitHub projects:
- a per-release one, always assigned automatically upon tagging a new
release in GitHub,
- a stable one which [always resolves to the latest version at time of
access](https://help.zenodo.org/#versioning).
I think there's value in people citing us as "GNPy", not "GNPy 2.2", for
example, so let's make sure we include this magic-always-newest-but-stable
DOI for this software.
Change-Id: Ia57a94882c74d605e21f55c87b0a74b1d734b5ed
Since about f9e0d18 and 94a8f35, we've changed the way how the equipment
config (and also the network topology) is passed around. Update the
README to reflect this.
Change-Id: I338b790fd4d54914c49e5e0aac3f44f2bc9d00ee
We talked about this during the coders call on 2020-06-02. When this
project started, it was decided to keep the `master` branch essentially
frozen between releases, and concentrate development into the `develop`
branch. Since that time, we've got a decent CI coverage and end-to-end
tests which should guard us against regressions and inaccurate
simulation results. It also seems that our users have a preference to
use tagged releases anyway, so we can get by by deprecating the
`develop` branch.
As agreed during the conf call, from this release on we'll be merging
approved changes directly into the `master` branch, and the `develop`
branch will be retired. We have measures in place that ought to limit
the risk of regression within `master` to an acceptable level.
Change-Id: I0048ba8e36810237667e6930380a9c8570090a26
Originally I was hoping that this is possible via the parent job
collection (oopt-zuul-jobs), but that's not the case, unfortunately, and
I have to do this in this project.
I created the token at PyPI's own web UI for my account, and saved the
secret to a file. Then I executed Zuul's helper script:
$ ~/work/prog/openstack/zuul/zuul/tools/encrypt_secret.py \
--infile secret-pypi --tenant TelecomInfraProject \
https://zuul.vexxhost.dev/ Telecominfraproject/oopt-gnpy
Change-Id: I05ab853ae26a449212e832e0f7e261c9ed71e364
This looks like something that's been "always" part of the Excel guide.
I think it is better placed in the README. After the releae we migth
want to improve the docs even more, but hey, that's something which
should be done after some discussion, not via these commits that I'm
going to self-approve shortly.
Change-Id: Icd73f4bb3a43f1a684ec7a364e4ebcc9b8e6af88
The PowerShellSessionLexer within pygments has troubles parsing the
example as something valid, so let's revert to a generic one.
Change-Id: I188e1d7bf2f7229ad15c1f0443584344fd11bf84
Turns out that we're already running Sphinx with options that are strict
enough to perform all sorts of checks. The `rstcheck` standalone tool is
too strict, it warns about legitimate Sphinx constructs (hence the
ignore list), and also happens to issue false warnings. Let's rely on
Sphinx for stuff below docs/, but still invoke rstcheck for the
top-level README (and anything that's not included in the Sphinx docs,
really, which is right now the README, AUTHORS, and a JSON-specific doc
that I have yet to convert).
Bug: https://github.com/myint/rstcheck/issues/19
Change-Id: Ib787d11e7d21452570618288acdf15b3e85270a7
This is effectively a revert of commit 771af49 which added a
commented-out feature for printing out carrier info of the first hop.
On one hand, I'm reluctant to remove this, because apparently this was
not added by an accident, the PR #193 explicitly speaks about a
suggestion from Dave Boertjes for this feature -- and the git history
with merges looks like this one was actually pulled in as a single
commit. On the other hand, it is apparently not used anywhere, and all
of the required information is already available in some other manner --
for example, one can easily follow the path and add these prints to the
propagation, or just walk the path manually.
Digging further, I removed some of similar print() statements in
acafc78, and then restored some commented-out print()s via ec9eb8d (also
see the discussion in #299), which were then removed by Esther in
8107dde. So my TL;DR version is that this is dead code, and that
apparently the *real* use case is having total insight into the spectrum
info along the path (e.g., #246). That should, IMHO, be handled by
proper processing of the resulting data in a nice UI.
Change-Id: I366d33f98e230f4cb60a6d4b791707f7604f8d65
The actual conversion formula includes the minus (-), not the absolute
value. We never noticed it as GNPy simulates only modern networks
based on uncompensated transmission which have not DCUs. In this case,
the sign of beta2 along a path is the same for all the spans and,
in this case, the actual amount of NLI does not change.
Change-Id: I60a61d00c578a1a0436231a2bda8e3b6256fc8b3
* changes:
Enable saving the network as converted from XLS
Save either to JSON or to CSV, not to both
CLI: Allow Raman in path_requests_run
CLI: Unify handling of the network topology
Remove unused variables
CLI: show default values in --help
Unify handling of the --equipment option in examples
CLI: specify shared code options just once
Tweak the --help output
Remove unused statements
XLS -> JSON conversion: add a nice program for this
transmission_main_example: Do not write out a CSV file
tests: don't clutter up the source dir with generated CSVs
use load_json instead of open coding
tests: Do not produce JSON files in the source tree
Split JSON export from service XLS reading
tests: Do not create JSON files in the source tree
Do not always write out JSON data when reading XLS files
Remove incomplete support for "fuzzy name matching"
distribute example data along GNPy
Do not create *_auto_design.json by default
tests: remove something which looks like a path, but is not a valid path
tests: show that the examples still work when directly invoked
examples: add some additional descriptions help context
Distribute our examples via setuptools
tests: call our example entry points via functions
examples: prepare for overriding sys.args
examples: move path_requests_run to gnpy.tools
examples: move transmission_main_example into gnpy.tools
examples: use ansi_escapes
examples: manual coding style tweaks
examples: autopep8 -aaaaaaaaaa
examples: autopep8
This is a feature that was requested by Esther due to their workflows at
Orange. There's also a standalone converter avaialable as
`gnpy-convert-xls`.
Change-Id: I1a483d168db0744fbf115e05e679e13b57d79398
There's no need to limit this to just the transmission_main_example, so
let's unify this handling.
Change-Id: I585f407c7f80da12fd33baf7261c35c736d78df2
I think this is a little bit cleaner that duplicating the info about the
default for some of these options.
Change-Id: If218a26ede3e71628f4839b4e505c4f4aa217699
Let's use the --option format instead of positional arguments; that way
it's more obvious that it can be omitted. Note that this constitutes a
change of behavior for the path_requests_run example.
Change-Id: Ic6653cf419e1a8573c3585190a88fc51500f549d
Try to indicate whether an option takes just JSON, or a JSON or an XLS
file. Also add some extra descriptions.
Change-Id: Ifb81d46f6ac659da79b08201a414822e9c318a1e
Esther mentioned that it is useful for her to be able to convert from
XLS files to JSON files. Let's add a full blown script for this.
I've also taken the liberty to refactor the code a bit so that there's
no default value, and to modernize everything with pathlib a little bit.
Change-Id: I80e50fc1280003910242ce1ff9fc9ae66e6d275b
We talked about this earlier today on a call, and agreed with Esther and
Alessio that this is probably a relict from the past. The file does not
appear to contain much useful information, anyway, so let's try to
remove it and wait if someone complains.
Change-Id: I215eeb37498b28b15ece2300f4bbdd184ac52f4a
There's no reason for this, in fact, the code got easier to read when
that detour to disk gets removed.
Change-Id: I45db215898da962e625a7fea6eda57744e21ff8a
This is something which got added in bc9eee32, but it never got
finalized to have a user-visible effect. To the best of my knowledge, it
only created a file which was never used.
I removed code which created that file in 0d542f22, so let's clean up
the rest.
I think this should also restore functionality of running convert.py in
a standalone mode. Looking at the ArgParser, the invocation never
considered the names_matching parameter.
Change-Id: Id0f4aa1db2d22233f74fb273176168a16ace4072
I would like to create a package for distribution to PIP, and this seems
like the path of least resistance.
This is, apparently, the way for shippign arbitrary data with Python
[1]. I've at least tried to make it user-firendly via adding a simple
utility which just prints out whatever that data path is.
[1] https://python-packaging.readthedocs.io/en/latest/non-code-files.html
Change-Id: I220ecad84b1d57d01e3f98f15befc700bd97c0b8
It's a bad habit to write files into the source code repository. It will
also become impossible if gnpy is installed into a systemwide, possible
read-only location.
The old behavior can be reactivated by using an extra option to tell
GNPy where to put the generated file.
Change-Id: I9ad43890ca5886f516885de5938a4778870a06c5
As I'm moving the top-level directory `examples/` to another place, I
wanted to clear the source of any mentions of examples which are not
actually valid paths.
Change-Id: If6cce20feacfbbb79549e865d06aa00fd2dcd08d
Since Ic4a124a5cbe2bd24c56e4565d27d313fe4da703f, there was no automated
test which would check if the generated examples *really* work. When I
was playing with this, I managed to break it at least once (especially
when working on overriding sys.args, i.e.,
I53833a5513abae0abd57065a49c0f357890e0820).
This now requires an equivalent of `pip install` before the tests can be
run.
Change-Id: I595a3efe29b3ee13800c5cb71f28a5f370988617
The main reason for doing this is becasue of the next commit which
re-adds testing of the generated wrappers.
Change-Id: I7137c6cf7a5b414fc708a15b125eaf88e996366c
This patch proposes a new implementation of the compute_constrained_path function based on the same method as the newly proposed compute_k_constrained_paths function, i.e. using shortest_simple_paths instead of all_simple_paths. This method is more efficient and avoids having to set a cutoff parameter. The new implementation should be identical to the old one from an external perspective, except that it finds a path with include node constraints in more cases.
Change-Id: Ia93b61c0af27076ed5088013bc87787a2920b629
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
I would like to avoid that extra fork to a child Python interpreter (it
looks like something that can be easily avoided). It's something that's
possible now that the code ships just some trivial wrappers (which are,
in turn, needed for setuptools' `console_scripts`).
This cannot use the `capsysbinary` fixture for wrapping of stdout/stderr
due to something in pytest which already got fixed, but has not been
released yet (May 2020). Let's use `capfdbinary` which works fine.
Change-Id: Ic4a124a5cbe2bd24c56e4565d27d313fe4da703f
See-also: https://github.com/pytest-dev/pytest/pull/6926
...which will be done in the next commit. One has to be careful with
sys.argv here because it uses different indexing than when passing args
explicitly.
Change-Id: I53833a5513abae0abd57065a49c0f357890e0820
This converts our first free-standing example entry point into a
function. It will become very handy when we start distributing these
entry points via setuptools.
Change-Id: Icd2e4658337f93cd0b0301978e2dc640de0cc72b
We have declared that we're supporting Python 3.6 as the minimal
required version of Python. Let's enforce this via testing. Let's also
do it via a long-term supported distro (CentOS8 in this case) so that we
can have someone else maintain stuff for us; it's easier to rely on
these prebuilt packages instead of downloading Python from upstream all
the time.
Also, Python 3.7 builds are currently broken in the CI because of some
breakage, either in the upstream zuul-jobs repo, or in Vexxhost's VM
images. So, now that we have Python 3.6 VMs available, use this to
restore CI functionality. That part can be reverted in future when
Debian Buster-based builds are working again.
I've also tried to use Python 3.8 on latest Fedora (version 32). There
were a couple of gotchas, including /tmp on tmpfs with not enough space
for building all required packages. Also, there's another issue with
building Pandas from scratch, so let's defer using Python 3.8 until
later. It's something that I will definitely look into, though, because
of significant speed improvements in that distro.
Change-Id: Ic19bf58875ba6d6afaee77f5c9b467261ec686d0
Depends-on: https://review.gerrithub.io/c/Telecominfraproject/oopt-zuul-jobs/+/494597
As a bonus, in the Python shell, `help(gnpy)`, `help(gnpy.core)`, etc,
now produce at least some useful information.
Change-Id: I76ade6f2456fcebd3c0a147374815dd245dc4b10
This also moves SimParams handling to a single place. As a result,
path_requests_run has just become Raman-aware (to the minimal possible
extent, OK).
Change-Id: I4e31af5c67335963ddab567d304f48a899cd569e
We agreed that `gnpy.core` should only contain stuff for propagating
wavelengths. Conceptually, JSON parsing and even instantiating these
network elements from data obtained through JSON is *not* something that
is on the same level -- and this will become more important when we move
into YANG format in future.
Also, instead of former `gnpy.core.equipment.common`, use
`gnpy.tools.json_io._JsonThing`. It is not really an awesome name :),
but I think it sucks less than a thing called "common" which would be no
really longer any "common" in that new file.
Change-Id: Ifd85ea4423d418c14c8fae3d5054c5cb5638d283
Similarly to I7ab9f64d7ac2042e8a16d031ba5562a6eb412471, it's better to
be explicit about what's going on. It makes it easier to reason about
the code.
Change-Id: Ic7f4a590567f1f5903222be8dae53521424d8f77
This will be needed by one of the follow-up commits which move JSON
manipulation into a single file. We have to distinguish between "Roadm"
the JSON representation and "Roadm" the network element which propagates
spectrum.
Change-Id: I6888842c57c3a57849fabe75d0ff6f5bbfab426a
I envision equipment.py as something which deals exclusively with the
traditional GNPy's JSON-formatted data, so make sure we do not include
any computation in that file.
Change-Id: I8473cccd84243147181a7195ba39fc6c9db3c42f
I think that equipment.py should be only concerned with constructing
network elements from JSON data.
Change-Id: I777835b02a23b76fb1d40c3a966e72b606e9c205
I think that being explicit about what gets instantiated is much easier
to read. For one, it enables "find usages of this thing" in IDEs.
The original code was also insecure because it would happily invoke any
function available in the global context with user-supplied data(!).
Change-Id: I7ab9f64d7ac2042e8a16d031ba5562a6eb412471
We have some docs on how to install this, and we rely on the
requirements.txt file for specifying what packages are required. There's
no point in arbitrarily handling the `xlrd` package in a different
manner.
Change-Id: I2355440ada7fd0cc4868aeff5a8956729655c96b
This has been the only place where content from gnyp.tools.service_sheet
was being used outside of tests and examples. It looks like something
which is actually *not* used anywhere (the ResultElement instances are
only ever apended to a list which gets used as-is, so we do not need any
custom comparisons or hashing).
Change-Id: Ib6ddcf55779218d602620e77973d88ad62d0ec7b
The TL;DR behind this patch is that it's better to have a utility
conversion function instead of having multiplier LUT and open code which
implements the conversion.
The FiberParams handling looked fishy -- apparently, it was keeping the
multiplier around, but it was unconditionally setting the units to
meters, anyway. Given that the units were not being preserved anyway
(everything got converted to meters), and that the multipler was not
used anywhere, let's refactor the code to just convert to meters using
our new utility function, and remove the unused argument.
Change-Id: Id886d409a4046f980eed569265baefd97db841bd
Apparently it's sometimes not obvious where the input data come from
(see next commit), so let's show the data which caused this excpetion to
the user.
Change-Id: Id333903a0549c4ef5dc37c2f6ff340bd357279ea
I think that gnpy/core/equipment.py should contain only stuff which
prepares the equipment_config, not anything "lower level" that is reused
from other places.
Change-Id: I0cd593fd3e5558178ddd0ad8fff5c596e022894a
We're saying that Python 3.6 is the minimal version that we support, so
let's make sure there's CI coverage for that.
I also tried enabling Python 3.8, but somehow the build of Pandas
failed. I don't feel like debugging a Pandas build failure today, so
let's postpone this thing until later. Just having 3.6 is a net
improvement, and we can play with even newer Python later -- and perhaps
on a newer distro, anyway.
Change-Id: I28a8c282225b7070ed3dddba56cccc8def313a77
Just ask pytest-gcov to not generate any test report. The coverage data
are still generated and will be used in later steps of the build
pipeline.
Change-Id: Ic5bb6a48e2abf6ee52e1c2650727ce4170611171
Image source: I took the existing banner, cropped it and resized to
200px width as per the theme docs.
Change-Id: Ic79b6164d557298746fe878de31ee0a9b0d93923
That class is an internal implementation detail, so mark it with a
leading underscore as per Python idioms.
Also, tweak the docs so that there's less duplicate information and
more cross-references.
Change-Id: Ieb1c8034ab5b442032396d7c4bbd0a697c7eb492
This mainly reverts some auto-fix-ups done in
I2f0fca5aa1314f9bb546a3e6dc712a42580cd562 which do not make that much
sense. By reverting them by hand, it's (hopefully) easy to see what is
just a tool work and what is an opinionated preference.
Change-Id: I6cb479e34b552fadc85c41b4b06b24e60c87b4a3
It always seemed like a strange restriction to not allow this.
Change-Id: Ice3ed3ecc08f42b6ef8b74d4a6bc3b1794ff078a
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Since Ia8c8d734c7045062ce123360f4a1432490384118, the lists no longer
have to have the same length.
Change-Id: I43ff10defa414cde0d6ff26a4d238b8680e39899
Currently interpolation of nf_ripple or gain_ripple fails if the length
of the input list is different from the dgt input list since the amplier
frequencies used for interpolation are calculated based on the length of
the dgt input list. There seems to be no good reason for this restriction
so I propose to calculate amplifier frequencies separately for the
different inputs. This also allows to specify a flat ripple with just one
number and a flat dgt with two numbers.
Change-Id: Ia8c8d734c7045062ce123360f4a1432490384118
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Also make sure that all modules are covered. It seems that there's no
automatic way for doing this, aargh. On the other hand, there's
apparently no need to repeat all the Sphinx markup blurb, and even
sectioning works nicely (read, "as I expect it to work") now :). I think
that it's still necessary to keep these "intermediate files" that only
trigger package-level and module-level autodocs, but hey, I can live
with this.
Change-Id: I705e0054cd7cd4350171770795d69f5c15c226d6
The documentation is something which our users see as one of the first
things when they go and try GNPy. With all respect to people who have
contributed over the years, there are more important information to
convey to a first-time user instead of a list of authors.
Change-Id: Ibe5f6477f9736b9ab71effcf0eccef7c7fdfdde5
This JSON file is never used by the rest of the code. Let's get rid of
one of these files which are put into the source code directory during
unit test execution.
Also remove other dead code; thanks to Esther for catching this.
Change-Id: I30a4e7edcf638162ec438fbf7f00d26d78944ac3
I decided to keep it around because I know that some people would like
to see those nanometers. Let's make sure it works.
Change-Id: Ib279cc8380a77f478da7a2bbc1e045a718446404
Given that everything else just uses these constants as imported from
numpy, there's no point keeping these wrappers around.
Change-Id: I0e19e05f40dc79d8005e915cf3ffb5e36328421a
Currently the string representation of some elements in elements.py refer to parameters that are not assigned until the propagate function runs.
Printing an element or trying to access its string representation before propagation therefore raises a TypeError.
This patch should fix the issue.
Change-Id: I29962f3c00e1f4fb7935535d4514a9579bc0c918
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
The compute_constrained_path function in request.py handles include nodes constraint by first finding all simple paths shorter
then a cutoff length and then checking if any of the paths meet the constraint. The cutoff is currently set to 120 which is
too small for large networks. For the CORONET_CONUS_Topology.json topology, for example, the shortest path between some node
pairs is longer than the cutoff.
This is a small proposed change to first compute the length of the shortest path and then set the cutoff to at least 20% (a
conservative number) higher than this. I also propose to increase the minimum cutoff from 120 to 150.
Change-Id: I97ff2915fb38e4681bd64d60f2cd6dfd422afd4f
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
"naming" with the "N" prefix looks reasonable, and it looks like my venv
has already had mccabe for that cyclomatic complexity. Let's get these
in.
Change-Id: Ie0cf4d8c20486f0f561db01903b3aa93cbebdb12
The code is already using long lines, so I think we can avoid a
discussion whether to raise this limit, and instead we can focus on
another discussion :) on what that limit should be.
Random googling suggests that GitHub's code renderer operates at 119
chars per line. A random style guide mentions going to 100 or 120. Prior
to this change, there has been 712 violations of PEP8 check E501.
Picking 119 would bring us down to 21 violations, and using 120 reduces
it further to 16. I think that 120 is a cuter number than 119, so 120 it
is unless someone objects hard enough to propose another cutoff in a
follow-up patch.
Change-Id: I57f48fcb6846fea35223daac91aa2e8c7afabc63
* changes:
CI: run flake8 for coding style nagging in changes
Fix syntax of the bandit config file
Upgrade pytest, and list it as a test-only dependency
CI: Activate coverage diffing
tests: simplify tox setup
CI: Run both non-coverage and coverage build/test jobs
tests: Check if example code provides exact same output
tests: Run examples via pytest
Show more details upon a test failure
This combines a few pieces of magic:
- Zuul merges speculatively, but in the git trees that the build VMs
see, the "current branch" is always the state as-if the currently tested
change was merged, while origin/"current branch" is the result of all
previous changes, if any, applied to the current tip of the target
branch.
- flake8 has a --diff option which appears to work correctly, *but* it
reports on all lines that are present in its input, including the
context -> hence the -U0 option.
Change-Id: I28403ff0132fac0b52696c82306732a4f81fa66a
See-also: https://gitlab.com/pycqa/flake8/issues/58
Unlike codacy, it seems that bandit the CLI tool complains about these:
Unable to parse config file: File contains no section headers.
file: '/home/jkt/work/TIP/oopt-gnpy/.bandit', line: 1
"skips: ['B101']\n"
Change-Id: Iab93052fd8aaf1754571a3c66796cfe3026f6a63
- test oms building:
o there should not be roadm or transceivers between end points except endpoints
o the element oms is must correspond to the correct oms id
o the element uid in the oms must match the id list
- test the alignment function
this function enables to have different grid end points in different parts
of the network. The grid used in the network must cover all these grids, so
some bit stuffing is needed on the oms that have different sizes.
The test checks that
o min and max attribute are correctly updated
o min and max n or freq values are consistent and consistent with bitmap
o alignment is correct
- test that the assignment of n and m values is correct
o check that assign_spectrum has returned an error code if the requested
assignment is not possible and that the bitmap has not been set to 0
o check that the bitmap sum works correctly when assignment is feasible
and that all range of spectrum has been set to zero. eg:
[1 1 0 0 0 0 1 1 1 1 1 1] and [1 1 1 1 1 0 0 0 0 1 1] must be:
[1 1 0 0 0 0 0 0 0 0 1 1]
- Check that spectrum assignment of 13,7 is correct in Hz
This example has been extracted from ITU-T G694.1
expected value in Hz for 13,7 is 193137500000000.0,193225000000000.0 in Hz
see fig I.3 of this document https://www.itu.int/rec/T-REC-G.694.1-201202-I/fr
- test assignment limits
o verify that inconsistent values raise error: ie with defined fmin fmax
n and m have limited values.
combine valid and non valid data for n and m
o verify that Bitmap created with a 0/1 list is consistent with fmin,
fmax, grid and guard band
- Test with a path configuration
o loop on assignment on a given path. assignment should be OK until n = 96
at that value the assignment is no more feasible (exceed grid) and the selection
function should return None value for all center_n, startn and stopn
o select an arbitrary request and try to assign 1 slot more than the whole
spectrum or exactly the whole spectrum and check that function correctly
return None or not None values
- Test assignment with reversed path
o add data and requests fixtures to reduce test time
o test that if spectrum is assigned on one direction it is also
assigned on reversed direction (bitmaps must be identical)
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Co-authored-by: Jan Kundrát <jan.kundrat@telecominfraproject.com>
Change-Id: I96dd15452cc2e59086d4022ec4b026be845f4355
- builds correspondance dicts between input name from excel
and names created with convert.py and autodesign in network.py
- correct the corresp_name dicts according to the effective
network autodesign. This supports the case of fiber splitting
and of fused elements
- include the case of parrallel links with only one hop
- interpret the node list constraint given by the user with the dict
- filter the constraints that are not applicable
- add tests for constraints
- correct equipment sheet of mesh_example_topologyv2.xls: morlaix and
loudeac should not appear in node A column since they are fused
ILA and FUSED constraints must be filled with the next node
information in order to avoid confusion on the direction.
for example
eg a----b-----c
| | |
i j k
| | |
e----f-----g
a constraint 'j' given for service i to k leads to 2 possible direction:
i-a-b-j-f-g-k
i-e-f-j-b-c-k
the user must indicate the chossen direction. This ambiguity does not
exist with network input in json format (names are unique).
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: Ia7cf2026e569c8b566459791fc89546b91fb117c
I was not happy with duplicating the "test command" section among
several tox test environments. I was not successful when using just
`.coveragerc` or via `addopts` in `[tool.pytest]`, but these
conditionals appear to work.
Also replace `pip install -e .` or `python setup.py develop` with tox'
native `usedevelop`.
Change-Id: I4986a3d14f38b7f6ed9b6a04f773eb222a53a827
This will make it simpler to update coverage info. The pytest-cov plugin
that we're already using apparently makes this behavior supported, nice.
Change-Id: Ieafc0da99a8c325f5f2286ed11e66069e244e43b
If user forgets to fill in the path_bandwidth, error message was
not explicit enough to help to correct.
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I776e95b6f859c3b643786b6e802f3c0bcbc1de76
The units can be found in several papers from the documentation
for example
A. Carena, G. Bosco, V. Curri, P. Poggiolini, M. Tapia Taiba, and
F. Forghieri. Statistical characterization of PM-QPSK signals after
propagation in uncompensated fiber links. In European Conference on
Optical Communications, 2010, 1–3. IEEE, 2010-09.
URL: http://ieeexplore.ieee.org/document/5621509/,
doi:10.1109/ECOC.2010.5621509.
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: If70b57a28ee108c4b8dbe341075e12169efbe14c
Now that https://review.opendev.org/712804 has been merged, we can just
use upstream jobs without that extra workaround.
Change-Id: Ia113caaea41bdd440dcb615c02ad95eba6da7543
I've bumped Sphinx because this might be needed for proper support of
pbr-provided version numbers. In the end I also had to re-run `pip
install -e .` locally, quite likely due to a different format of version
numbers now that pbr is being used, but let's make sure that we're using
a version of Sphinx that is now known to work.
Change-Id: I451b4b17bb8097eb7f2f0f0956cc1c956a531828
Ouch, this one hurts. It turns out that PBR-based setup does *not*
install all dependencies when running `python setup.py install`. On the
other hand, running any of:
- `pip install .`
- `pip install --editable .`
- `python setup.py develop`
...makes everything work. So, let's change the instructions and all the
build scripts (including the Docker file) to make sure this thing still
works. Sorry for noise.
This is a significant change, it means that people will have "in-place
installations" of GNPy. Changes to their git checkouts, if used, will
apply, etc. I think this is actually a good change.
fixes#287
TL;DR: package installation with Python is still a mess.
Change-Id: I422b889b599e0b7cae36f160d1548cef7fb50a4e
It turns out that our current setup does not really support the `sdist`
Python packaging step. I'm trying to increase automation, both for
making releases for upload to pypi.org, and also for CI via Zuul. As it
turns out, Zuul comes with a set of predefined jobs which -- by default
-- use `tox`, and tox was having troubles dealing with our `setup.py`
because it also assumes that the `sdist` step works. It is also supposed
to:
- fix version number duplication in `setup.py`,
- fix version number duplication in Sphinx docs,
- prevent the need to write a `MANIFEST.in` manually.
TL;DR: insetad of having to deal with a ton of other creative
boilerplate, use tools for lazy people like me, and PBR ("Python Build
Reasonableness") appears to check the marks here.
Change-Id: I27c36c4f6b0e76857d16f7819ec237e9b811476a
We're still primarily a GitHub project, so it is necessary to add a
pointer for git-review to point to GerritHub (which is our Gerrit
hosting site).
See-also: https://docs.openstack.org/infra/git-review/
Change-Id: I6fe8da2358ae50340fbe384b038ab097ab229b59
In commit 80eced8, the structure of parameters to `elements.Fiber` was
changed. Options such as fiber length are now passed in via
`self.parameters.*` instead of `self.*`. Commit 639b379 which fixed a
test failure precedes that change, and when we merge both as I did in
commit bc4b664, the test no longer works. My bad. On the other hand,
this will be caught by trunk gating which is something that Zuul can do,
and therefore something that we'll have in our upcoming CI, yay!
Fixes: bc4b664
Change-Id: Ifcd8f0bf01e9d91dbef3da1aa7f56f89132d6f48
The check on node_list constraint has to be be done on all elements except the last one,
and the last one is always a "STRICT" value. this means that if no constraints are given
this list is equals to ["STRICT"]. Previous code was using len("STRICT") ie 6 instead of
len(["STRICT"]) ie 1.
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
In order for Zuul to start self-testing, it must actually have
a project entry listed. This is the initial commit.
Change-Id: I017cb036f3191e46446d82b96a6acd35f2adcd0e
- no need to explicitly log exceptions that are about to be raised
- kill some extra commented-out prints
Change-Id: I73bae5a2456644c4d4ff45bd984d44c27bc22ec4
Using `with pytest.raises` is better than open coding the equivalent
feature. Similarly, when a block is not expected to raise an exception,
let's just let it run outside of a `try` block and rely on the test
framework to report a possible failure when hitting an unhandled
exception.
Change-Id: Icb1bb83e649733b56fcdc9168cabf88c9cf8d478
when a node name used in link does not correspond to listed
node names, Bad link msg was thrown without info on which link
causes the problem.
This change gives additional info on link and catch the user error
more cleanly.
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
TODO: a path containing only transceivers and no roadms leads to no oms
this has not been properly taken into account. (single link w/o ROADM
has no SA complexity and is out of the scope)
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
If request is bidir and 'z-a-path-metric' is missing, raises an error
If present, should not raise an error
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
remove some prints, indicate which from actual or expected key
is printed.
preceise that test is also performed on values
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Create an exception in case of an error due to spectrum problem
eg if spectrum request is not correct
if values are not correct.
use it instead of exit
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
When a request is blocked and its M value is set to 0. This should not raise
an error in pth_assign_spectrum. This test verify that the function
does not raise an error.
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
in case there is no possible disjoint path with the added constraints
(most of the time due to an inconsistant user request)
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
removing unused import
change short variable names to conform to [a-z_][a-z0-9_]{2,30}$
change main variable names to conform to [A-Z_][A-Z0-9_]{2,30}$
add or remove spaces
add docstrings
correct comments and indents of cut lines
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
remove unused imports
add docstrings
conform to '[A-Z_][A-Z0-9_]{2,30}$' pattern in main
remove trailing spaces
add/remove extra spaces
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
add one service only excel file + changes on compare.py to support
no synchronization vector case
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
add aa bidir request to test service error handling
TODO: write more detailed test on the bidir case
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
For this purpose we create a wrong request with M=0 and verify
that serviceError is correctly raised when calling Result_element class
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- add the bidir information on json expected services,
- add the label object in json responses
- add the spectrum on csv responses
- add the no-path container when relevant
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
function compute_path_with_disjunction needs an additional reversed path
and results must contain wavelength assignment
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
for codacy report:
removing extra spces before , and :
adding spaces after , :
adding spaces around < > =
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
reversed path must be computed even if bidir is not requested
because in WDM system service are all bidir.
bidir option is only to avoid lengthy propagation of reversed
path when it is not needed
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
for codacy report:
removing extra spces before , and :
adding spaces after , :
adding spaces around < > =
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- use a new jsontopath_metric function to collect metrics
out of a json response.
- path metrics must be shown also for reversed path if this
is requested. This function avoids repeading code here
- add reversed metrics on the last columns of the CSV
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
if --bidir option is used on the main program, the field is set
to true for all demands in case demands are expressed in an excel
sheet. --bidir option does not change bidir field if the service
file is in json format.
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Update the program because the same Path_request class is called
that now includes this bidir field
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- Instead applying bidir option independantly from service demands (json or xls)
the "bidirectional" attribute is introduced per request in the json.
This enables bidirectional option per requests.
if --bidir option is used on the main program, the field is set
to true for all demands in case demands are expressed in an excel
sheet. --bidir option does not change bidir field if the service
file is in json format.
Default value of "bidirectional" attribute is False.
- As a result the reversed path is propagated only if the birectional
field of the request is True. (remember that the reversed path must
be computed whatever the option because it is needed to compute
spectral occupation on both directions).
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
all BLOCKING_NOMODE requests have the same type of response
so the test is simplified to account for this
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- add some help input for the main program arguments
- move and correct comments
- add empty lines on stdout to have a nice printing
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
correct typos in comments and precise that results show the
mean value of SNR of all channels on stdout
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
in path assignment function, path elements and reversed path
elements are concatenated to compute the overall spectrum
availability on all elements
in main program, assignment is performed after computing reversed paths
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
add a bidir argument to make bidir propagation as optional.
Reversed path computation is not optional because it is needed
for spectrum assignment.
for all requests, if a path could be computed a reversed path is
computed and propagation is performed on it if bidir option is on.
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
reversed_oms was introdused in order to identify which oms correspond
to the reversed direction of a given oms.
with this commit we make use of this functionality and avoid the cumbersome
way that recovered the reversed path by computing shortest path in the
reversed way for each roadm. This function could not support multiple links
in parallel between two roadms, and was adding computation time.
The function first lists the oms of the pth in the reversed order and then
appends all its elements to the path. the first and last elements are transponder
and are append separately.
Unidir topology are not supported: if there is no reversed path, this raises an error
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
reversed_oms is introdused in order to identify which oms correspond
to the reversed direction of a given oms. Indeed for spectrum assignment
it is mandatory to mark spectrum resources occupation on both directions
(requests are supposed bidirectional in WDM).
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
The couple (N,M) is added on the last column only for non blocked requests
an empty string is used instead
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
The label object is added in the response. It contains center index N value
and number of slots M, required by the request according to the computation.
The label object directly follows the hop attribute as detailed in
draft-ietf-teas-yang-path-computation.
If the path is not blocked this changes the index of the last hop information
(-3 instead of -2) and the index of the transponder for the first hop
(2 instead of 1)
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
N is the center frequency index (on G694.1 grid) and M the number of slots M,
required by the request according to the computation.
for convenience, we use N and M = 0 when request are blocked. Note that N= 0 is
a valid index when M is not 0.
If the number of slot required by a request is not feasible, the request is marked
as blocked with 'NO_SPECTRUM' as blocking reason
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
previous way only check path existence to know if the request was blocked
or not.
Now the printing checks if the blocking_reason attribute exist, and if so
adapts the printing accordingly. The reason for blocking is added on the
output.
if no path could be computed, snr, osnr and other metrics depending on path
are replaced by empty strings
else, the metrics corresponding to the computed path are shown
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
In compute_path_with_disjunction, and in case user mode is not feasible
returns the blocking reason instead of an empty path.
If the user does not give the mode and the automatic selection does not
give any feasible mode instead of checking if a mode exists, the function
now checks the presence of a blocking reason.
if the blocking reason is among BLOCKING_NOPATH reasons, than an empty
path is returned
if the blocking reason is among BLOCKING_NOMODE, then a path could be computed
and the mode information correspond to the last explored mode.
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
creation of a function to avoid code duplication: json_param creates
the relevant parameters to show on the csv based on json input
replace try/except by a test on keys:
previous way tried to get pth_el['no-path'] and is the path was
not blocked this raised a key error. Now the there is a simple check if
the key is present.
Besides, as the no-path has been change to 'no-path' container containing
a 'no-path' attribute with the blocking reason, the test is made on the
attribute so on pth_el['no-path']['no-path'].
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
if the path is empty NO_PATH reason or NO_PATH_WITH_CONSTRAINT reason
is returned in the blocking_reason attribute
if no mode is feasible, the last explored mode is returned with the path (and
implicitly the last computed SNR). The baud_rate is derived from this last
mode
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
if path could be computed: gives details of the path and on the propagation.
- the 'no-path' attribute is changed to a 'no-path' container that contains:
o the 'response-id' attribute
o a 'no-path' attribute with blocking reason
o if a path could be computed, the 'path-properties' of the path that
was computed with the metrics
Note that this proposal to add information for blocking in the json output (instead
of a bare NO PATH) corresponds to the way PCEp is working in general, but is not yet
integrated in draft-ietf-teas-yang-path-computation model. Returning the whole path
in case of blocking in addition to blocking reason is a novelty from GNPy and was a
request from the users
TODO : use correct ietf model when ready
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Before continuing on spectrum assignment we need to clearly identify blocking reasons:
implicit previous way (a path is missing) is not satisfactory because in case of
spectrum blocking a path was possible. So we introduce a 'blocking_reason' attribute
on requests, that will only exist if the path is blocked during the process.
The 'blocking_reason' attribute refflects the blocking reason.
Commit defines blocking types and group them depending on the existence of path or
feasibility:
'NO_PATH': no path was computed,
'NO_PATH_WITH_CONSTRAINT': no path was computed with this constraint
'NO_FEASIBLE_BAUDRATE_WITH_SPACING': no path was computed due to the spacing constraint
'NO_COMPUTED_SNR': the computed path could not give any SNR result
'NO_FEASIBLE_MODE': the user let the program choose a mode and path was computed but
no mode was feasible for the set of constraints
'MODE_NOT_FEASIBLE': the user imposed a mode, a path was computed but this mode
is not feasible
'NO_SPECTRUM': a path, a mode were selected but there is not enough spectrum available on
this path
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
function is called to assign spectrum to each request
result shows an additionnal column for blocking reason
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
this is a first function that assigns spectrum following the order
of requests according to the selected mode and nb of channels computed
based on requested path_bandwidth
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
oms_list contains the list of OMS and each OMS contains the list
of uid of each crossed elements (ordered)
each element is updated with the oms_id to which it belongs
each oms contains a bitmap with frequency slots according to
frequency min max defined in eqpt_config.json (SI) and in case oms
are defined elsewhere, there is an alignment of grids to ease computation
the build_OMS_list function builds the OMS list and implements oms attributes
in all network elements
Commit also contains basic functions to handle spectrum bitmap and indexes
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
previous comparison was done on the result from .sort(), ie None.
list.sort() method modifies the list in-place and returns None.
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
if name of the constraint input from user is not part of networks names
(typically in the case of excel input), then the program try to find a
name that is clode to the user name and that is in the network list of
names. This list must not include trnasponder names (because transponder
end points are already listed as constraints and transponder in the
middle of a path are not supported yet)
This will be improved in the PR Ila names in constraints #278
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
add a no path case (request 6) in requests and expected responses.
response is also generated if path is not feasible: checks
that it is correctly handled in csv and json responses
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
create a json response based on test file and compare it to expected
response.
comparison first checks that there is no missing or extra key
and then compares keys
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
previous test assumed same order for header fields.
order the headers in the same way in order to support different
types of order
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
use
if not condition:
raise AssertionError()
instead of
assert condition
according to codacy recommendation
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
using pandas package to have an easy ordering of response column:
- test that the generated header is as expected
- read the response. In order to support different orders wrt
response answer and field answer, test function frst orders lines
according to response index and then to columns (fields of the answer).
check that the answers are as expected
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
previous try section encompass errors that should not be silently
ignored. Correction pointed a default in a test file.
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
anytype supported including transponder in order to accept well formed
route list from user (if user enters 'trx Lannion_CAS' this should be
accepted even if it repeats the source name)
A later PR better handles route list names
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
previously reported the requested bandwidth, now fill it with an
empty string, same as the other fields.
This will be updated in a later PR when different kind of blocking
will be supported
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- 'loose' and 'strict' changed to 'LOOSE' and 'STRICT'
- n, m changed to N, M
- unused objects removed
- ...
Also correct templates for service and response
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
previously contained the user-given source name in excel file,
but could differ from effective transponder source/destination
now both source and src-tp-id contain the same info (gnpy does
not make difference between node and ports)
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
restriction was placed on fiber type because when using excel input
autodesign create fiber names with syntax not explicit to the user, so that
entering a node name as constraint may end up to a wrong interpretation eg
aa -bb -> create names such as 'fiber aa to bb', fiber bb to aa' .
If user constraint is bb there is a ambiguity on the fiber direction.
However this is not a problem for user using json format.
So I preferred to removed this constraint now.
a later PR solves this naming ambiguity
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
since empty attributes have been removed from the requests with
previous changes, some aditional tests are needed to continue supporting
optional power and nch. (previous objects were created with null
or default values)
user may enter requests without specifying these fields, in this
case the object 'output-power' or 'max-nb-of-channel' do not exist.
the try /except form handles the corresponding exception and
default values are kept else.
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
change the naming according to model update +
previous changes authorize empty list of nodes.
This new test supports this case
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
previous way used a wrong interpretation of hop-type. in ietf model,
hop-type is reserved for LOOSE or STRICT constraint description.
Instead, transponder info , according to ietf usual way, should be
included aas a new path-route-object type. such object is not yet
defined in IETF so this is a GNPY proposal to use a 'transponder' object
with type and mode attributes.
this is what has been ecncoded in reques.py for requests and for answers
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
in case no path could be computed, the answer is changed according to
ietf path-computation model to a simple 'no-path' object
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
+ removing (currently) unused direction attribute.
This will be added again in a later PR when it will be used
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- removing empty objects (if no content , removes the object),
especially
- removing empty synchronization vector if no disjunction
constraint exists
- removing optional power and nb of channel fields, if user
did not specify any
when reading, first try if the object exists : try:/except to catch
this case
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- changes concerning names due to ietf path-computation draft changes:
- 'unnumbered-hop' changed to 'num-unnum-hop'
- suppression of 'label-hop'
- 'link-diverse' and 'node-diverse' changed to 'disjointness'
- correction because of previously wrong interpretation of the model:
- detailed succession on include nodes moved from
'optimisation /explicit-route-include-objects'
to 'route-object-include-exclude'
in 'explicit-route-objects' attribute
- correction of keywords
- n and m replaced by N and M
- strict and loose replaces by STRICT and LOOSE strings
- change the name of respponse from 'path' to 'response'
example service file corrected accordingly
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Writing an explicit comparison followed by argument printing *and*
handling the final error is just backwards. Let the tool be quiet, this
nonsense does not really add any value.
This might have nothing to do with the ITU frequency grid (it's really
just about a uniform distribution), so let's give it a more readable
name and more readable parameters.
This looks like the root cause of bug #243, the default values suggested
that this function works in THz.
These defaults are not used anywhere, so let's get rid of something
which adds no value and actively confuses people.
As agreed upon during today's coders call, this is something that is
needed by actual users in the field, so let's prioritize their needs
over clarity of output for demo purposes.
Esther and Jonas pointed out that it is much more common to work with
OSNR measurements per 0.1nm rather than per signal bandwidth. This is in
line with what OSAs usually report and what transponder datasheets
specify.
cc #307
As per Alessio's request, this adds a DOI and makes this software
citeable. DOIs are assigned automatically via Zenodo in a process that's
integrated with GitHub.
Merge develop into master in preparation for the 1.8 release
Highlights for the upcoming release:
- Raman simulation
- automatic building of Docker images
- bugfixes, refactoring, CI and docs improvements
(This replaces #261 by me and #293 by Jonas.)
## Remove debug printing from propagate()
This is inspired by #293. The original issue was that the transponder OSNR was not accounted for. Rather than making the `propagate()` and `propagate2()` more complex, let's move the actual path printing to the demo code. There's no secret sauce in there, it's just a simple for-each-print thingy, so let's remove it from the library code.
fixes#262
## doc: fiber length summary in km, not meters
Reading `80000m` is a bit more complex than just `80 km`. Also let's add a space between the numebr and the unit for better readability.
## examples: color highlighting of the "most interesting output"
I think that this SNR value represents the most important output of this example. There's plenty of debugging info on display already, so let's make this one more prominent.
I was thinking about moving the highlighting to elements' each `__str__()` function, but that felt a bit like layering violation to me. I could have also changed just the transponder's `__str__()`. In the end, I think that repeating just the final GSNR at the link-end transponder makes most sense here. This is aligned with what we talked about at yesterday's (on 2019-09-18 -- note that this is a backport from #261) demo for Microsoft, after all.
I'm trying to clean up the core code while not causing too much trouble
to our users. Esther pointed out that there's an internal use case at
Orange where people are looking at the incremental results when
computing paths.
I strongly dislike commented-out debugging code, but for the sake of
progress, let's put it in here. It's roughly as good as that unused
`show` parameter, and it allowed a refactoring to make the code more
readable.
This has been marked obsolete for 11 months. It's also one of the
callers of the propagate(), so it's being touched by that change which
removes the `show` parameter. This commit will make it easier to put
debug path printing just where it's really needed.
Various presentations from Polito are slowly changing to use "GSNR" as a
"Generalized SNR", but it's true that our code does not use this term
anywhere, and that it is not properly explained. Let's wait a bit for
this term to become a bit more mainstream and for updated docs on our
side; then this commit can be safely reverted.
Thanks to Jonas for reporting this.
I think that this SNR value represents the most important output of this
example. There's plenty of debugging info on display already, so let's
make this one more prominent.
I was thinking about moving the highlighting to elements' each __str__()
function, but that felt a bit like layering violation to me. I could
have also changed just the transponder's __str__(). In the end, I think
that repeating just the final GSNR at the link-end transponder makes
most sense here. This is aligned with what we talked about at
yesterday's (on 2019-09-18 -- note that this is a backport from #261)
demo for Microsoft, after all.
This is inspired by #293. The original issue was that the transponder
OSNR was not accounted for. Rather than making the propagate() and
propagate2() more complex, let's move the actual path printing to the
demo code. There's no secret sauce in there, it's just a simple
for-each-print thingy, so let's remove it from the library code.
fixes#262
A third, independent job in Travis CI just for building a container
image (and testing it a little bit). Here's how to use it once it is
built and published and pulled:
$ docker run -it --rm --volume $(pwd):/shared telecominfraproject/oopt-gnpy
One can also pass commands to it directly. Note that the *relative* path
specifier given as `./` is required. One could possibly get around it by
$PATH manipulation, but hey, I have to stop somewhere.
$ docker run -it --rm --volume $(pwd):/shared telecominfraproject/oopt-gnpy ./transmission_main_example.py
Thanks to Jonas for the --volume option trick and for that early
non-overwriting copying for the example directory.
The `install` phase in Travis CI is apparently common for all jobs in
the build matrix (it's rather confusing what they call a "stage" and
what is a "job" for them, and what their mutual relation is). Because
there's no point in doing any kind of installation in case when we're
building for Docker, let's just move the old `install` block into
`script`. With just that, however, Travis adds an implicit `pip install
-r requirements.txt` in an attempt at being helpful. In short, having
completely different "stuff to be done as a check" is very painful with
Travis.
The individual "script lines" in a job's `script` section are always
executed, all of them, even if a previous one failed. That's why I moved
the actual Docker invocation into an external shell script. When they
were not in a shell script and the script lines contained `set -e`, then
a failure of a particular command would cause the build to be marked as
"errored" instead of "failed" within Travis. Also, the multiline if
conditionals were rather painful to write.
One commit might end up in different branches. If that happens, the
second build would overwrite the image tag in the docker registry, which
is rather suboptimal. Let's try to fetch that image first, and only
update the latest/stable tags if the image was already available
beforehand.
fixes#260
- Avoid recalculating SNRs in transmission main example since they are already calculated and stored in the Transceiver class
- Also include per channel power (useful for checking tilt) and OSNR ASE in the output
As Jonas pointed out, the code used to contain a check for non-nan
values, effectively skipping channels where the Raman gain was not
explicitly computed.
Now that we do not introduce NaNs into some channels anymore, this
shortcut no longer works. We could either add explicit filtering for
only showing those channels which are covered by the Raman engine, but
then the result would be rather confusing in the non-Raman case. One
could also add another column with the simulated vs. approximated NLI,
but when I tried this, the output looked a bit cluttered.
I think that the best course of action for now is to just show info
about all channels (if asked by the user). So this is just a cleanup for
a condition which is now always on.
The Raman engine computes NLI just for a subset of channels; this is an
important speed optimization because the computation is rather CPU
heavy. However, the code just left NaNs in place for NLI of those
channels which were not explicitly simulated.
This is wrong because these NaNs propagate all the way to the total
input/output powers per the whole spectrum, etc, leading to NaNs being
shown to the user.
This patch uses a very simple linear approximation just in order to
prevent these NaNs.
fixes#288
Raman feature
I've added some very basic documentation (really, just usage instructions). What is still missing:
- more specific docs
- test coverage (right now, there's none!)
We've agreed to merge this sooner rather than later so that more people can reasonably test it. There's a bunch of things that I'm not happy with, such as the default example showing NaNs as the OSNR to the user at the end transponders, etc (I suspect this is due to simulating just some channels and no approximation, right?), but let's solve these based on feedback from testing.
As proposed in my earlier comments, I went ahead and merged the wrapper example code into the `transmission_main_example.py`. So here's what needs to be done in order to "use Raman amplifiers" in a basic example, with no autodesign:
- replace some `Fiber` elements with a `RamanFiber` in the network topology JSON
- invoke the example with a `--sim examples/sim_params.json` which activates the Raman engine
- pass the `--show-channels` flag so that the actual results are visible
This is more or less covered by the docs skeleton.
What I'm including here are comments from Vittorio (thanks!). It seems
that the majority of actual numeric parameters which drive the
simulation are undocumented, so this one will have to wait for Alessio
or someone else from the Polito team to fill the blanks.
There were just these substantial differences:
- the Raman code showed a per-channel SNR summary, this is now
controlled via the `--show-channels` option
- when a Raman fiber is used the `--sim` option for specifying input
simulation parameters is now mandatory
I'm therefore merging these two files even though we've rpeviously
decided not to do this -- consult the review comment at
https://github.com/Telecominfraproject/oopt-gnpy/pull/263#discussion_r310506082
and the discussion during this Tuesday's coders call). If this turns out
to be a problem for autodesign, we can always revert this.
One possible catch is that the final "SNR total" shows NaN for the
default Raman example. That's just the way the simulation engine works
right now, I'm afraid. The `--show-channels` options helps a lot.
Both of these places referred to "eq. 123 from arXiv:1209.0394", the
only difference (apart from the source of the input parameters, beta2
and asymptotic_length) was calling the two branches "SCI" and "XCI" vs.
"SPM" and "XPM".
In this commit I've only moved the code to a single implementation. The
input data are still being read from the same parameters, of course.
Conceptually, this is just about propagating the input parameters (which
drive the simulation) into all RamanFiber instances. The network module
already contains similar functions, let's move it there.
Compared to `eqpt_config.json`, the only extra content in the new copy
was the `RamanFiber` block. There's no disadvantage in just using one
equipment library; the traditional code can easily ignore the RamanFiber
stanza.
This is a typo, the parameters were clearly supposed to be uniformly
spaced. It doesn't affect the results (much), because the remaining
values are "close enough" for a reasonable interpolation.
Using the existing Raman example, the difference in OSNR ASE at the
signal bandwidth is 0.01 dB (31.46 -> 31.47 dB).
Perhaps it would make sense to enforce that these offsets are a
monotonic sequence.
For some reason, the code allowed using "convenience names" for
accessing properties since commit 58ac717f. To me, this looks like an
obvious anti-pattern because accessing a single property via three
different names only makes the code less readable. Let's kill this
"feature".
In case of the `Power` class, the code used "ase" and "nli" on the
majority of places, so let's use these abbreviations instead of their
spelt-out variants.
SpectralInformation was "clean" already, but there were calls to the
`update()` wrapper around the `namedtuple._replace`. Given that there
were no property aliases, it's safe to just call `_replace()` directly.
In case of the `Pref` class, once again always use `p_span0`, `p_spani`
instead of `p0` and `pi` -- it's a trivial change.
Since ReadTheDocs does not support [1] running as a CI check on GitHub
yet, let's make sure that we at least run sphinx. This would have caught
a recent docs breakage (see parent commit).
[1] https://github.com/readthedocs/readthedocs.org/issues/1340
Docs building started failing after our dependency update. The reason is
that the updated sphinx bibtex extension started being a bit stricter in
their interpretation of bibliography files:
parsing bibtex file /home/jkt/work/TIP/oopt-gnpy/docs/biblio.bib...
Exception occurred:
File "/home/jkt/work/TIP/_py/lib64/python3.6/site-packages/pybtex/errors.py", line 78, in report_error
raise exception
pybtex.database.input.bibtex.DuplicatePersonField: entry with key bononi_modeling_2012 has a duplicate year field
Fix this by using `date` as field name when a full date is given.
I misunderstood how Travis CI works; it's not a subshell, it's something
which affects the other commands. Let's just run everything from the
top-level directory.
Pinning dependencies to a specific version is safe in terms of
preventing accidental breakage, but it has a cost of possibly using
outdated dependencies.
Let's see if we can rely on the semantic versioning of our dependencies
here.
I'm doing this instead of other approaches (such as splitting the
top-level deps from "the rest of the dep chain" [1][2]) because I require
additional tools in my venv, such as the python-lnaguage-server. There
would be little point in injecting these into requirements to be used by
other people.
[1] https://www.kennethreitz.org/essays/a-better-pip-workflow
[2] 59eb51c026
Listing all transitive dependencies, including their respective versions
(as done by `pip freeze`, for example) is something which effectively
leads to installing outdated and possibly vulnerable software.
Let's get rid of the transitive dependencies.
Thanks to Esther for noticing.
The code determines these paths relative to the actual example .py file
already. Given that `pytest` and other bits expect to run from the
top-levle directory, let's remove this misleading instruction from the
docs.
I do not have a vector image of this one, unfortunately. The data
apparently comes from "someone at TIP", perhaps a hired graphic
designer. It was passed to me by Diego Landa when I asked for the
original dataset.
Rather than do the None-dance and document the default value within a
docstring, let's use the default value directly. This is safe because
numbers are immutable.
Because default arguments are evaluated *once*, not every time they are
called, a mutable default value is not "reset", and this happens:
>>> from gnpy.core.node import Node
>>> x=Node('123')
>>> y=Node('456')
>>> print(x.metadata)
{'location': Location(latitude=0, longitude=0, city=None, region=None)}
>>> print(y.metadata)
{'location': Location(latitude=0, longitude=0, city=None, region=None)}
>>> y.metadata['foo']=123
>>> print(x.metadata)
{'location': Location(latitude=0, longitude=0, city=None, region=None), 'foo': 123}
This is easily fixable by using an immutable value as a placeholder
here.
This feature is intended to support designs such as OpenROADM where the
line degree integrates a specific preamp/booster pair. In that case, it
does not make sense for our autodesign to "pick an amplifier". The
restrictions can be activated by:
- Listing them in `eqpt_config.json`, so that they are effective for all
ROADM instances.
- On a per-ROADM basis within the Excel sheet or the JSON definitions.
Restrictions apply to an entire ROADM as a whole, not to the individual
degrees.
If a per-degree exception is needed, the amplifier of this degree can be
defined in the equipment sheet or in the network definition.
If no booster amplifier should be placed on a degree, use the `Fused`
node in place of an amplifier.
Signed-off-by: Esther Le Rouzic <esther.lerouzic@orange.com>
Co-authored-by: Jan Kundrát <jan.kundrat@telecominfraproject.com>
testTopology listed corlay twice in Eqpt although it is a ILA.
should appear only once in node A column
update expected parser results for this change in tests/data
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
program was not correctly listing nodes when links duplicate EDFA entries.
I refactored it to make it simpler to understand.
I added coordinates on ../tests/data/testTopology.xls for plot purpose
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
I have no idea which one of the existing pypi modules is best for these,
and given that we're using just two escape codes, I think it makes sense
not to bother with a more capable third-party module just for two magic
strings.
Once the actual config-parsing code start raising these exceptions
instead of directly calling sys.exit(), the user experience would
deteriorate due to raw exception traces. There's little value in the
trace itself, so just wrap the whole config loading with pretty error
formatting.
We still do not point to a specific place where that error is defined
(such as a line/column in a given JSON file) because that information is
already lost by the time we perform these checks.
Also, these checks are largely open-coded ad-hoc stuff. Some required
items are not covered, raising KeyError instead. We should get a formal
schema for these...
While the `itufl()` function uses THz by default, its values depend on
the frequency range that is passed via arguments. In this context, the
f_min and f_max come from the default SpectralInformation which is in
Hz.
Thanks to @ojnas for reporting this.
fixes#243
For some reason, warnings were disabled in commit 07de78c, but it is not
clear to me what the purpose was back then. It passes without warnings
locally, and I think that warnings are useful in general, so let's give
the CI a try.
The results are still perfectly visible within the *Checks* tab, so
let's cut the comment spam a little bit.
I've already done the same for lgtm.com; for that app, it's done in
their service's configuration within the web app.
If `nf_min` was not present, then `nf_max` would be left remaining
because an attempt to nuke `nf_min` raised an exception.
Thanks to codecov.io for making it easy to spot this on the coverage
page.
...which might give us a faster, container-based build environment as
long as some legacy, several-years-old docs are still correct. Let's
give it a try.
According to the Travis-CI docs, this requires switching to a newer base
OS image. It might not require an explicit pin like this in near future
as the default is, apparently, being migrated at this very time, but I
do not feel like working with a random rolling-update process of a
third-party service, thank you.
These two lists were not synced with each other, and some contributors
whose commits have been merged in git were missing. The resulting list
is a bit longer because not everybody who contributes does that strictly
via commits pushed to GitHub.
Teh changelog is available over GitHub (and also within the git tags,
now that I added the missing v1.2 tag), so let's cut the verbosity a bit
by just linking to a dedicated page for this trivia.
The table was completely hidden from the HTML rendering at GitHub. The
space between the "left edge" of the table and the text content appears
to be substantial.
exception KeyError type in service sheet not correctly catched
print Request.mode instead of Requestmode (not defined at this point)
selection of modes did not respect min spacing criterium:
constraint added
transmission_main did not give SNR in 0.1 nm: added in std out
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
when constraints such as include noe or disjuntion is applied
the candidates are sorted with shortest path in length first
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
add weight = length of fiber nodes on connections wher from_node is a fiber
add weight = 0.01 km on other edges
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
-separate edfa and raman_list of acceptable amplifiers to better
customize criteria between edfa and raman amplifiers
for example min gian requirement: no extended min gain range for raman
amplifiers because there is always an edfa solution, which is better for
small gains.
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
- in auto-design, Raman is already not used if lineic fiber loss >
eqpt_config.json [Span][max_fiber_lineic_loss_for_raman]
- this commit ensures that a warning is displayed even when auto-desing
is not used (when the network equipment configuration is imported from
json or xls topology)
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
EOL span ageing was added for each connector "to be fused" span
=> now, EOL ageing is only added to the last span of the fused spans
section.
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
Coordinates in files changed during the autodesign compared
to previous autodesign version: autodesign_expeted test
files updated
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- use the same file to test different configuration: with and without Eqpt sheet defined,
add the abcdfgh topo for disjunction tests in the same file
- change the name of files to avoid mixing with examples/meshTopologyExampleV2.xxx
TODO: test if examples/ files pass for both path_requests_run and trasmission_main_example
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- update eqpt_config.json to power-mode : false to take into account gain target
of the eqpt sheet
- correct eqpt-config.json with new parameters
- add gain target in meshTopolgyExampleV2Eqpt.xls
- correct test_parser.py test function names
- suppress Exceltestfile
- change power_mode in test_parser to True in eqpt_config.json for all tests
except for parser: changed in the function to False to enable
Eqpt files gain target reading
Next: reduce the number of test files and include examples/ files in the tests
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- tests if networ autodesign does not change some reference files
- changed the meshTopologyExampleV2 files to account for newest features:
empty columns in mode, power, nb channels, disjuntion examples ...
- added a tsp type with more modes for diversification of tests
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
-add f_min & f_max frequency definition in amplifier json
-improve interpolation algorithm to support length differences between the spectrum information and the amplifier ripple and dgt frequency definition
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
new code provides default values when attribute is missing in the
eqpt_config.json, which can cause unexpected beahaviour
=> provide a warning message when a missing attribute is set to a
default value.
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
warning message when extended gain range or power requirements cannot be met
and power is reduced
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
set individual channel powers wrto the target reference power
tilt and ripple is eliminated after the Roadm
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
power mode no longer reads operational_gain:
now reads operational.dp_db
or calculate optimum dp_db from next span loss
gain_mode:
reads operational.gain_target
or use gain_from_dp
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
squash to dp
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
tolerate 3dB below min gain in amplifier selection
this is to allow selection of high power amps even if they are below min
gain
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
used for amplifier selection in auto-design
but it is possible to manually use and set an amplifier beyond its
extended_gain_range
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
auto_design over meshTopologyToy.xls will show raman use
run:
python transmission_main.py meshTopologyToy.xls
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
support min gain for raman auto-design:
raman amplification is only considered for a span if its gain > specified
min gain of the raman hybrid in eqpt_config
auto-design was checked succesfully when enabling a mix of 6 possible different
amplifiers: low gain, medium gain, hybrid ramans, high power and high
gain amplifiers. They were picked as expected.
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
quick & dirty 1st implementation:
-fixed raman nf and gain,
-no tilt, no ripple,
-no nonlinear contribution,
-no pump power reduction from egress con loss
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
-read sys_margins in equipment['SI']
-add sys_margins to all Transceivers OSNR for path feasibility check
(path_request_run only)
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
add_drop_osnr contribution is added at the end of the transmission
propagation, at the same time as Tx_osnr
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
add Tx_osnr or add_drop_osnr on raw snr values to avoid cumulated adding
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
bug fix: forgot to add add_drop_osnr with tx_osnr
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
save and be able to retrieve the carrier information processed by Edfa
and Fiber elements:
@ input & output of the element
- channel power: ase, nli, signal and total
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
Check and remove duplicate links
a warning is issued when a duplicate link is dicovered
the execution is paused for the user ot see the warning
the duplicate link is removed and the execution resumed
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
with this feature, spacing is checked with respect to eqpt library
instead of hard coded values in equipment +
mode selection is based on the minspacing instead of a coef or margin on baudrate value
some sanity check are introduced:
- request spacing must be greater than min spacing
- tsp baudrate must be smaller than min spacing
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
add colors on messages to highlight them
add messages explaining program steps
update readme and excel user guide with latest fetures
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- indicate when a mode is selected if the selected path does not pass
+ some reformatting of columns
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- indicate which request has incorrect tsp type or mode
- correct wrong reading from excel : if string values contain only a number
xlrd interprets as a float eg 1 -> 1.0 . A function is used to correct this
when filling the Request class
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
exception handling add some info on which element (uid) is causing a problem
this can help the user to identify where he must correct the input files
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
all_simple_path search leads to a very long time process in case of large network
a cutoff parameters has been added to avoid this. Value needs to be parametrized:
right now correspond to my experience
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- output file of -o option in path_requests_run.py was not correctly
handled in case of path indirection eg ../../bar.foo
- fiber constraint is not correctly handled in case of several parrallel directions
of same fiber name. remove if from the set of constraint till problem is not solved
- loose_list was not correctly indexed in request.py. assume the first element attribute (except
of the transceiver) applies for the whole list. This will need further corrections
- handle the case when path.snr is none in the optimization of mode process
with this feature, spacing is checked with respect to eqpt library
instead of hard coded values in equipment +
mode selection is based on the minspacing instead of a coef or margin on baudrate value
some sanity check are introduced:
- request spacing must be greater than min spacing
- tsp baudrate must be smaller than min spacing
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
add colors on messages to highlight them
add messages explaining program steps
update readme and excel user guide with latest fetures
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- indicate when a mode is selected if the selected path does not pass
+ some reformatting of columns
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
add combination of [mode, pow, nb channel] filled or empty
leading to feasible path or not, and check the propagate and propagate_and_optimize_mode
functions work as expected on a reference toy example
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
tx_osnr was impacting automatic mode selection feature : this commit solves the error
+ add a novel version of the excel example with an empty mode cases
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
exception handling add some info on which element (uid) is causing a problem
this can help the user to identify where he must correct the input files
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- indicate which request has incorrect tsp type or mode
- correct wrong reading from excel : if string values contain only a number
xlrd interprets as a float eg 1 -> 1.0 . A function is used to correct this
when filling the Request class
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
all_simple_path search leads to a very long time process in case of large network
a cutoff parameters has been added to avoid this. Value needs to be parametrized:
right now correspond to my experience
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- output file of -o option in path_requests_run.py was not correctly
handled in case of path indirection eg ../../bar.foo
- fiber constraint is not correctly handled in case of several parrallel directions
of same fiber name. remove if from the set of constraint till problem is not solved
- loose_list was not correctly indexed in request.py. assume the first element attribute (except
of the transceiver) applies for the whole list. This will need further corrections
- handle the case when path.snr is none in the optimization of mode process
small fix: correct wrong numbering of request in json and csv
output when -o is used ; correct example files
signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- this version handles special cases: if no baudrate satisfies the spacing
, if no mode satisfies the OSNR threshold from transponders
- template of service corrected wih the novel path_bandwidth
- some ideas TODO added for testing
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- adding cost in every config files including tests files,
- correcting wrong usage reactions (if value is not correct)
- correction of orthograph
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Correction of data file for test_parser.py + adding a test on path non looping
- service json files now include path_nadwidth value
- previous constrained routing did not ensure loop free path. This has been
corrected in A test has been added to avoid loosing this feature in future
versions.
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- correction of json to csv function
- small correction on disjunction format to avoid double (double crash the program)
- adding time stamp to measure perf
- demands with all the same disjunction can be aggregated
- a new set of disjunction list is created to avoid inconsistancy
with the aggregated request-ids
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
adding the counting feature on standard output
adding tsp nb in csv + small bug fixes
small fixes to improve stdout and csv printing
small bug fixes on service aggregation and automatic correction of names
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
if mode is not given, the program automatically choses the first mode of the tsp
that has the highest bitrate and baudrate
- propagation for each loop on baudrate, no proppag in the loop on the mode
(same propoagation applies for identical baudrate)
- starts with the highest baudrate
- Make power and nb-channel optional fields
- power uses defaulf power in SI
- nb channel computed based on min max frequency and spacing
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- add bitrate in the json service file and enable to support both with and without bitrate
- change mode to optional
- add an aggregation function that groups identical demands (except for id and bitrate)
TODO : check which mode can satisfy the request or how many transponders -> going towards
dimensionning
- Correcting some bug on loose parameter: hop-type attribute was forced to be always 'loose'
-> now reads the excel entry
- service sheets checks on header if field names are corrects, but any order is
now feasible.
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- re-changing to to \u2192 in convert.py to comply with test files
- changing route constraint in data file : the constraint had a too ambiguous
naming in the service file
- test on None was incorrect in convert_sheet
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
correct loose or strict constraint in the new function correct_route_list
correct test to find the name with existing uids
remove the \u2192 char that was not well supported with excel reading
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- normal way is usually to apply the design optical power for all channels.
This change uses the default power (same power as used for design) but enables to
force an arbitrary power if needed. TODO : introduce spectral power density
to apply power depending on baudrate.
- definition of min max frequency and spacing define the nb of channels:
uses min max frequencies and spacing to determine nb-channels. It is possible
to force a different spacing for the request. TODO: check that the value is
consistant with baudrate and min max values.
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
service_sheet.py contains exactly the same function: I suggest to remove this file
to clean the examples directory
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- create some test to check that produced paths are really disjoint
- add some TODOs on optical power for requests computation
First check of disjunction feature added to tests
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- select the first path that is satisfying disjunction
not finished:
- constraints on nodes not taken into account
- modification on the build network not added
- not clean, need some refactoring
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- Implementing a conflict table for path disjoint choices
- adding disjunction in the parser and json (read and write)
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
take into account manual padding input, i.e. att_in defined in fiber params
add EOL even if con_out is not None
Force Roadm input power to 0 in power_mode even if the ingress amplifier
gain is not null
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
- adding a test to check that transponder types and modes are part of the eqpt library
- adding a formating on numeical value input for path request ids
- automatically printing the results into a csv file in addition to the json file
and with the saime name+.csv
- printing results in a more pretty way for demo
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
-Promote incremental and iterative network design
-Automatic saving of a "network-name_auto_design.json" file
-Results of the autodesign (additional amplifiers, configuration) are
saved to this ..._auto_design.json file
-This file can then be used to run a new simulation just like a normal
json input file
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
- adding a program to convert json result file into a CSV file
- adding some more metrics in the results
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- typos corrections
- explanations on cable id, create_eqt_sheet.py, dimensionning
- adding updates in user guide
- harmonisation of naming _eqpt instead of eqt in create_eqt_sheet.py
- improving standard output, removing pi ref power print on standard output
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
align the behaviour of
eqpt_config[SI].power_range_db
with
eqpt_config[Spans].delta_power_range_db
so that the min and max excursions are taken into account (which was not the case
when using range or arange for the SI power excursion)
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
power range sweep fix
fix behaviour when power range length = 0
update eqpt_config json default values
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
restore verbose off for power sweep
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
new field 'out_voa_auto': true/false in eqpt_config json for elligible
amplifiers
if the field is set to true and the power_mode (in
eqpt_config[Spans]) is also set to true, a VOA value is calculated based
on available gain and power margins (EOL) to maximize amplifier gain and
improve its NF
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
can pick up the best NF amplifier among several amplifiers
sharing the same gain and/or power requirements when these requirements
are not satisfied (used to take the highest gain or the highest power)
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
amplifier selection in autodesign now takes into account
-required design gain
-required design power
-lowest NF among amplifiers satisfying the requirements
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
separate in the code:
* add egress amplifier
* vs setting the amplifier parameters
=> prepare improvments in select_edfa and target_power code
regroup all network optimization operations in network.py (remove from
transmission_main)
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
* toggle true/false in eqpt_config json file to allow the use of a given amplifier type in automatic design: eqpt_config[Edfa][allowed_for_design] : true/false
* automatic design is picking the best amplifier (gain, NF constraints)
among the available ones: if toggle to false, the type is deemed non
available. Only alternative before this feature was to remove the
amplifier from eqpt_config library.
* if set to false, the amplifier type can still be input in the network
topology file: it will be recongized.
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
* automatic design (when amplifiers are missing from network topology
input) finds the optimum power difference between spans
* The range of this optimum power difference is defined in
eqpt_config[Spans][delta_power_range_db] = [min, max, step]
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
=>small span padding now looks at the total loss of all spans spliced
together instead of individual span losses
=>the att_in padding attenuator is placed at the input of the 1st span
(the 1st of the serie of spans spliced together with Fused ne)
squashed with the fix to implement att_in attenuation in Fiber.propagate
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
intermediate bug fix to be squashed
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
read [Spans][padding] in eqpt_config json file
* add input attenuator on all fibers in the network with loss < padding
* create new Fiber attribute: att_in, which is a fixed attenuator for
padding purposes
* define "padding" : 0 in eqpt_config will disable the feature
effectively
improve fiber splitting to take into account the padding target in the
min fiber length and the target length is set accordingly to this min
length
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
* Fiber or Edfa type_variety in the the network topology that are not
defined in the eqpt_config json (for example Fiber ELEAF) no longer
crash the code: instead there is a clear error message and the code exit
gracioulsy
* remove outdated network topology json files
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
read fiber spans default values from eqpt_config.json[Spans]
=>if con_in/con_out is None or not defined in params
Rename connector_loss_in/out to con_in/out for consistency
update parser tests to accept the new con_in/out syntax and the new default
values
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
=> read power range [lower, upper, step] in eqpt_config.json
do not display intermediate NE info if range > 1
=> update eqpt_config.json data
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
* apply to power_mode only
* bug caused by the previous merge
restore default connector loss in excel to json parser (convert.py) to
0dB
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
roll_off is a characteristic of a given mode of a transponder: it is now
integrated in the Transceiver library in eqpt_config.json. Default value is
provided in the SI field if no specific transponder type is input
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- adding relevant call in path_request_run
- unifying variable name: baudrat -> baud_rate
- correcting test with the new power features
- unifying naming of variables n_ch-> nb_channel, sink -> destination (this
follows the usual naming in yang path computation models)
- bug fix in novel trx_mode_params function , use of the function in
path_requests_un
- TODO : place roll-off in the tsp lib instead of SI
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
creation of modular functions to be called
use of the same propagate function in both examples
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- use load_equipment instead of load_SI
- integrate the pathrequest class into transmission main
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- Path_request class is updated to be more generic and reuseable
in transmission main example. json processing linked to the yang
modelling is kept in the pat_request_run, while path_request class
only contains useful attributes
- adding functions in info and request python files in core directory
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
bugs from the last refactor merge
- fix#1: update fiber length after split
- fix#2: add egress amp after fiber split
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
test verifies that OSNR and SNR computed values are consistant
including connector loss and input power variation
onto 2 example links: 1 and 5 spans
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
previous json did not have connector losses input:
this commits updates the json expected files with the additional
connector losse in parameters .
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- connector losses can be part of the json description or not
in any case a connector loss in and out is now part of the fiber class.
if not present the default value is 0.0 dB
- propagate function in Fiber class now has a first attenuation
propagation step. output conn loos is integrated in the
initial loop function.
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
- Separating test python files for different purposes
convert_file and convert_service_sheet now tested in a dedicated
file testing parsers_test.py
- Correction of tests due to previous major refactor (especially introducing
load_network)
- adding test files and references (expected json files)
- adding a test on service json file
- adapting the compare module to generated files
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Excel_userguide has been updated with a description of how to use the service sheet
documentation on convert_service_sheet has been added
bugfix on convert_service_sheet to avoid multiple file writing
bugfix on create_eqpt_sheet.py to avoid the creation of a line when site is FUSED type
Completing README and adding templates for json files
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Path_requests_run and convert_service_sheet.py now use funtions from transmission main
ISSUE from develop refactor : the json generation of the topology is missing all amplifiers !
- ILA are not included
- some edfa appear in the json topo when Eqpt sheet is used, but not all of them (only for
the requested path when running transmission_main_example)
TODO : identify if this is a new behaviour or if this is a regression
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
convert_services_sheet. py reads all columns and creat adhoc attributes.
Route constraint is saved in the "optimisation" field of the json format.
it is used as strict constraint for path computation. automatic decision
on node type is made based on the name.
Spacing, nb of channel and input power have been set in the requests json,
however this may not be inline with the ietf way: they should instead be
link attributes. However the objective of the program currently diverges
from this control oriented description , since requests explore whatif
scenarios for each request with its specific transponder type.
Introduction of loose case for the route constraint , input power,
spacing, nb of channel, per service entry
If no path exist to a loose node it is skipped. else a critical error is raised
Minor corrections on convert and path request
- convert: remove source and destination from intermediate list of nodes if
they are listed
- correction on the header of the sheet (column names)
- path-request: removing debug printings for a nice demo :)
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
verify that the trx_type is in the eqpt library
+ correction on the convert_service_sheet (use a list instead of multiple classes initialization)
Parametrisation of networkfile and spectril information in path_requests_run.py
addition of a second input file so that input can be with 2 excel files,
or with 2 json files , or a mix
utilisation of SI attribute in Eqpt_config.json for the input of spectral
information.
Implementation of transceiver_variety and parametrisation of eqpt_config.json
each request now reads the tranceiver type and convert it into
baudrate (assuming a mode).
eqpt_config file is now an argument of the path_requests_run.py
Adding additionnal columns in service sheet for mode, system and route
Transponder selection now includes the tsp modin the eqpt sheet now
also relies on mode name.
additional columns have been defined to input system values such as
channel spacing, input power, nb of channels. TODO : This enables to compute
the spectral information vector according to the transponder features
for each service in the list...
2 optional columns to define the path as input (with a loose attribute):
if present the path must contain the ordered list of nodes to be crossed
TODO : use path input instead of the internal path computed
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Modules converts the service sheet into json file:
initial definition of classes.
Completing the json template of path computation request
Adding sync vector : but not in the correct form
should avoid multiple sync entries with same info
Treating multiple requests:
path_request_run.py allows computing snr from a list of requests
TODO: integrate into transmission_main_example and enable
feasiblility computation without path computation
Using transceiver class structure to export path computation feasibility
the output of the function now exports a list of tranceiver element,
each containing the result from spectral information propagation.
Adding transceiver type in eqpt library + correct form of xls sevice sheet
eqt library includes information abour transceivers and their modes
(baudrate, bitrate, OSNR threshold, and short name)
service sheet must not have annotation or comments outside of the useful row/column
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
network design when no amplifiers are input in the json file
select_edfa chose the best amplifier in equipment list _from
eqpt_config.json_ wiht the following criteria in order:
1-amplifier wih sufficient gain
2-amplifier wiht sufficient power TODO
3-best NF amplifier staisfying 1 & 2
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
xls topology is parsed automatically to json
transmission_main reads from the json generated topology
transmission_main should not read from convert.py data output
This way there is consistency between json and xls inputs
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
6 files are tested: if the converted json file constructed
based on the excel files provided in the test folder are not
identical to expected result, the test fails.
For future creation of test files:
excel name file should start with excelTest.
reference json file should be identical to the excelTest
eg excelTestFilefoo.xls -> testFilefoo.json
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
replacing bare string reading with Path object and split nam based on
Path structure in convert.py and in transmission_main_example.py
Update of pytest tests
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Typos correction
Explanations added on how to fill in the excel Eqpt sheet
Removing verbose printing for debug of create_eqpt_sheet.py
Bug correction : blank removed when copying city names with creat_eqpt_sheet.py
Typos correction on README and Excel_userguide
adding some line for the export PYTHONPATH in the readme
typos corrections
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
The README now points to a user guide file explaining the sheets and column format
the guide is not finished
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
The program reads the xls Nodes and Links Sheet and create the
mandatory city column as a text file.
If not present in Nodes the Type column is implicitely derived
from node degree (degree 2 means ILA, other means ROADM)
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Text file path and name copied from excel input file for create_eqpt_sheet.py
input file name is used for the txt file creation
file is saved at the same place as the input file
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
xls convert:
sanity check Nodes vs Links sheets
column parsing limitation so user can add non code related
fields/information
code fix and eqpt_exists to check if an equipment is defined in the eqpt_config.json library
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
fix bug in Fused span: adding ingress and egress directions
=> do not share the same NE between 2 directions
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
*new Fused spans class to support the connection between 2 fibers
without amplification
*add_egress_amplifier adjust the edfa gain to compensate the loss
of n fused spans
*eqpt not found in eqpt library is caught and stop the code
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
code fix for the eqpt sheet reading in xls parser
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
amplifier design and eqpt parser code fix
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
*eqpt sheet is optional: no error message if missing
*All nodes description is not needed
=> only read the node eqpt config when amp_type is input
=> if amp_type = '', the node ingress or egress eqpt is ignored
=> the network.py add_egress_amplifier will fill in missing edfa
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
improve code reading and clarity of topology parser:
*modify the connections binding
=>def fiber_dest_from_source to find all dest_city connected to a source_city
=>def fiber_link to return the fiber link from source_city to dest_city
*makes the parser algorithm more understandable
*prepare for the equipment parser
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
*namedtuple default values are only applied if the cell is not read
*if the cell is read but is empty '', there is a need to provide default
values: which is what this fix does
*sanity checks are reinforced :
-node_type is replaced by ROADM if degree <> 2: notify user
(print)
-check that node type is in ('ILA','ROADM','FUSED')
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
Parse advanced fiber parameters from xls into json format:
accept a .xls or a .json input parameter
creates the corresponding .json file
read east/west directions for fiber parameters (fber type, distance...)
read node type (ILA or ROADM)
provide default values if fields are missing
=> full backward compatibility to read the original CORONET xls
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
-read eqpt_config.json with various EDFA and fiber type definitions
-std low gain and medium gain EDFA available
-clearer differentiation between the 2 edfa models:
is the advanced_config_from_json field present or not?
Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
If it isn't much trouble, please send your contribution as patches to our Gerrit.
Here's [how to submit patches](https://review.gerrithub.io/Documentation/intro-gerrit-walkthrough-github.html), and here's a [list of stuff we are currently working on](https://review.gerrithub.io/q/project:Telecominfraproject/oopt-gnpy+status:open).
Just sign in via your existing GitHub account.
However, if you feel more comfortable with filing GitHub PRs, we can work with that too.
[](https://lgtm.com/projects/g/Telecominfraproject/oopt-gnpy/)
[](https://codecov.io/gh/Telecominfraproject/oopt-gnpy)
GNPy is an open-source, community-developed library for building route planning and optimization tools in real-world mesh optical networks.
We are a consortium of operators, vendors, and academic researchers sponsored via the [Telecom Infra Project](http://telecominfraproject.com)'s [OOPT/PSE](https://telecominfraproject.com/open-optical-packet-transport) working group.
Together, we are building this tool for rapid development of production-grade route planning tools which is easily extensible to include custom network elements and performant to the scale of real-world mesh optical networks.

## Quick Start
Install either via [Docker](https://gnpy.readthedocs.io/en/master/install.html#using-prebuilt-docker-images), or as a [Python package](https://gnpy.readthedocs.io/en/master/install.html#using-python-on-your-computer).
Read our [documentation](https://gnpy.readthedocs.io/), learn from the demos, and [get in touch with us](https://github.com/Telecominfraproject/oopt-gnpy/discussions).
This example demonstrates how GNPy can be used to check the expected SNR at the end of the line by varying the channel input power:

GNPy can do much more, including acting as a Path Computation Engine, tracking bandwidth requests, or advising the SDN controller about a best possible path through a large DWDM network.
Learn more about this [in the documentation](https://gnpy.readthedocs.io/).
`gnpy`: mesh optical network route planning and optimization library
====
|docs| |build|
**gnpy is an open-source, community-developed library for building route planning
and optimization tools in real-world mesh optical networks.**
`gnpy <http://github.com/telecominfraproject/gnpy>`_ is:
- a sponsored project of the `OOPT/PSE <http://telecominfraproject.com/project-groups-2/backhaul-projects/open-optical-packet-transport/>`_ working group of the `Telecom Infra Project <http://telecominfraproject.com>`_.
- fully community-driven, fully open source library
- driven by a consortium of operators, vendors, and academic researchers
- intended for rapid development of production-grade route planning tools
- easily extensible to include custom network elements
- performant to the scale of real-world mesh optical networks
Documentation: https://gnpy.readthedocs.io
Installation
------------
``gnpy`` is hosted in the `Python Package Index <http://pypi.org/>`_ (`gnpy <https://pypi.org/project/gnpy/>`_). It can be installed via:
Both approaches above will handle installing any additional software dependencies.
**Note**: *We recommend the use of the Anaconda Python distribution
(https://www.anaconda.com/download) which comes with many scientific
computing dependencies pre-installed.*
Instructions for Use
--------------------
``gnpy`` is a library for building route planning and optimization tools.
It ships with a number of example programs. Release versions will ship with
fully-functional programs.
**Note**: *If you are a network operator or involved in route planning and
optimization for your organization, please contact project maintainer James
Powell <james.powell@telecominfraproject>. gnpy is looking for users with
specific, delineated use cases to drive requirements for future
development.*
**To get started, run the transmission example:**
..code-block::shell
$ python examples/transmission_main_example.py
By default, this script operates on a single span network defined in `examples/edfa/edfa_example_network.json <examples/edfa/edfa_example_network.json>`_
You can specify a different network at the command line as follows. For
example, to use the CORONET Continental US (CONUS) network defined in `examples/coronet_conus_example.json <examples/coronet_conus_example.json>`_:
GNPy is a sponsored project of the [OOPT/PSE](https://telecominfraproject.com/open-optical-packet-transport/) working group of the [Telecom Infra Project](http://telecominfraproject.com).
There are weekly calls about our progress.
Newcomers, users and telecom operators are especially welcome there.
We encourage all interested people outside the TIP to [join the project](https://telecominfraproject.com/apply-for-membership/) and especially to [get in touch with us](https://github.com/Telecominfraproject/oopt-gnpy/discussions).
## Contributing
`gnpy` is looking for additional contributors, especially those with experience planning and maintaining large-scale, real-world mesh optical networks.
To get involved, please contact [Jan Kundrát](mailto:jan.kundrat@telecominfraproject.com) or [Gert Grammel](mailto:ggrammel@juniper.net).
`gnpy` contributions are currently limited to members of [TIP](http://telecominfraproject.com).
Membership is free and open to all.
See the [Onboarding Guide](https://github.com/Telecominfraproject/gnpy/wiki/Onboarding-Guide) for specific details on code contributions, or just [upload patches to our Gerrit](https://review.gerrithub.io/Documentation/intro-gerrit-walkthrough-github.html).
Here is [what we are currently working on](https://review.gerrithub.io/q/project:Telecominfraproject/oopt-gnpy+status:open).
## Project Background
Data Centers are built upon interchangeable, highly standardized node and network architectures rather than a sum of isolated solutions.
This also translates to optical networking.
It leads to a push in enabling multi-vendor optical network by disaggregating HW and SW functions and focusing on interoperability.
In this paradigm, the burden of responsibility for ensuring the performance of such disaggregated open optical systems falls on the operators.
Consequently, operators and vendors are collaborating in defining control models that can be readily used by off-the-shelf controllers.
However, node and network models are only part of the answer.
To take reasonable decisions, controllers need to incorporate logic to simulate and assess optical performance.
Hence, a vendor-independent optical quality estimator is required.
Given its vendor-agnostic nature, such an estimator needs to be driven by a consortium of operators, system and component suppliers.
Founded in February 2016, the Telecom Infra Project (TIP) is an engineering-focused initiative which is operator driven, but features collaboration across operators, suppliers, developers, integrators, and startups with the goal of disaggregating the traditional network deployment approach.
The group’s ultimate goal is to help provide better connectivity for communities all over the world as more people come on-line and demand more bandwidth-intensive experiences like video, virtual reality and augmented reality.
Within TIP, the Open Optical Packet Transport (OOPT) project group is chartered with unbundling monolithic packet-optical network technologies in order to unlock innovation and support new, more flexible connectivity paradigms.
The key to unbundling is the ability to accurately plan and predict the performance of optical line systems based on an accurate simulation of optical parameters.
Under that OOPT umbrella, the Physical Simulation Environment (PSE) working group set out to disrupt the planning landscape by providing an open source simulation model which can be used freely across multiple vendor implementations.
## TIP OOPT/PSE & PSE WG Charter
We believe that openly sharing ideas, specifications, and other intellectual property is the key to maximizing innovation and reducing complexity
TIP OOPT/PSE's goal is to build an end-to-end simulation environment which defines the network models of the optical device transfer functions and their parameters.
This environment will provide validation of the optical performance requirements for the TIP OLS building blocks.
- The model may be approximate or complete depending on the network complexity.
Each model shall be validated against the proposed network scenario.
- The environment must be able to process network models from multiple vendors, and also allow users to pick any implementation in an open source framework.
- The PSE will influence and benefit from the innovation of the DTC, API, and OLS working groups.
- The PSE represents a step along the journey towards multi-layer optimization.
License
-------
GNPy is distributed under a standard BSD 3-Clause License.
Running simulations with GNPy requires three pieces of information:
- the :ref:`network topology<concepts-topology>`, which describes how the network looks like, what are the fiber lengths, what amplifiers are used, etc.,
- the :ref:`equipment library<concepts-equipment>`, which holds machine-readable datasheets of the equipment used in the network,
- the :ref:`simulation options<concepts-simulation>` holding instructions about what to simulate, and under which conditions.
.._concepts-topology:
Network Topology
----------------
The *topology* acts as a "digital self" of the simulated network.
When given a network topology, GNPy can either run a specific simulation as-is, or it can *optimize* the topology before performing the simulation.
A network topology for GNPy is often a generic, mesh network.
This enables GNPy to take into consideration the current spectrum allocation as well as availability and resiliency considerations.
When the time comes to run a particular *propagation* of a signal and its impairments are computed, though, a linear path through the network is used.
For this purpose, the *path* through the network refers to an ordered, acyclic sequence of *nodes* that are processed.
This path is directional, and all "GNPy elements" along the path match the unidirectional part of a real-world network equipment.
..note::
In practical terms, an amplifier in GNPy refers to an entity with a single input port and a single output port.
A real-world inline EDFA enclosed in a single chassis will be therefore represented as two GNPy-level amplifiers.
The network topology contains not just the physical topology of the network, but also references to the :ref:`equipment library<concepts-equipment>` and a set of *operating parameters* for each entity.
These parameters include the **fiber length** of each fiber, the connector **attenutation losses**, or an amplifier's specific **gain setting**.
The topology is specified via :ref:`XLS files<excel>` or via :ref:`JSON<json>`.
.._complete-vs-incomplete:
Fully Specified vs. Partially Designed Networks
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Let's consider a simple triangle topology with three :abbr:`PoPs (Points of Presence)` covering three cities:
..graphviz::
:layout:neato
:align:center
graph "High-level topology with three PoPs" {
A -- B
B -- C
C -- A
}
In the real world, each city would probably host a ROADM and some transponders:
..graphviz::
:layout:neato
:align:center
graph "Simplified topology with transponders" {
"ROADM A" [pos="2,2!"]
"ROADM B" [pos="4,2!"]
"ROADM C" [pos="3,1!"]
"Transponder A" [shape=box, pos="0,2!"]
"Transponder B" [shape=box, pos="6,2!"]
"Transponder C" [shape=box, pos="3,0!"]
"ROADM A" -- "ROADM B"
"ROADM B" -- "ROADM C"
"ROADM C" -- "ROADM A"
"Transponder A" -- "ROADM A"
"Transponder B" -- "ROADM B"
"Transponder C" -- "ROADM C"
}
GNPy simulation works by propagating the optical signal over a sequence of elements, which means that one has to add some preamplifiers and boosters.
The amplifiers are, by definition, unidirectional, so the graph becomes quite complex:
.._topo-roadm-preamp-booster:
..graphviz::
:layout:neato
:align:center
digraph "Preamps and boosters are explicitly modeled in GNPy" {
In many regions, the ROADMs are not placed physically close to each other, so the long-haul fiber links (:abbr:`OMS (Optical Multiplex Section)`) are split into individual spans (:abbr:`OTS (Optical Transport Section)`) by in-line amplifiers, resulting in an even more complicated topology graphs:
..graphviz::
:layout:neato
:align:center
digraph "A subset of a real topology with inline amplifiers" {
"ROADM A" [pos="2,4!"]
"ROADM B" [pos="6,4!"]
"ROADM C" [pos="4,-3!"]
"Transponder A" [shape=box, pos="1,5!"]
"Transponder B" [shape=box, pos="7,5!"]
"Transponder C" [shape=box, pos="4,-4!"]
"Transponder A" -> "ROADM A"
"Transponder B" -> "ROADM B"
"Transponder C" -> "ROADM C"
"ROADM A" -> "Transponder A"
"ROADM B" -> "Transponder B"
"ROADM C" -> "Transponder C"
"Booster A C" [shape=triangle, orientation=-166, fixedsize=true, width=0.5, height=0.5, pos="2.2,3.2!", label=""]
"Preamp A C" [shape=triangle, orientation=0, fixedsize=true, width=0.5, height=0.5, pos="1.5,3.0!", label=""]
"ROADM A" -> "Booster A C"
"Preamp A C" -> "ROADM A"
"Booster A B" [shape=triangle, orientation=-90, fixedsize=true, width=0.5, height=0.5, pos="3,4.3!", label=""]
"Preamp A B" [shape=triangle, orientation=90, fixedsize=true, width=0.5, height=0.5, pos="3,3.6!", label=""]
"ROADM A" -> "Booster A B"
"Preamp A B" -> "ROADM A"
"Booster C B" [shape=triangle, orientation=-30, fixedsize=true, width=0.5, height=0.5, pos="4.7,-2.1!", label=""]
"Preamp C B" [shape=triangle, orientation=10, fixedsize=true, width=0.5, height=0.5, pos="5.4,-2.3!", label=""]
"ROADM C" -> "Booster C B"
"Preamp C B" -> "ROADM C"
"Booster C A" [shape=triangle, orientation=20, fixedsize=true, width=0.5, height=0.5, pos="2.6,-2.3!", label=""]
"Preamp C A" [shape=triangle, orientation=-30, fixedsize=true, width=0.5, height=0.5, pos="3.3,-2.1!", label=""]
"ROADM C" -> "Booster C A"
"Preamp C A" -> "ROADM C"
"Booster B A" [shape=triangle, orientation=90, fixedsize=true, width=0.5, height=0.5, pos="5,3.6!", label=""]
"Preamp B A" [shape=triangle, orientation=-90, fixedsize=true, width=0.5, height=0.5, pos="5,4.3!", label=""]
"ROADM B" -> "Booster B A"
"Preamp B A" -> "ROADM B"
"Booster B C" [shape=triangle, orientation=-180, fixedsize=true, width=0.5, height=0.5, pos="6.5,3.0!", label=""]
"Preamp B C" [shape=triangle, orientation=-20, fixedsize=true, width=0.5, height=0.5, pos="5.8,3.2!", label=""]
"ROADM B" -> "Booster B C"
"Preamp B C" -> "ROADM B"
"Inline A C 1" [shape=triangle, orientation=-166, fixedsize=true, width=0.5, pos="2.4,2.2!", label=" \N", color=red, fontcolor=red]
"Inline A C 2" [shape=triangle, orientation=-166, fixedsize=true, width=0.5, pos="2.6,1.2!", label=" \N", color=red, fontcolor=red]
"Inline A C 3" [shape=triangle, orientation=-166, fixedsize=true, width=0.5, pos="2.8,0.2!", label=" \N", color=red, fontcolor=red]
"Inline A C n" [shape=triangle, orientation=-166, fixedsize=true, width=0.5, pos="3.0,-1.1!", label=" \N", color=red, fontcolor=red]
"Booster A C" -> "Inline A C 1"
"Inline A C 1" -> "Inline A C 2"
"Inline A C 2" -> "Inline A C 3"
"Inline A C 3" -> "Inline A C n" [style=dotted]
"Inline A C n" -> "Preamp C A"
"Booster A B" -> "Preamp B A" [style=dotted]
"Booster C A" -> "Preamp A C" [style=dotted]
"Booster C B" -> "Preamp B C" [style=dotted]
"Booster B C" -> "Preamp C B" [style=dotted]
"Booster B A" -> "Preamp A B" [style=dotted]
}
In such networks, GNPy's autodesign features becomes very useful.
It is possible to connect ROADMs via "tentative links" which will be replaced by a sequence of actual fibers and specific amplifiers.
In other cases where the location of amplifier huts is already known, but the specific EDFA models have not yet been decided, one can put in amplifier placeholders and let GNPy assign the best amplifier.
.._concepts-equipment:
The Equipment Library
---------------------
In order to produce an accurate simulation, GNPy needs to know the physical properties of each entity which affects the optical signal.
Entries in the equipment library correspond to actual real-world, tangible entities.
Unlike a typical :abbr:`NMS (Network Management System)`, GNPy considers not just the active :abbr:`NEs (Network Elements)` such as amplifiers and :abbr:`ROADMs (Reconfigurable Optical Add/Drop Multiplexers)`, but also the passive ones, such as the optical fiber.
As the signal propagates through the network, the largest source of optical impairments is the noise introduced from amplifiers.
An accurate description of the :abbr:`EDFA (Erbium-Doped Fiber Amplifier)` and especially its noise characteristics is required.
GNPy describes this property in terms of the **Noise Figure (NF)** of an amplifier model as a function of its operating point.
The amplifiers compensate power losses induced on the signal in the optical fiber.
The linear losses, however, are just one phenomenon of a multitude of effects that affect the signals in a long fiber run.
While a more detailed description is available :ref:`in the literature<physical-model>`, for the purpose of the equipment library, the description of the *optical fiber* comprises its **linear attenutation coefficient**, a set of parameters for the **Raman effect**, optical **dispersion**, etc.
Signals are introduced into the network via *transponders*.
The set of parameters that are required describe the physical properties of each supported *mode* of the transponder, including its **symbol rate**, spectral **width**, etc.
In the junctions of the network, *ROADMs* are used for spectrum routing.
GNPy currently does not take into consideration the spectrum filtering penalties of the :abbr:`WSSes (Wavelength Selective Switches)`, but the equipment library nonetheless contains a list of required parameters, such as the attenuation options, so that the network can be properly simulated.
.._concepts-nf-model:
Amplifier Noise Figure Models
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
One of the key parameters of an amplifier is the method to use for computing the Noise Figure (NF).
GNPy supports several different noise models with varying level of accuracy.
When in doubt, contact your vendor's technical support and ask them to :ref:`contribute their equipment descriptions<extending-edfa>` to GNPy.
The most accurate noise models describe the resulting NF of an EDFA as a third-degree polynomial.
GNPy understands polynomials as a NF-yielding function of the :ref:`gain difference from the optimal gain<ext-nf-model-polynomial-NF>`, or as a function of the input power resulting in an incremental OSNR as used in :ref:`OpenROADM inline amplifiers<ext-nf-model-polynomial-OSNR-OpenROADM>` and :ref:`OpenROADM booster/preamps in the ROADMs<ext-nf-model-noise-mask-OpenROADM>`.
For scenarios where the vendor has not yet contributed an accurate EDFA NF description to GNPy, it is possible to approximate the characteristics via an operator-focused, min-max NF model.
.._nf-model-min-max-NF:
Min-max NF
**********
This is an operator-focused model where performance is defined by the *minimal* and *maximal NF*.
These are especially suited to model a dual-coil EDFA with a VOA in between.
In these amplifiers, the minimal NF is achieved when the EDFA operates at its maximal (and usually optimal, in terms of flatness) gain.
The worst (maximal) NF applies when the EDFA operates at its minimal gain.
This model is suitable for use when the vendor has not provided a more accurate performance description of the EDFA.
Raman Approximation
*******************
While GNPy is fully Raman-aware, under certain scenarios it is useful to be able to run a simulation without an accurate Raman description.
For these purposes the :ref:`polynomial NF<ext-nf-model-polynomial-NF>` model with :math:`\text{a} = \text{b} = \text{c} = 0`, and :math:`\text{d} = NF` can be used.
.._concepts-simulation:
Simulation
----------
When the network model has been instantiated and the physical properties and operational settings of the actual physical devices are known, GNPy can start simulating how the signal propagate through the optical fiber.
This set of input parameters include options such as the *spectrum allocation*, i.e., the number of channels and their spacing.
Various strategies for network optimization can be provided as well.
``gnpy-transmission-example`` gives the possibility to use an excel input file instead of a json file. The program then will generate the corresponding json file for you.
The file named 'meshTopologyExampleV2.xls' is an example.
In order to work the excel file MUST contain at least 2 sheets:
- Nodes
- Links
(In progress) The File MAY contain an additional sheet:
- Eqt
- Service
.._excel-nodes-sheet:
Nodes sheet
-----------
Nodes sheet contains nine columns.
Each line represents a 'node' (ROADM site or an in line amplifier site ILA or a Fused)::
City (Mandatory) ; State ; Country ; Region ; Latitude ; Longitude ; Type
-**City** is used for the name of a node of the graph. It accepts letters, numbers,underscore,dash, blank... (not exhaustive). The user may want to avoid commas for future CSV exports.
**City name MUST be unique**
-**Type** is not mandatory.
- If not filled, it will be interpreted as an 'ILA' site if node degree is 2 and as a ROADM otherwise.
- If filled, it can take "ROADM", "FUSED" or "ILA" values. If another string is used, it will be considered as not filled. FUSED means that ingress and egress spans will be fused together.
-*State*, *Country*, *Region* are not mandatory.
"Region" is a holdover from the CORONET topology reference file `CORONET_Global_Topology.xlsx <gnpy/example-data/CORONET_Global_Topology.xlsx>`_. CORONET separates its network into geographical regions (Europe, Asia, Continental US.) This information is not used by gnpy.
-*Longitude*, *Latitude* are not mandatory. If filled they should contain numbers.
-**Booster_restriction** and **Preamp_restriction** are not mandatory.
If used, they must contain one or several amplifier type_variety names separated by ' | '. This information is used to restrict types of amplifiers used in a ROADM node during autodesign. If a ROADM booster or preamp is already specified in the Eqpt sheet , the field is ignored. The field is also ignored if the node is not a ROADM node.
**There MUST NOT be empty line(s) between two nodes lines**
.._excel-links-sheet:
Links sheet
-----------
Links sheet must contain sixteen columns::
<-- east cable from a to z --> <-- west from z to -->
NodeA ; NodeZ ; Distance km ; Fiber type ; Lineic att ; Con_in ; Con_out ; PMD ; Cable Id ; Distance km ; Fiber type ; Lineic att ; Con_in ; Con_out ; PMD ; Cable Id
Links sheets MUST contain all links between nodes defined in Nodes sheet.
Each line represents a 'bidir link' between two nodes. The two directions are represented on a single line with "east cable from a to z" fields and "west from z to a" fields. Values for 'a to z' may be different from values from 'z to a'.
Since both direction of a bidir 'a-z' link are described on the same line (east and west), 'z to a' direction MUST NOT be repeated in a different line. If repeated, it will generate another parrallel bidir link between the same end nodes.
Parameters for "east cable from a to z" and "west from z to a" are detailed in 2x7 columns. If not filled, "west from z to a" is copied from "east cable from a to z".
They are the two endpoints of the link. They MUST contain a node name from the **City** names listed in Nodes sheet.
-**Distance km** is not mandatory.
It is the link length.
- If filled it MUST contain numbers. If empty it is replaced by a default "80" km value.
- If value is below 150 km, it is considered as a single (bidirectional) fiber span.
- If value is over 150 km the `gnpy-transmission-example`` program will automatically suppose that intermediate span description are required and will generate fiber spans elements with "_1","_2", ... trailing strings which are not visible in the json output. The reason for the splitting is that current edfa usually do not support large span loss. The current assumption is that links larger than 150km will require intermediate amplification. This value will be revisited when Raman amplification is added”
-**Fiber type** is not mandatory.
If filled it must contain types listed in `eqpt_config.json <gnpy/example-data/eqpt_config.json>`_ in "Fiber" list "type_variety".
If not filled it takes "SSMF" as default value.
-**Lineic att** is not mandatory.
It is the lineic attenuation expressed in dB/km.
If filled it must contain positive numbers.
If not filled it takes "0.2" dB/km value
-*Con_in*, *Con_out* are not mandatory.
They are the connector loss in dB at ingress and egress of the fiber spans.
If filled they must contain positive numbers.
If not filled they take "0.5" dB default value.
-*PMD* is not mandatory and and is not used yet.
It is the PMD value of the link in ps.
If filled they must contain positive numbers.
If not filled, it takes "0.1" ps value.
-*Cable Id* is not mandatory.
If filled they must contain strings with the same constraint as "City" names. Its value is used to differenate links having the same end points. In this case different Id should be used. Cable Ids are not meant to be unique in general.
(in progress)
.._excel-equipment-sheet:
Eqpt sheet
----------
The equipment sheet (named "Eqpt") is optional.
If provided, it specifies types of boosters and preamplifiers for all ROADM degrees of all ROADM nodes, and for all ILA nodes.
This sheet contains twelve columns::
<-- east cable from a to z --> <-- west from z to a -->
Node A ; Node Z ; amp type ; att_in ; amp gain ; tilt ; att_out ; delta_p ; amp type ; att_in ; amp gain ; tilt ; att_out ; delta_p
If the sheet is present, it MUST have as many lines as there are egress directions of ROADMs defined in Links Sheet, and all ILAs.
For example, consider the following list of links (A, B and C being a ROADM and amp# ILAs):
::
A - amp1
amp1 - amp2
Amp2 - B
A - amp3
amp3 - C
then Eqpt sheet should contain:
- one line for each ILAs: amp1, amp2, amp3
- one line for each one-degree ROADM (B and C in this example)
- two lines for each two-degree ROADM (just the ROADM A)
::
A - amp1
amp1 - amp2
Amp2 - B
A - amp3
amp3 - C
B - amp2
C - amp3
In case you already have filled Nodes and Links sheets `create_eqpt_sheet.py <gnpy/example-data/create_eqpt_sheet.py>`_ can be used to automatically create a template for the mandatory entries of the list.
This generates a text file meshTopologyExampleV2_eqt_sheet.txt whose content can be directly copied into the Eqt sheet of the excel file. The user then can fill the values in the rest of the columns.
-**Node A** is mandatory. It is the name of the node (as listed in Nodes sheet).
If Node A is a 'ROADM' (Type attribute in sheet Node), its number of occurence must be equal to its degree.
If Node A is an 'ILA' it should appear only once.
-**Node Z** is mandatory. It is the egress direction from the *Node A* site. Multiple Links between the same Node A and NodeZ is not supported.
-**amp type** is not mandatory.
If filled it must contain types listed in `eqpt_config.json <gnpy/example-data/eqpt_config.json>`_ in "Edfa" list "type_variety".
If not filled it takes "std_medium_gain" as default value.
If filled with fused, a fused element with 0.0 dB loss will be placed instead of an amplifier. This might be used to avoid booster amplifier on a ROADM direction.
-**amp_gain** is not mandatory. It is the value to be set on the amplifier (in dB).
If not filled, it will be determined with design rules in the convert.py file.
If filled, it must contain positive numbers.
-*att_in* and *att_out* are not mandatory and are not used yet. They are the value of the attenuator at input and output of amplifier (in dB).
If filled they must contain positive numbers.
-**tilt**, in dB, is not mandatory. It is the target gain tilt over the full amplfifier bandwidth and is defined with regard to wavelength, i.e. negative tilt means lower gain
for higher wavelengths (lower frequencies). If not filled, the default value is 0.
-**delta_p**, in dBm, is not mandatory. If filled it is used to set the output target power per channel at the output of the amplifier, if power_mode is True. The output power is then set to power_dbm + delta_power.
# to be completed #
(in progress)
.._excel-service-sheet:
Service sheet
-------------
Service sheet is optional. It lists the services for which path and feasibility must be computed with ``gnpy-path-request``.
Service sheet must contain 11 columns::
route id ; Source ; Destination ; TRX type ; Mode ; System: spacing ; System: input power (dBm) ; System: nb of channels ; routing: disjoint from ; routing: path ; routing: is loose?
-**route id** is mandatory. It must be unique. It is the identifier of the request. It can be an integer or a string (do not use blank or dash or coma)
-**Source** is mandatory. It is the name of the source node (as listed in Nodes sheet). Source MUST be a ROADM node. (TODO: relax this and accept trx entries)
-**Destination** is mandatory. It is the name of the destination node (as listed in Nodes sheet). Source MUST be a ROADM node. (TODO: relax this and accept trx entries)
-**TRX type** is mandatory. They are the variety type and selected mode of the transceiver to be used for the propagation simulation. These modes MUST be defined in the equipment library. The format of the mode is used as the name of the mode. (TODO: maybe add another mode id on Transceiver library ?). In particular the mode selection defines the channel baudrate to be used for the propagation simulation.
-**mode** is optional. If not specified, the program will search for the mode of the defined transponder with the highest baudrate fitting within the spacing value.
-**System: spacing** is mandatory. Spacing is the channel spacing defined in GHz difined for the feasibility propagation simulation, assuming system full load.
-**System: input power (dBm) ; System: nb of channels** are optional input defining the system parameters for the propagation simulation.
- input power is the channel optical input power in dBm
- nb of channels is the number of channels to be used for the simulation.
-**routing: disjoint from ; routing: path ; routing: is loose?** are optional.
- disjoint from: identifies the requests from which this request must be disjoint. If filled it must contain request ids separated by ' | '
- path: is the set of ROADM nodes that must be used by the path. It must contain the list of ROADM names that the path must cross. TODO : only ROADM nodes are accepted in this release. Relax this with any type of nodes. If filled it must contain ROADM ids separated by ' | '. Exact names are required.
- is loose? 'no' value means that the list of nodes should be strictly followed, while any other value means that the constraint may be relaxed if the node is not reachable.
-**path bandwidth** is mandatory. It is the amount of capacity required between source and destination in Gbit/s. Value should be positive (non zero). It is used to compute the amount of required spectrum for the service.
GNPy ships with an :ref:`equipment library<concepts-equipment>` containing machine-readable datasheets of networking equipment.
Vendors who are willing to contribute descriptions of their supported products are encouraged to `submit a patch <https://review.gerrithub.io/Documentation/intro-gerrit-walkthrough-github.html>`__.
This chapter discusses option for modeling performance of :ref:`EDFA amplifiers<extending-edfa>`, :ref:`Raman amplifiers<extending-raman>`, :ref:`transponders<extending-transponder>` and :ref:`ROADMs<extending-roadm>`.
.._extending-edfa:
EDFAs
-----
An accurate description of the :abbr:`EDFA (Erbium-Doped Fiber Amplifier)` and especially its noise characteristics is required.
GNPy describes this property in terms of the **Noise Figure (NF)** of an amplifier model as a function of its operating point.
GNPy supports several different :ref:`noise models<concepts-nf-model>`, and vendors are encouraged to pick one which describes performance of their equipment most accurately.
.._ext-nf-model-polynomial-NF:
Polynomial NF
*************
This model computes the NF as a function of the difference between the optimal gain and the current gain.
Unlike GNPy which simluates the preamplifier and the booster separately as two amplifiers for best accuracy, the OpenROADM specification mandates a certain performance level for a combination of these two amplifiers.
For the express path, the effective noise mask comprises the preamplifier and the booster.
When terminating a channel, the same effective noise mask is mandated for a combination of the preamplifier and the drop stage.
GNPy emulates this specification via two special NF models:
- The ``openroadm_preamp`` NF model for preamplifiers.
This NF model provides all of the linear impairments to the signal, including those which are incured by the booster in a real network.
- The ``openroadm_booster`` NF model is a special "zero noise" faux amplifier in place of the booster.
.._ext-nf-model-min-max-NF:
Min-max NF
**********
When the vendor prefers not to share the amplifier description in full detail, GNPy also supports describing the NF characteristics via the *minimal* and *maximal NF*.
This approximates a more accurate polynomial description reasonably well for some models of a dual-coil EDFA with a VOA in between.
In these amplifiers, the minimal NF is achieved when the EDFA operates at its maximal (and usually optimal, in terms of flatness) gain.
The worst (maximal) NF applies when the EDFA operates at the minimal gain.
.._ext-nf-model-dual-stage-amplifier:
Dual-stage
**********
Dual-stage amplifier combines two distinct amplifiers.
Vendors which provide an accurate description of their preamp and booster stages separately can use the dual-stage model for an aggregate description of the whole amplifier.
.._ext-nf-model-advanced:
Advanced Specification
**********************
The amplifier performance can be further described in terms of gain ripple, NF ripple, and the dynamic gain tilt.
When provided, the amplifier characteristic is fine-tuned as a function of carrier frequency.
.._extending-raman:
Raman Amplifiers
----------------
An accurate simulation of Raman amplification requires knowledge of:
- the *power* and *wavelength* of all Raman pumping lasers,
- the *direction*, whether it is co-propagating or counter-propagating,
- the Raman efficiency of the fiber,
- the fiber temperature.
Under certain scenarios it is useful to be able to run a simulation without an accurate Raman description.
For these purposes, it is possible to approximate a Raman amplifier via a fixed-gain EDFA with the :ref:`polynomial NF<ext-nf-model-polynomial-NF>` model using :math:`\text{a} = \text{b} = \text{c} = 0`, and a desired effective :math:`\text{d} = NF`.
This is also useful to quickly approximate a hybrid EDFA+Raman amplifier.
.._extending-transponder:
Transponders
------------
Since transponders are usually capable of operating in a variety of modes, these are described separately.
A *mode* usually refers to a particular performance point that is defined by a combination of the symbol rate, modulation format, and :abbr:`FEC (Forward Error Correction)`.
The following data are required for each mode:
``bit-rate``
Data bit rate, in :math:`\text{Gbits}\times s^{-1}`.
``baud-rate``
Symbol modulation rate, in :math:`\text{Gbaud}`.
``required-osnr``
Minimal allowed OSNR for the receiver.
``tx-osnr``
Initial OSNR at the transmitter's output.
``grid-spacing``
Minimal grid spacing, i.e., an effective channel spectral bandwidth.
In :math:`\text{Hz}`.
``tx-roll-off``
Roll-off parameter (:math:`\beta`) of the TX pulse shaping filter.
Describes the increase of the requires GSNR as the :abbr:`CD (Chromatic Dispersion)` deteriorates.
``dgd-penalty``
*Work-in-progress.*
Describes the increase of the requires GSNR as the :abbr:`DGD (Differential Group Delay)` deteriorates.
``pmd-penalty``
*Work-in-progress.*
Describes the increase of the requires GSNR as the :abbr:`PMD (Polarization Mode Dispersion)` deteriorates.
GNPy does not directly track the FEC performance, so the type of chosen FEC is likely indicated in the *name* of the selected transponder mode alone.
.._extending-roadm:
ROADMs
------
In a :abbr:`ROADM (Reconfigurable Add/Drop Multiplexer)`, GNPy simulates the impairments of the preamplifiers and boosters of line degrees :ref:`separately<topo-roadm-preamp-booster>`.
The set of parameters for each ROADM model therefore includes:
``add-drop-osnr``
OSNR penalty introduced by the Add and Drop stages of this ROADM type.
``target-channel-out-power``
Per-channel target TX power towards the egress amplifier.
Within GNPy, a ROADM is expected to attenuate any signal that enters the ROADM node to this level.
This can be overridden on a per-link in the network topology.
``pmd``
Polarization mode dispersion (PMD) penalty of the express path.
In :math:`\text{ps}`.
Provisions are in place to define the list of all allowed booster and preamplifier types.
This is useful for specifying constraints on what amplifier modules fit into ROADM chassis, and when using fully disaggregated ROADM topologies as well.
Gaussian Noise (GN) based modeling library for physical layer impairment evaluation in optical networks.
Summary
--------
We believe that openly sharing ideas, specifications, and other intellectual property is the key to maximizing innovation and reducing complexity
PSE WG Charter
--------------
- Goal is to build an end-to-end simulation environment which defines the network models of the optical device transfer functions and their parameters. This environment will provide validation of the optical performance requirements for the TIP OLS building blocks.
- The model may be approximate or complete depending on the network complexity. Each model shall be validated against the proposed network scenario.
- The environment must be able to process network models from multiple vendors, and also allow users to pick any implementation in an open source framework.
- The PSE will influence and benefit from the innovation of the DTC, API, and OLS working groups.
- The PSE represents a step along the journey towards multi-layer optimization.
Documentation
=============
The following pages are meant to describe specific implementation details and modeling assumptions behind GNpy.
`GNPy <http://github.com/telecominfraproject/gnpy>`_ is an open-source,
community-developed library for building route planning and optimization tools
in real-world mesh optical networks. It is based on the Gaussian Noise Model.
The Excel file will be processed into a JSON file with the same prefix.
Further details about the Excel data structure are available `in the documentation <docs/excel.rst>`__.
The main transmission example will calculate the average signal OSNR and SNR
across network elements (transceiver, ROADMs, fibers, and amplifiers)
between two transceivers selected by the user. Additional details are provided by doing ``gnpy-transmission-example -h``. (By default, for the CORONET Global
network, it will show the transmission of spectral information between Abilene and Albany)
This script calculates the average signal OSNR = |OSNR| and SNR = |SNR|.
|Pase| is the amplified spontaneous emission noise, and |Pnli| the non-linear
interference noise.
..|Pase|replace:: P\ :sub:`ase`
..|Pnli|replace:: P\ :sub:`nli`
Further Instructions for Use
----------------------------
Simulations are driven by a set of `JSON <docs/json.rst>`__ or `XLS <docs/excel.rst>`__ files.
The ``gnpy-transmission-example`` script propagates a spectrum of channels at 32 Gbaud, 50 GHz spacing and 0 dBm/channel.
Launch power can be overridden by using the ``--power`` argument.
Spectrum information is not yet parametrized but can be modified directly in the ``eqpt_config.json`` (via the ``SpectralInformation`` -SI- structure) to accommodate any baud rate or spacing.
The number of channel is computed based on ``spacing`` and ``f_min``, ``f_max`` values.
An experimental support for Raman amplification is available:
Configuration of Raman pumps (their frequencies, power and pumping direction) is done via the `RamanFiber element in the network topology <gnpy/example-data/raman_edfa_example_network.json>`_.
General numeric parameters for simulation control are provided in the `gnpy/example-data/sim_params.json <gnpy/example-data/sim_params.json>`_.
Use ``gnpy-path-request`` to request several paths at once:
This program operates on a network topology (`JSON <docs/json.rst>`__ or `Excel <docs/excel.rst>`__ format), processing the list of service requests (JSON or XLS again).
The service requests and reply formats are based on the `draft-ietf-teas-yang-path-computation-01 <https://tools.ietf.org/html/draft-ietf-teas-yang-path-computation-01>`__ with custom extensions (e.g., for transponder modes).
An example of the JSON input is provided in file `service-template.json`, while results are shown in `path_result_template.json`.
Important note: ``gnpy-path-request`` is not a network dimensionning tool: each service does not reserve spectrum, or occupy ressources such as transponders. It only computes path feasibility assuming the spectrum (between defined frequencies) is loaded with "nb of channels" spaced by "spacing" values as specified in the system parameters input in the service file, each cannel having the same characteristics in terms of baudrate, format,... as the service transponder. The transceiver element acts as a "logical starting/stopping point" for the spectral information propagation. At that point it is not meant to represent the capacity of add drop ports.
As a result transponder type is not part of the network info. it is related to the list of services requests.
The current version includes a spectrum assigment features that enables to compute a candidate spectrum assignment for each service based on a first fit policy. Spectrum is assigned based on service specified spacing value, path_bandwidth value and selected mode for the transceiver. This spectrum assignment includes a basic capacity planning capability so that the spectrum resource is limited by the frequency min and max values defined for the links. If the requested services reach the link spectrum capacity, additional services feasibility are computed but marked as blocked due to spectrum reason.
OpenROADM networks can be simulated via ``gnpy/example-data/eqpt_config_openroadm_*.json`` -- see ``gnpy/example-data/Sweden_OpenROADM*_example_network.json`` as an example.
GNPy uses a set of JSON files for modeling the network.
Some data (such as network topology or the service requests) can be also passed via :ref:`XLS files<excel-service-sheet>`.
Equipment Library
-----------------
Design and transmission parameters are defined in a dedicated json file.
By default, this information is read from `gnpy/example-data/eqpt_config.json <https://github.com/Telecominfraproject/oopt-gnpy/blob/master/gnpy/example-data/eqpt_config.json>`_.
This file defines the equipment libraries that can be customized (EDFAs, fibers, and transceivers).
It also defines the simulation parameters (spans, ROADMs, and the spectral information to transmit.)
EDFA
~~~~
The EDFA equipment library is a list of supported amplifiers. New amplifiers
can be added and existing ones removed. Three different noise models are available:
1.``'type_def': 'variable_gain'`` is a simplified model simulating a 2-coil EDFA with internal, input and output VOAs.
The NF vs gain response is calculated accordingly based on the input parameters: ``nf_min``, ``nf_max``, and ``gain_flatmax``.
It is not a simple interpolation but a 2-stage NF calculation.
2.``'type_def': 'fixed_gain'`` is a fixed gain model.
`NF == Cte == nf0` if `gain_min < gain < gain_flatmax`
3.``'type_def': 'openroadm'`` models the incremental OSNR contribution as a function of input power.
It is suitable for inline amplifiers that conform to the OpenROADM specification.
The input parameters are coefficients of the :ref:`third-degree polynomial<ext-nf-model-polynomial-OSNR-OpenROADM>`.
4.``'type_def': 'openroadm_preamp'`` and ``openroadm_booster`` approximate the :ref:`preamp and booster within an OpenROADM network<ext-nf-model-noise-mask-OpenROADM>`.
No extra parameters specific to the NF model are accepted.
5.``'type_def': 'advanced_model'`` is an advanced model.
A detailed JSON configuration file is required (by default `gnpy/example-data/std_medium_gain_advanced_config.json <https://github.com/Telecominfraproject/oopt-gnpy/blob/master/gnpy/example-data/std_medium_gain_advanced_config.json>`_).
It uses a 3rd order polynomial where NF = f(gain), NF_ripple = f(frequency), gain_ripple = f(frequency), N-array dgt = f(frequency).
Compared to the previous models, NF ripple and gain ripple are modelled.
The following options are still defined in ``eqpt_config.json`` for legacy reasons, but
they do not correspond to tangible network devices.
Auto-design automatically creates EDFA amplifier network elements when they are missing, after a fiber, or between a ROADM and a fiber.
This auto-design functionality can be manually and locally deactivated by introducing a ``Fused`` network element after a ``Fiber`` or a ``Roadm`` that doesn't need amplification.
The amplifier is chosen in the EDFA list of the equipment library based on gain, power, and NF criteria.
Only the EDFA that are marked ``'allowed_for_design': true`` are considered.
For amplifiers defined in the topology JSON input but whose ``gain = 0`` (placeholder), auto-design will set its gain automatically: see ``power_mode`` in the ``Spans`` library to find out how the gain is calculated.
Span
~~~~
Span configuration is not a list (which may change in later releases) and the user can only modify the value of existing parameters:
The user can only modify the value of existing parameters.
It defines a spectrum of N identical carriers.
While the code libraries allow for different carriers and power levels, the current user parametrization only allows one carrier type and one power/channel definition.
To properly estimate :math:`P_{\text{ch}}` and :math:`P_{\text{ASE}}`
the transmitted power at the beginning of the considered route must be
known, and losses and amplifiers gain and noise figure, including their
@@ -62,8 +63,10 @@ models have been proposed and validated in the technical literature
The decision about which model to test within the PSE activities was
driven by requirements of the entire PSE framework:
i. the model must be *local*, i.e., related individually to each network element (i.e. fiber span) generating NLI, independently of preceding and subsequent elements; and
ii. the related computational time must be compatible with interactive operations.
i. the model must be *local*, i.e., related individually to each network
element (i.e. fiber span) generating NLI, independently of preceding and
subsequent elements; and ii. the related computational time must be compatible
with interactive operations.
So, the choice fell on the Gaussian Noise
(GN) model with incoherent accumulation of NLI over fiber spans
@@ -79,46 +82,67 @@ for fiber types with chromatic dispersion roughly larger than 4
ps/nm/km, the analytical approximation ensures an excellent accuracy
with a computational time compatible with real-time operations.
The Gaussian Noise Model to evaluate the NLI
--------------------------------------------
As previously stated, fiber propagation of multilevel modulation formats relying on the polarization-division-multiplexing
generates impairments that can be summarized as a disturbance called nonlinear interference (NLI),
when exploiting a DSP-based coherent receiver, as in all state-of-the-art equipment.
From a practical point of view, the NLI can be modeled as an additive
Gaussian random process added by each fiber span, and whose strength depends on the cube of the input power spectral density and
on the fiber-span parameters.
Since the introduction in the market in 2007 of the first transponder based on such a transmission technique, the scientific
community has intensively worked to define the propagation behavior of such a trasnmission technique.
First, the role of in-line chromatic dispersion compensation has been investigated, deducing that besides being
not essential, it is indeed detrimental for performances :cite:`curri_dispersion_2008`.
Then, it has been observed that the fiber propagation impairments are practically summarized by the sole NLI, being all the other
phenomena compensated for by the blind equalizer implemented in the receiver DSP :cite:`carena_statistical_2010`.
Once these assessments have been accepted by the community, several prestigious research groups have started to work
on deriving analytical models able to estimating the NLI accumulation, and consequentially the generalized SNR that sets the BER,
according to the transponder BER vs. SNR performance.
Many models delivering different levels of accuracy have been developed and validated. As previously clarified, for the purposes
of the PSE framework, the GN-model with incoherent accumulation of NLI over fiber spans has been selected as adequate.
The reason for such a choice is first such a model being a "local" model, so related to each fiber spans, independently of
the preceding and succeeding network elements. The other model characteristic driving the choice is
the availability of a closed form for the model, so permitting a real-time evaluation, as required by the PSE framework.
For a detailed derivation of the model, please refer to :cite:`poggiolini_analytical_2011`, while a qualitative description
can be summarized as in the following.
The GN-model assumes that the channel comb propagating in the fiber is well approximated by unpolarized spectrally shaped
Gaussian noise. In such a scenario, supposing to rely - as in state-of-the-art equipment - on a receiver entirely compensating for linear propagation effects, propagation in the fiber only excites the four-wave mixing (FWM) process among the continuity of
the tones occupying the bandwidth. Such a FWM generates an unpolarized complex Gaussian disturbance in each spectral slot
that can be easily evaluated extending the FWM theory from a set of discrete tones - the standard FWM theory introduced back in the 90s by Inoue :cite:`Innoue-FWM`- to a continuity of tones, possibly spectrally shaped.
Signals propagating in the fiber are not equivalent to Gaussian noise, but thanks to the absence of in-line compensation for choromatic dispersion,
the become so, over short distances.
So, the Gaussian noise model with incoherent accumulation of NLI has estensively proved to be a quick yet accurate and conservative tool
to estimate propagation impairments of fiber propagation.
Note that the GN-model has not been derived with the aim of an *exact* performance estimation, but to pursue a conservative performance prediction. So, considering these characteristics, and the fact that the NLI is always a secondary effect with respect to the ASE noise accumulation, and - most importantly - that typically linear propagation parameters (losses, gains and noise figures) are known within
a variation range, a QoT estimator based on the GN model is adequate to deliver performance predictions in terms of a reasonable SNR range, rather than an exact value.
As final remark, it must be clarified that the GN-model is adequate to be used when relying on a relatively narrow bandwidth up to few THz. When exceeding such a bandwidth occupation, the GN-model must be generalized introducing the interaction with the Stimulated
Raman Scattering in order to give a proper estimation for all channels :cite:`cantono2018modeling`.
This will be the main upgrade required within the PSE framework.
As previously stated, fiber propagation of multilevel modulation formats
relying on the polarization-division-multiplexing generates impairments that
can be summarized as a disturbance called nonlinear interference (NLI), when
exploiting a DSP-based coherent receiver, as in all state-of-the-art equipment.
From a practical point of view, the NLI can be modeled as an additive Gaussian
random process added by each fiber span, and whose strength depends on the cube
of the input power spectral density and on the fiber-span parameters.
Since the introduction in the market in 2007 of the first transponder based on
such a transmission technique, the scientific community has intensively worked
to define the propagation behavior of such a trasnmission technique. First,
the role of in-line chromatic dispersion compensation has been investigated,
deducing that besides being not essential, it is indeed detrimental for
performances :cite:`curri_dispersion_2008`. Then, it has been observed that
the fiber propagation impairments are practically summarized by the sole NLI,
being all the other phenomena compensated for by the blind equalizer
implemented in the receiver DSP :cite:`carena_statistical_2010`. Once these
assessments have been accepted by the community, several prestigious research
groups have started to work on deriving analytical models able to estimating
the NLI accumulation, and consequentially the generalized SNR that sets the
BER, according to the transponder BER vs. SNR performance. Many models
delivering different levels of accuracy have been developed and validated. As
previously clarified, for the purposes of the PSE framework, the GN-model with
incoherent accumulation of NLI over fiber spans has been selected as adequate.
The reason for such a choice is first such a model being a "local" model, so
related to each fiber spans, independently of the preceding and succeeding
network elements. The other model characteristic driving the choice is the
availability of a closed form for the model, so permitting a real-time
evaluation, as required by the PSE framework. For a detailed derivation of the
model, please refer to :cite:`poggiolini_analytical_2011`, while a qualitative
description can be summarized as in the following. The GN-model assumes that
the channel comb propagating in the fiber is well approximated by unpolarized
spectrally shaped Gaussian noise. In such a scenario, supposing to rely - as in
state-of-the-art equipment - on a receiver entirely compensating for linear
propagation effects, propagation in the fiber only excites the four-wave mixing
(FWM) process among the continuity of the tones occupying the bandwidth. Such a
FWM generates an unpolarized complex Gaussian disturbance in each spectral slot
that can be easily evaluated extending the FWM theory from a set of discrete
tones - the standard FWM theory introduced back in the 90s by Inoue
:cite:`Innoue-FWM`- to a continuity of tones, possibly spectrally shaped.
Signals propagating in the fiber are not equivalent to Gaussian noise, but
thanks to the absence of in-line compensation for choromatic dispersion, the
become so, over short distances. So, the Gaussian noise model with incoherent
accumulation of NLI has estensively proved to be a quick yet accurate and
conservative tool to estimate propagation impairments of fiber propagation.
Note that the GN-model has not been derived with the aim of an *exact*
performance estimation, but to pursue a conservative performance prediction.
So, considering these characteristics, and the fact that the NLI is always a
secondary effect with respect to the ASE noise accumulation, and - most
importantly - that typically linear propagation parameters (losses, gains and
noise figures) are known within a variation range, a QoT estimator based on the
GN model is adequate to deliver performance predictions in terms of a
reasonable SNR range, rather than an exact value. As final remark, it must be
clarified that the GN-model is adequate to be used when relying on a relatively
narrow bandwidth up to few THz. When exceeding such a bandwidth occupation, the
GN-model must be generalized introducing the interaction with the Stimulated
Raman Scattering in order to give a proper estimation for all channels
:cite:`cantono2018modeling`. This will be the main upgrade required within the
GNPy is an open-source, community-developed library for building route planning and optimization tools in real-world mesh optical networks. It is based on the Gaussian Noise Model.
Signal propagation is implemented in :py:mod:`.core`.
Path finding and spectrum assignment is in :py:mod:`.topology`.
Various tools and auxiliary code, including the JSON I/O handling, is in
Equipment description defines equipment types and parameters.
It takes place in the default **eqpt_config.json** file.
By default **gnpy-transmission-example** uses **eqpt_config.json** file and that
can be changed with **-e** or **--equipment** command line parameter.
2. Amplifier parameters and subtypes
#######################################
Several amplifiers can be used by GNpy, so they are defined as an array of equipment parameters in **eqpt_config.json** file.
-*"type_variety"*:
Each amplifier is identified by its unique *"type_variety"*, which is used in the topology files input to reference a specific amplifier. It is a user free defined id.
For each amplifier *type_variety*, specific parameters are describing its attributes and performance:
-*"type_def"*:
Sets the amplifier model that the simulation will use to calculate the ase noise contribution. 5 models are defined with reserved words:
-*"advanced_model"*
-*"variable_gain"*
-*"fixed_gain"*
-*"dual_stage"*
-*"openroadm"*
*see next section for a full description of these models*
-*"advanced_config_from_json"*:
**This parameter is only applicable to the _"advanced_model"_ model**
json file name describing:
- nf_fit_coeff
- f_min/max
- gain_ripple
- nf_ripple
- dgt
*see next section for a full description*
-*"gain_flatmax"*:
amplifier maximum gain in dB before its extended gain range: flat or nominal tilt output.
If gain > gain_flatmax, the amplifier will tilt, based on its dgt function
If gain > gain_flatmax + target_extended_gain, the amplifier output power is reduced to not exceed the extended gain range.
-*"gain_min"*:
amplifier minimum gain in dB.
If gain < gain_min, the amplifier input is automatically padded, which results in
NF += gain_min - gain
-*"p_max"*:
amplifier max output power, full load
Total signal output power will not be allowed beyond this value
-*"nf_min/max"*:
**These parameters are only applicable to the _"variable_gain"_ model**
min & max NF values in dB
NF_min is the amplifier NF @ gain_max
NF_max is the amplifier NF @ gain_min
-*"nf_coef"*:
**This parameter is only applicable to the *"openroadm"* model**
[a, b, c, d] 3rd order polynomial coefficients list to define the incremental OSNR vs Pin
Incremental OSNR is the amplifier OSNR contribution
Pin is the amplifier channel input power defined in a 50GHz bandwidth
Incremental OSNR = a*Pin³ + b*Pin² + c*Pin + d
-*"preamp_variety"*:
**This parameter is only applicable to the _"dual_stage"_ model**
1st stage type_variety
-*"booster_variety"*:
**This parameter is only applicable to the *"dual_stage"* model**
2nd stage type_variety
-*"out_voa_auto"*: true/false
**power_mode only**
**This parameter is only applicable to the *"advanced_model"* and *"variable_gain"* models**
If "out_voa_auto": true, auto_design will chose the output_VOA value that maximizes the amplifier gain within its power capability and therefore minimizes its NF.
-*"allowed_for_design"*: true/false
**auto_design only**
Tells auto_design if this amplifier can be picked for the design (deactivates unwanted amplifiers)
It does not prevent the use of an amplifier if it is placed in the topology input.
..code-block::json
{"Edfa":[{
"type_variety":"std_medium_gain",
"type_def":"variable_gain",
"gain_flatmax":26,
"gain_min":15,
"p_max":23,
"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":23,
"nf_min":6.5,
"nf_max":11,
"out_voa_auto":false,
"allowed_for_design":true
}
]}
3. Amplifier models
#######################################
In an opensource and multi-vendor environnement, it is needed to support different use cases and context. Therefore several models are supported for amplifiers.
5 types of EDFA definition are possible and referenced by the *"type_def"* parameter with the following reserved words:
-*"advanced_model"*
This model is refered as a whitebox model because of the detailed level of knowledge that is required. The amplifier NF model and ripple definition are described by a json file referenced with *"advanced_config_from_json"*: json filename. This json file contains:
- nf_fit_coeff: [a,b,c,d]
3rd order polynomial NF = f(-dg) coeficients list
dg = gain - gain_max
- f_min/max: amplifier frequency range in Hz
- gain_ripple : [...]
amplifier gain ripple excursion comb list in dB across the frequency range.
- nf_ripple : [...]
amplifier nf ripple excursion comb list in dB across the frequency range.
- dgt : [...]
amplifier dynamic gain tilt comb list across the frequency range.
*See next section for the generation of this json file*
This model is refered as an operator model because a lower level of knowledge is required. A full polynomial description of the NF cross the gain range is not required. Instead, NF_min and NF_max values are required and used by the code to model a dual stage amplifier with an internal mid stage VOA. NF_min and NF_max values are typically available from equipment suppliers data-sheet.
There is a default JSON file ”default_edfa_config.json”* to enforce 0 tilt and ripple values because GNpy core algorithm is a multi-carrier propogation.
- gain_ripple =[0,...,0]
- nf_ripple = [0,...,0]
- dgt = [...] generic dgt comb
..code-block::json-object
"Edfa":[{
"type_variety": "std_medium_gain",
"type_def": "variable_gain",
"gain_flatmax": 26,
"gain_min": 15,
"p_max": 23,
"nf_min": 6,
"nf_max": 10,
"out_voa_auto": false,
"allowed_for_design": true
}
]
-*"fixed_gain"*
This model is also an operator model with a single NF value that emulates basic single coil amplifiers without internal VOA.
if gain_min < gain < gain_max, NF == nf0
if gain < gain_min, the amplifier input is automatically padded, which results in
NF += gain_min - gain
..code-block::json-object
"Edfa":[{
"type_variety": "std_fixed_gain",
"type_def": "fixed_gain",
"gain_flatmax": 21,
"gain_min": 20,
"p_max": 21,
"nf0": 5.5,
"allowed_for_design": false
}
]
-*"openroadm"*
This model is a black box model replicating OpenRoadm MSA spec for ILA.
..code-block::json-object
"Edfa":[{
"type_variety": "openroadm_ila_low_noise",
"type_def": "openroadm",
"gain_flatmax": 27,
"gain_min": 12,
"p_max": 22,
"nf_coef": [-8.104e-4,-6.221e-2,-5.889e-1,37.62],
"allowed_for_design": false
}
]
-*"dual_stage"*
This model allows the cascade (pre-defined combination) of any 2 amplifiers already described in the eqpt_config.json library.
- preamp_variety defines the 1st stge type variety
- booster variety defines the 2nd stage type variety
Both preamp and booster variety must exist in the eqpt libray
The resulting NF is the sum of the 2 amplifiers
The preamp is operated to its maximum gain
- gain_min indicates to auto_design when this dual_stage should be used
But unlike other models the 1st stage input will not be padded: it is always operated to its maximu gain and min NF. Therefore if gain adaptation and padding is needed it will be performed by the 2nd stage.
..code-block::json
{
"type_variety":"medium+low_gain",
"type_def":"dual_stage",
"gain_min":25,
"preamp_variety":"std_medium_gain",
"booster_variety":"std_low_gain",
"allowed_for_design":true
}
4. advanced_config_from_json
#######################################
The build_oa_json.py library in ``gnpy/example-data/edfa_model/`` can be used to build the json file required for the amplifier advanced_model type_def:
Update an existing json file with all the 96ch txt files for a given amplifier type
amplifier type 'OA_type1' is hard coded but can be modified and other types added
returns an updated amplifier json file: output_json_file_name = 'edfa_config.json'
amplifier file names
Convert a set of amplifier files + input json definiton file into a valid edfa_json_file:
nf_fit_coeff: NF 3rd order polynomial coefficients txt file
nf = f(dg) with dg = gain_operational - gain_max
nf_ripple: NF ripple excursion txt file
gain_ripple: gain ripple txt file
dgt: dynamic gain txt file
input json file in argument (defult = 'OA.json')
the json input file should have the following fields:
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.