The code look as if it was trying to prevent direct instantiation of the
SimParams class. However, instance *creation* in Python is actually
handled via `__new__` which was not overridden. In addition, the
`get()` accessor was invoking `SimParams.__new__()` directly, which
meant that this class was instantiated each time it was needed.
Let's cut the boilerplate by getting rid of the extra step and just use
the regular constructor.
This patch doesn't change anything in actual observable behavior. I
still do not like this implicit singleton design pattern, but nuking
that will have to wait until some other time.
Change-Id: I3ca81bcd0042e91b4f6b7581879922611f18febe
Constant power per slot_width uses the slot width instead of
baud rate compared to PSD.
This is the equalization used in OpenROADM
add tests for constant power per slot width equalization
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: Ie350e4c15cb6b54c15e418556fe33e72486cb134
On a ROADM, the code would previously set the same per-carrier power
regardless of the channel spectrum width. With this patch, carriers are
equalized either by their:
- absolute power (same as before),
- power spectral density (PSD).
Also, it's possible to apply a per-channel power offset (in dB) which
will be applied to a specified channel on top of the selected
power-level or PSD strategy. The same offset can be also selected
through the `--spectrum` option via the `default_pdb` parameter.
The equalization policy can be set via the ROADM model (in the equipment
config) as well as on a per-instance basis.
The PSD is defined as the absolute power over a spectral bandwidth,
where the spectral bandwidth corresponds to the actual spectrum
occupation (without any applicable guard bands), as approximated by the
symbol rate. PSD is specified in mW/GHz. As an example, for a 32 GBaud
signal at 0.01 mW, the PSD is 0.01/32 = 3.125e-4 mW/GHz.
This has some implications on the power sweep and ROADM behavior. Same
as previously (with absolute power targets), the ROADM design determines
the power set points. Target power is usually the best (highest) power
that can be supported by the ROADMs, especially the Add/Drop and express
stages' losses, with the goal to maximize the power at the booster's
input. As such, the `--power` option (or the power sweep) doesn't
manipulate with ROADM's target output power, but only with the output
power of the amplifiers. With PSD equalization, the `--power` option is
interpreted as the power of the reference channel defined in equipment
config's `SI` container, and its PSD is used for propagation. Power
sweep is interpreted in the same way, e.g.:
"SI":[{
"f_min": 191.3e12,
"baud_rate": 32e9,
"f_max":195.1e12,
"spacing": 50e9,
"power_dbm": 0,
"power_range_db": [-1,1,1],
"roll_off": 0.15,
"tx_osnr": 40,
"sys_margins": 2
}],
...and with the PSD equalization in a ROADM:
{
"uid": "roadm A",
"type": "Roadm",
"params": {
"target_psd_out_mWperGHz": 3.125e-4,
}
},
{
"uid": "edfa in roadm A to toto",
"type": "Edfa",
"type_variety": "standard_medium_gain",
"operational": {
"gain_target": 22,
"delta_p": 2,
"tilt_target": 0.0,
"out_voa": 0
}
},
then we use the power steps of the power_range_db to compute resulting
powers of each carrier out of the booster amp:
power_db = psd2powerdbm(target_psd_out_mWperGHz, baud_rate)
sweep = power_db + delta_power for delta_power in power_range_db
Assuming one 32Gbaud and one 64Gbaud carriers:
32 Gbaud 64 Gbaud
roadmA out power
(sig+ase+nli) -20dBm -17dBm
EDFA out power
range[
-1 1dBm 4dBm
0 2dBm 5dBm
1 3dBm 6dBm
]
Design case:
Design is performed based on the reference channel set defined in SI
in equipment config (independantly of equalization process):
"SI":[{
"f_min": 191.3e12,
"baud_rate": 32e9,
"f_max":195.1e12,
"spacing": 50e9,
"power_dbm": -1,
"power_range_db": [0,0,1],
"roll_off": 0.15,
"tx_osnr": 40,
"sys_margins": 2
}],
`delta_p` values of amps refer to this reference channel, but are applicable
for any baudrate during propagation, e.g.:
{
"uid": "roadm A",
"type": "Roadm",
"params": {
"target_psd_out_mWperGHz": 2.717e-4,
}
},
{
"uid": "edfa in roadm A to toto",
"type": "Edfa",
"type_variety": "standard_medium_gain",
"operational": {
"gain_target": 22,
"delta_p": 2,
"tilt_target": 0.0,
"out_voa": 0
}
},
Then the output power for a 64 Gbaud carrier will be +4 =
= lin2db(db2lin(power_dbm + delta_p)/32e9 * 64e9)
= lin2db(db2lin(power_dbm + delta_p) * 2)
= powerdbm + delta + 3 = 4 dBm
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
Change-Id: I28bcfeb72b0e74380b087762bb92ba5d39219eb3
The lumped losses are used in the computation of the loss/gain profile
through the fiber whether the Raman effect is considered or not. The
computed power profile is used to calculate the related NLI impairment.
Using the 'gn_model_analytic' method, the lumped losses are taken into
account as the contribution of an additional total loss at the end of
the fiber span. In case the 'ggn_spectrally_separated' is selected, the
method uses the computed power profile according to the specified z and
frequency arrays. The lumped losses are so considered within the NLI
power evolution along the fiber.
Change-Id: I73a6baa321aca4d041cafa180f47afed824ce267
Signed-off-by: Jan Kundrát <jan.kundrat@telecominfraproject.com>
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
Gamma and the raman efficiency are calculated using the effective area if not provided. Both these parameters are managed as optional in json_io.py for backward compatibility.
Change-Id: Id7f1403ae33aeeff7ec464e4c7f9c1dcfa946827
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 change siplifies the structure of the simulation parameters,
removing the gnpy.science_utils.simulation layer, provides some
documentation of the parameters and define a mock fixture for testing in
safe mode.
Jan: while I'm not thrilled by this concept of hidden global state, we
agreed to let it in as a temporary measure (so as not to hold merging of
Andrea's flexgrid/multirate patches). I've refactored this to a more
pytest-ish way of dealing with fixtures. In the end, it was also
possible to remove the MockSimParams class because it was not adding any
features on top of what SimParams can do already (and to what was
tested).
Change-Id: If5ef341e0585586127d5dae3f39dca2c232236f1
Signed-off-by: Jan Kundrát <jan.kundrat@telecominfraproject.com>
Getter and setter removed from the class PumpParams. The propagation
direction is cast to lower case string within the PumpParams
constructor.
Change-Id: Ice28affe8bcffbf8adcebb5cb096be8100081511
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
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
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