This fixes#421
As a first step PDL is specified in the eqpt library for ROADMs only.
In a later step, PDL (as well as PMD) should be specified also for amps
and possibly for fibers. PDL values from the OpenROADM MSA for ROADMs
are included in the corresponding eqpt files.
The acculumation rule for PDL is the same as for PMD as shown in:
"The statistics of polarization-dependent loss in optical communication
systems", A. Mecozzi and M. Shtaif, IEEE Photon. Technol. Lett., vol.
14, pp. 313-315, Mar 2002.
PDL penalty is specified and calculated in the same way as for CD and
PMD, i.e. linear interpolation between impairment_value/penalty_value
pairs. This patch includes penalty specification for OpenROADM trx
modes according to the MSA.
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Change-Id: Ib0ab383bcaee7d7523ffc3fa9a949d76c8c86ff7
The penalties are calculated and presented separately from the GSNR.
They are also taken into account when optimizing trx mode and verifying
path feasibility in path_requests_run processing.
Penalties are specified in the eqpt_config file as part of trx modes.
This patch includes specifications for OpenROADM trx modes.
Penalties are defined by a list of
impairment_value/penalty_value pairs, for example:
"penalties": [
{
"chromatic_dispersion": 4e3,
"penalty_value": 0
},
{
"chromatic_dispersion": 18e3,
"penalty_value": 0.5
},
{
"pmd": 10,
"penalty_value": 0
},
{
"pmd": 30,
"penalty_value": 0.5
}
]
- Between given pairs, penalty is linearly interpolated.
- Below min and above max up_to_boundary, transmission is considered
not feasible.
This is in line with how penalties are specified in OpenROADM and
compatible with specifications from most other organizations and
vendors.
The implementation makes it easy to add other penalties (PDL, etc.) in
the future.
The input format is flexible such that it can easily be extended to
accept combined penalty entries (e.g. CD and PMD) in the future.
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Change-Id: I3745eba48ca60c0e4c904839a99b59104eae9216
In this change, the RamanSolver is completely restructured in order to obtain a simplified and faster solution of the Raman equation. Additionally, the inter-channel Raman effect can be evaluated also in the standard fiber, when no Raman pumping is present. The same is true for the GGN model.
The Raman pump parameter pumps_loss_coef has been removed as it was not used. The loss coefficient value evaluated at the pump frequency can be included within the fiber loss_coef parameter.
This change induces variations in some expected test results as the Raman profile solution is calculated by a completely distinct algorithm. Nevertheless, these variations are negligible being lower than 0.1dB.
Change-Id: Iaa40fbb23c555571497e1ff3bf19dbcbfcadf96b
Modification of the Fiber and the NliSolver in order to properly propagate the new definition of the spectral information taking advantage of the numpy array structures.
In the previous version, the propagation of the spectral information was implemented by means of for cycles over each channel, in turn.
In this change the propagation is applied directly on the newly defined spectral information attributes as numpy arrays.
Additional changes:
- Simplification of the FiberParameters and the NliParameters;
- Previous issues regarding the loss_coef definition along the frequency are solved;
- New test in test_science_utils.py verifing that the fiber propagation provides the correct values in case of a few cases of flex grid spectra.
Change-Id: Id71f36effba35fc3ed4bbf2481a3cf6566ccb51c
Squeeze function has been replaced by asarray. Using 'get' function
instead of if condition for the dictionaries. Frequency reference
derived from wavelength reference of 1550 nm.
Change-Id: I815ad8591c9e238f3fc9322ca0946ea469ff448f
This fixes#420.
In order to be consistent with the OpenROADM MSA, the input power per
channel used for calculating incremental OSNR and NF should be scaled to
50 GHz slot width.
Signed-off-by: Jonas Mårtensson <jonas.martensson@ri.se>
Change-Id: I64ca3e4cad6399f308827f4161d7c6b89be9d2ca
On certain values of loss_coef, the computation loss_coef * 1e-3 * 1e3
results in x.0000000000000000y values:
eg if 0.21 is provided in the topology file, then parameters.FiberParams
changes this to _loss_coef = 0.00021
and elements.Fiber.to_json prints 0.21000000000000002
This is a normal floating point behaviour, but is rather confusing.
In order to remove this unwanted decimal, I propose to round the printings
in to_json
https://docs.python.org/3/tutorial/floatingpoint.html
The change also add this round for gain, because in power mode
the gain is computed based on loss and loss may have this floating value.
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: Ib3287a794e7da985eabf0af914c0e1ef4914e857
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)
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
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
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 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 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
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
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>
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>
- 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
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
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>
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>
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>
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.
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.
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.