Merge branch 'develop'

This commit is contained in:
Jan Kundrát
2019-05-17 21:25:08 +02:00
44 changed files with 203034 additions and 4467 deletions

View File

@@ -21,34 +21,9 @@ Documentation: https://gnpy.readthedocs.io
Branches and Tagged Releases
----------------------------
- the `master <https://github.com/Telecominfraproject/oopt-gnpy/tree/master>`_ branch contains stable, validated code. It is updated from develop on a release schedule determined by the OOPT-PSE Working Group. For more information about the validation process, see: https://github.com/Telecominfraproject/oopt-gnpy/wiki/Testing-for-Quality
- all releases are `available via GitHub <https://github.com/Telecominfraproject/oopt-gnpy/releases>`_
- the `master <https://github.com/Telecominfraproject/oopt-gnpy/tree/master>`_ branch contains stable, `validated code <https://github.com/Telecominfraproject/oopt-gnpy/wiki/Testing-for-Quality>`_. It is updated from develop on a release schedule determined by the OOPT-PSE Working Group.
- the `develop <https://github.com/Telecominfraproject/oopt-gnpy/tree/develop>`_ branch contains the latest code under active development, which may not be fully validated and tested.
- the `phase-1 <https://github.com/Telecominfraproject/oopt-gnpy/tree/phase-1>`_ branch contains code for Phase I of the OOPT-PSE efforts and is kept only for reference. This branch is unmaintained.
A brief outline of major (tagged) `gnpy` releases:
+---------------+-------------+-----------------------------------------------+
| release date | version tag | notes |
+===============+=============+===============================================+
| Mar 5, 2019 | v1.2 | - plotting fixes |
| | | - documentation clean-up |
| | | - bug fixes |
+---------------+-------------+-----------------------------------------------+
| Jan 30, 2019 | v1.1 | - XLS parser enhancements |
| | | - Transponder and Roadm add-drop noise |
| | | contribution and system margin included |
| | | - Automatic transponders mode selection |
| | | - Route selection with disjunction constraints|
| | | - Detailed carrier information inspection on |
| | | each element along propagation |
| | | - OpenRoadm noise models |
| | | - bug fixes |
+---------------+-------------+-----------------------------------------------+
| Oct 16, 2018 | v1.0 | - first "production"-ready release |
| | | - open network element model (EDFA, GN-model) |
| | | - auto-design functionality |
| | | - path request functionality |
+---------------+-------------+-----------------------------------------------+
How to Install
--------------
@@ -62,10 +37,9 @@ How to Install
It is recommended that you use a "virtual environment" when installing `gnpy`.
Do not install `gnpy` on your system Python.
We recommend the use of the Anaconda Python distribution
(https://www.anaconda.com/download) which comes with many scientific computing
We recommend the use of the `Anaconda Python distribution <https://www.anaconda.com/download>`_ which comes with many scientific computing
dependencies pre-installed. Anaconda creates a base "virtual environment" for
you automatically. You can also create and manage your conda "virtual
you automatically. You can also create and manage your ``conda`` "virtual
environments" yourself (see:
https://conda.io/docs/user-guide/tasks/manage-environments.html)
@@ -111,7 +85,7 @@ of the `gnpy` repo and install it with:
$ python setup.py install # install
To test that `gnpy` was successfully installed, you can run this command. If it
executes without a `ModuleNotFoundError`, you have successfully installed
executes without a ``ModuleNotFoundError``, you have successfully installed
`gnpy`.
.. code-block:: shell
@@ -193,59 +167,59 @@ information to transmit.)
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': None` is an advanced model. A detailed json configuration file is required (by default `examples/std_medium_gain_advanced_config.json <examples/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.
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': None`` is an advanced model. A detailed JSON configuration file is required (by default `examples/std_medium_gain_advanced_config.json <examples/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.
For all amplifier models:
+----------------------+-----------+-----------------------------------------+
| field | type | description |
+======================+===========+=========================================+
| `type_variety` | (string) | a unique name to ID the amplifier in the|
| | | JSON/Excel template topology input file |
+----------------------+-----------+-----------------------------------------+
| `out_voa_auto` | (boolean) | auto_design feature to optimize the |
| | | amplifier output VOA. If true, output |
| | | VOA is present and will be used to push |
| | | amplifier gain to its maximum, within |
| | | EOL power margins. |
+----------------------+-----------+-----------------------------------------+
| `allowed_for_design` | (boolean) | If false, the amplifier will not be |
| | | picked by auto-design but it can still |
| | | be used as a manual input (from JSON or |
| | | Excel template topology files.) |
+----------------------+-----------+-----------------------------------------+
+------------------------+-----------+-----------------------------------------+
| field | type | description |
+========================+===========+=========================================+
| ``type_variety`` | (string) | a unique name to ID the amplifier in the|
| | | JSON/Excel template topology input file |
+------------------------+-----------+-----------------------------------------+
| ``out_voa_auto`` | (boolean) | auto_design feature to optimize the |
| | | amplifier output VOA. If true, output |
| | | VOA is present and will be used to push |
| | | amplifier gain to its maximum, within |
| | | EOL power margins. |
+------------------------+-----------+-----------------------------------------+
| ``allowed_for_design`` | (boolean) | If false, the amplifier will not be |
| | | picked by auto-design but it can still |
| | | be used as a manual input (from JSON or |
| | | Excel template topology files.) |
+------------------------+-----------+-----------------------------------------+
The fiber library currently describes SSMF and NZDF but additional fiber types can be entered by the user following the same model:
+----------------------+-----------+-----------------------------------------+
| field | type | description |
+======================+===========+=========================================+
| `type_variety` | (string) | a unique name to ID the fiber in the |
| ``type_variety`` | (string) | a unique name to ID the fiber in the |
| | | JSON or Excel template topology input |
| | | file |
+----------------------+-----------+-----------------------------------------+
| `dispersion` | (number) | (s.m-1.m-1) |
| ``dispersion`` | (number) | (s.m-1.m-1) |
+----------------------+-----------+-----------------------------------------+
| `gamma` | (number) | 2pi.n2/(lambda*Aeff) (w-2.m-1) |
| ``gamma`` | (number) | 2pi.n2/(lambda*Aeff) (w-2.m-1) |
+----------------------+-----------+-----------------------------------------+
The transceiver equipment library is a list of supported transceivers. New
transceivers can be added and existing ones removed at will by the user. It is
used to determine the service list path feasibility when running the
path_request_run.py routine.
`path_request_run.py routine <examples/path_request_run.py>`_.
+----------------------+-----------+-----------------------------------------+
| field | type | description |
+======================+===========+=========================================+
| `type_variety` | (string) | a unique name to ID the transceiver in |
| ``type_variety`` | (string) | A unique name to ID the transceiver in |
| | | the JSON or Excel template topology |
| | | input file |
+----------------------+-----------+-----------------------------------------+
| `frequency` | (number) | Min/max as below. |
| ``frequency`` | (number) | Min/max as below. |
+----------------------+-----------+-----------------------------------------+
| `mode` | (number) | a list of modes supported by the |
| ``mode`` | (number) | A list of modes supported by the |
| | | transponder. New modes can be added at |
| | | will by the user. The modes are specific|
| | | to each transponder type_variety. |
@@ -257,34 +231,34 @@ The modes are defined as follows:
+----------------------+-----------+-----------------------------------------+
| field | type | description |
+======================+===========+=========================================+
| `format` | (string) | a unique name to ID the mode. |
| ``format`` | (string) | a unique name to ID the mode |
+----------------------+-----------+-----------------------------------------+
| `baud_rate` | (number) | in Hz |
| ``baud_rate`` | (number) | in Hz |
+----------------------+-----------+-----------------------------------------+
| `OSNR` | (number) | min required OSNR in 0.1nm (dB) |
| ``OSNR`` | (number) | min required OSNR in 0.1nm (dB) |
+----------------------+-----------+-----------------------------------------+
| `bit_rate` | (number) | in bit/s |
| ``bit_rate`` | (number) | in bit/s |
+----------------------+-----------+-----------------------------------------+
| `roll_off` | (number) | Not used. |
| ``roll_off`` | (number) | Not used. |
+----------------------+-----------+-----------------------------------------+
| `tx_osnr` | (number) | In dB. OSNR out from transponder. |
| ``tx_osnr`` | (number) | In dB. OSNR out from transponder. |
+----------------------+-----------+-----------------------------------------+
| `cost` | (number) | Arbitrary unit |
| ``cost`` | (number) | Arbitrary unit |
+----------------------+-----------+-----------------------------------------+
Simulation parameters are defined as follows.
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.
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.
``'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.
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 configuration is performed as follows. It is not a list (which may change
in later releases) and the user can only modify the value of existing
@@ -293,25 +267,25 @@ parameters:
+------------------------+-----------+---------------------------------------------+
| field | type | description |
+========================+===========+=============================================+
| `power_mode` | (boolean) | If false, gain mode. Auto-design sets |
| | | amplifier gain = preceding span loss, |
| ``power_mode`` | (boolean) | If false, gain mode. Auto-design sets |
| | | amplifier gain = preceding span loss, |
| | | unless the amplifier exists and its |
| | | gain > 0 in the topology input json. |
| | | gain > 0 in the topology input JSON. |
| | | If true, power mode (recommended for |
| | | auto-design and power sweep.) |
| | | Auto-design sets amplifier power |
| | | according to delta_power_range. If the |
| | | amplifier exists with gain > 0 in the |
| | | topology json input, then its gain is |
| | | topology JSON input, then its gain is |
| | | translated into a power target/channel. |
| | | Moreover, when performing a power sweep |
| | | (see power_range_db in the SI |
| | | (see ``power_range_db`` in the SI |
| | | configuration library) the power sweep |
| | | is performed w/r/t this power target, |
| | | regardless of preceding amplifiers |
| | | regardless of preceding amplifiers |
| | | power saturation/limitations. |
+------------------------+-----------+---------------------------------------------+
| `delta_power_range_db` | (number) | Auto-design only, power-mode |
| ``delta_power_range_db`` | (number) | Auto-design only, power-mode |
| | | only. Specifies the [min, max, step] |
| | | power excursion/span. It is a relative |
| | | power excursion w/r/t the |
@@ -345,22 +319,24 @@ parameters:
| | | a 23 dB span to |
| | | power = power_dbm + power_range_db + 1 |
+------------------------+-----------+---------------------------------------------+
| `max_length` | (number) | Split fiber lengths > max_length. |
| ``max_fiber_lineic_loss_for_raman`` | (number) | Maximum linear fiber loss for Raman |
| | | amplification use. |
+------------------------+-----------+---------------------------------------------+
| ``max_length`` | (number) | Split fiber lengths > max_length. |
| | | Interest to support high level |
| | | topologies that do not specify in line |
| | | amplification sites. For example the |
| | | CORONET_Global_Topology.xls defines |
| | | links > 1000km between 2 sites: it |
| | | couldn't be simulated if these links |
| | | were not splitted in shorter span |
| | | lengths. |
| | | were not split in shorter span lengths. |
+------------------------+-----------+---------------------------------------------+
| `length_unit` | "m"/"km" | Unit for max_length. |
| ``length_unit`` | "m"/"km" | Unit for ``max_length``. |
+------------------------+-----------+---------------------------------------------+
| `max_loss` | (number) | Not used in the current code |
| ``max_loss`` | (number) | Not used in the current code |
| | | implementation. |
+------------------------+-----------+---------------------------------------------+
| `padding` | (number) | In dB. Min span loss before putting an |
| ``padding`` | (number) | In dB. Min span loss before putting an |
| | | attenuator before fiber. Attenuator |
| | | value |
| | | Fiber.att_in = max(0, padding - span_loss). |
@@ -375,25 +351,23 @@ parameters:
| | | Therefore it is not possible to set |
| | | span_loss < padding. |
+------------------------+-----------+---------------------------------------------+
| `EOL` | (number) | All fiber span loss ageing. The value |
| ``EOL`` | (number) | All fiber span loss ageing. The value |
| | | is added to the con_out (fiber output |
| | | connector). So the design and the path |
| | | feasibility are performed with |
| | | span_loss + EOL. EOL cannot be set |
| | | manually for a given fiber span |
| | | (workaround is to specify higher con_out |
| | | (workaround is to specify higher ``con_out`` |
| | | loss for this fiber). |
+------------------------+-----------+---------------------------------------------+
| `con_in`, `con_out` | (number) | Default values if Fiber/params/con_in/out |
| | | is None in the topology input |
| ``con_in``, | (number) | Default values if Fiber/params/con_in/out |
| ``con_out`` | | is None in the topology input |
| | | description. This default value is |
| | | ignored if a Fiber/params/con_in/out |
| | | value is input in the topology for a |
| | | given Fiber. |
+------------------------+-----------+---------------------------------------------+
**[1]**
.. code-block:: json
{
@@ -418,30 +392,28 @@ existing parameters:
+--------------------------+-----------+---------------------------------------------+
| field | type | description |
+==========================+===========+=============================================+
| `gain_mode_default_loss` | (number) | Default value if Roadm/params/loss is |
| | | None in the topology input description. |
| ``target_pch_out_db`` | (number) | Auto-design sets the ROADM egress channel |
| | | power. This reflects typical control loop |
| | | algorithms that adjust ROADM losses to |
| | | equalize channels (eg coming from different |
| | | ingress direction or add ports) |
| | | This is the default value |
| | | Roadm/params/target_pch_out_db if no value |
| | | is given in the ``Roadm`` element in the |
| | | topology input description. |
| | | This default value is ignored if a |
| | | params/loss value is input in the |
| | | topology for a given ROADM. |
| | | params/target_pch_out_db value is input in |
| | | the topology for a given ROADM. |
+--------------------------+-----------+---------------------------------------------+
| `power_mode_pref` | (number) | Power mode only. Auto-design sets the |
| | | power of ROADM ingress amplifiers to |
| | | power_dbm + power_range_db, |
| | | regardless of existing gain settings |
| | | from the topology JSON input. |
| | | Auto-design sets the Roadm loss so that |
| | | its egress channel power = power_mode_pref, |
| | | regardless of existing loss settings |
| | | from the topology JSON input. It means |
| | | that the output power from a ROADM (and |
| | | therefore its OSNR contribution) is Cte |
| | | and not depending from power_dbm and |
| | | power_range_db sweep settings. This |
| | | choice is meant to reflect some typical |
| | | control loop algorithms. |
| ``add_drop_osnr`` | (number) | OSNR contribution from the add/drop ports |
+--------------------------+-----------+---------------------------------------------+
| ``restrictions`` | (strings) | Authorized type_variety of amplifier for |
| | | booster or preamp. |
| | | Listed type_variety MUST be defined in the |
| | | Edfa catalog. |
+--------------------------+-----------+---------------------------------------------+
The `SpectralInformation` object can be configured as follows. The user can
The ``SpectralInformation`` object can be configured as follows. 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
@@ -450,21 +422,18 @@ one power/channel definition.
+----------------------+-----------+-------------------------------------------+
| field | type | description |
+======================+===========+===========================================+
| `f_min/max` | (number) | In Hz. Carrier min max excursion |
| ``f_min``, | (number) | In Hz. Carrier min max excursion. |
| ``f_max`` | | |
+----------------------+-----------+-------------------------------------------+
| `baud_rate` | (number) | In Hz. Simulated baud rate. |
| ``baud_rate`` | (number) | In Hz. Simulated baud rate. |
+----------------------+-----------+-------------------------------------------+
| `spacing` | (number) | In Hz. Carrier spacing. |
| ``spacing`` | (number) | In Hz. Carrier spacing. |
+----------------------+-----------+-------------------------------------------+
| `roll_off` | (number) | Not used. |
| ``roll_off`` | (number) | Not used. |
+----------------------+-----------+-------------------------------------------+
| `OSNR` | (number) | Not used. |
| ``tx_osnr`` | (number) | In dB. OSNR out from transponder. |
+----------------------+-----------+-------------------------------------------+
| `bit_rate` | (number) | Not used. |
+----------------------+-----------+-------------------------------------------+
| `tx_osnr` | (number) | In dB. OSNR out from transponder. |
+----------------------+-----------+-------------------------------------------+
| `power_dbm` | (number) | Reference channel power. In gain mode |
| ``power_dbm`` | (number) | Reference channel power. In gain mode |
| | | (see spans/power_mode = false), all gain |
| | | settings are offset w/r/t this reference |
| | | power. In power mode, it is the |
@@ -477,17 +446,19 @@ one power/channel definition.
| | | power sweep is defined (see after) the |
| | | design is not repeated. |
+----------------------+-----------+-------------------------------------------+
| `power_range_db` | (number) | Power sweep excursion around power_dbm. |
| ``power_range_db`` | (number) | Power sweep excursion around power_dbm. |
| | | It is not the min and max channel power |
| | | values! The reference power becomes: |
| | | power_range_db + power_dbm. |
+----------------------+-----------+-------------------------------------------+
| ``sys_margins`` | (number) | In dB. Added margin on min required |
| | | transceiver OSNR. |
+----------------------+-----------+-------------------------------------------+
The `transmission_main_example.py <examples/transmission_main_example.py>`_
script propagates a spectrum of channels at 32 Gbaud, 50 GHz spacing and 0
dBm/channel. These are not yet parametrized but can be modified directly in the
script (via the SpectralInformation structure) to accommodate any baud rate,
spacing, power or channel count demand.
The `transmission_main_example.py <examples/transmission_main_example.py>`_ 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.
Use `examples/path_requests_run.py <examples/path_requests_run.py>`_ to run multiple optimizations as follows:
@@ -496,7 +467,7 @@ Use `examples/path_requests_run.py <examples/path_requests_run.py>`_ to run mult
$ python path_requests_run.py -h
Usage: path_requests_run.py [-h] [-v] [-o OUTPUT] [network_filename] [service_filename] [eqpt_filename]
The `network_filename` and `service_filename` can be an XLS or JSON file. The `eqpt_filename` must be a JSON file.
The ``network_filename`` and ``service_filename`` can be an XLS or JSON file. The ``eqpt_filename`` must be a JSON file.
To see an example of it, run:
@@ -507,10 +478,10 @@ To see an example of it, run:
This program requires a list of connections to be estimated and the equipment
library. The program computes performances for the list of services (accepts
json or excel format) using the same spectrum propagation modules as
transmission_main_example.py. Explanation on the Excel template is provided in
JSON or Excel format) using the same spectrum propagation modules as
``transmission_main_example.py``. Explanation on the Excel template is provided in
the `Excel_userguide.rst <Excel_userguide.rst#service-sheet>`_. Template for
the json format can be found here: `service-template.json
the JSON format can be found here: `service-template.json
<service-template.json>`_.
Contributing

View File

@@ -0,0 +1,160 @@
{
"nf_fit_coeff": [
0.0008,
0.0272,
-0.2249,
6.4902
],
"f_min": 191.35e12,
"f_max": 196.1e12,
"nf_ripple": [
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
0.0
],
"gain_ripple": [
0.15017064489112,
0.14157768006701,
0.00223094639866,
-0.06701528475711,
-0.05982935510889,
-0.01028161641541,
0.02740682579566,
0.02795958961474,
0.00107516750419,
-0.02199015912898,
-0.00877407872698,
0.0453465242881,
0.1204721524288,
0.18936662479061,
0.23826109715241,
0.26956762981574,
0.27836159966498,
0.26941687604691,
0.23579878559464,
0.18147717755444,
0.1191656197655,
0.05921587102177,
0.01509526800668,
-0.01053287269681,
-0.02475397822447,
-0.01847257118928,
-0.00420121440538,
0.01584903685091,
0.0399193886097,
0.04494451423784,
0.04961788107202,
0.03378873534338,
0.01027114740367,
-0.01319618927973,
-0.04962835008375,
-0.0765630234506,
-0.10606051088777,
-0.13550774706866,
-0.15460322445561,
-0.17113588777219,
-0.18053287269681,
-0.18324644053602,
-0.19440221943049,
-0.20897508375209,
-0.23575900335007,
-0.25188965661642,
-0.22244242043552,
-0.15656302345061
],
"dgt": [
2.4553191172498,
2.44342862248888,
2.41879254989742,
2.38192717604575,
2.33147727493671,
2.26678136721453,
2.19013043016015,
2.10336369905543,
2.01414465424155,
1.92915262384742,
1.85543800978691,
1.79748596476494,
1.75428006928365,
1.72461030013125,
1.70379790088896,
1.68845480656382,
1.6761448370895,
1.66286684904577,
1.64799163036252,
1.63068023161292,
1.61073904908309,
1.58973304612691,
1.56750088631614,
1.54578500307573,
1.5242627235492,
1.50335352244996,
1.48420288841848,
1.46637521309853,
1.44977369463316,
1.43476940680732,
1.42089447397912,
1.40864903907609,
1.3966294751726,
1.38430337205545,
1.3710092503689,
1.35690844654118,
1.3405812000038,
1.32210817897091,
1.30069883494415,
1.27657903892303,
1.24931318255134,
1.21911100318577,
1.18632744096844,
1.15209185089701,
1.11575888725852,
1.07773189112355,
1.03941448941778,
1.0
]
}

View File

@@ -1,5 +1,6 @@
{
"nf_ripple": "NFR0_96.txt",
"gain_ripple": "DFG0_96.txt",
"dgt": "DGT_96.txt"
"nf_ripple": "NFR_96.txt",
"gain_ripple": "DFG_96.txt",
"dgt": "DGT_96.txt",
"nf_fit_coeff": "pNFfit3.txt"
}

View File

@@ -1,8 +0,0 @@
-1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01
-2.0000000000000000e+01 -2.0000000000000000e+01 -2.0000000000000000e+01 -2.0000000000000000e+01 -2.0000000000000000e+01 -2.0000000000000000e+01 -2.0000000000000000e+01 -2.0000000000000000e+01 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02
-1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -2.0000000000000000e+01 -2.0000000000000000e+01 -2.0000000000000000e+01 -2.0000000000000000e+01 -2.0000000000000000e+01 -2.0000000000000000e+01 -2.0000000000000000e+01 -2.0000000000000000e+01
-2.0500000000000000e+01 -2.0489473680000000e+01 -2.0478947370000000e+01 -2.0468421050000000e+01 -2.0457894740000000e+01 -2.0447368420000000e+01 -2.0436842110000001e+01 -2.0426315790000000e+01 -2.0415789470000000e+01 -2.0405263160000001e+01 -2.0394736840000000e+01 -2.0384210530000001e+01 -2.0373684210000000e+01 -2.0363157890000000e+01 -2.0352631580000001e+01 -2.0342105260000000e+01 -2.0331578950000001e+01 -2.0321052630000001e+01 -2.0310526320000001e+01 -2.0300000000000001e+01 -2.0289473680000000e+01 -2.0278947370000001e+01 -2.0268421050000001e+01 -2.0257894740000001e+01 -2.0247368420000001e+01 -2.0236842110000001e+01 -2.0226315790000001e+01 -2.0215789470000001e+01 -2.0205263160000001e+01 -2.0194736840000001e+01 -2.0184210530000001e+01 -2.0173684210000001e+01 -2.0163157890000001e+01 -2.0152631580000001e+01 -2.0142105260000001e+01 -2.0131578950000002e+01 -2.0121052630000001e+01 -2.0110526320000002e+01 -2.0100000000000001e+01 -2.0089473680000001e+01 -2.0078947370000002e+01 -2.0068421050000001e+01 -2.0057894739999998e+01 -2.0047368420000002e+01 -2.0036842109999998e+01 -2.0026315790000002e+01 -2.0015789470000001e+01 -2.0005263159999998e+01 -1.9994736840000002e+01 -1.9984210529999999e+01 -1.9973684209999998e+01 -1.9963157890000002e+01 -1.9952631579999998e+01 -1.9942105260000002e+01 -1.9931578949999999e+01 -1.9921052629999998e+01 -1.9910526319999999e+01 -1.9899999999999999e+01 -1.9889473679999998e+01 -1.9878947369999999e+01 -1.9868421049999998e+01 -1.9857894739999999e+01 -1.9847368419999999e+01 -1.9836842109999999e+01 -1.9826315789999999e+01 -1.9815789469999999e+01 -1.9805263159999999e+01 -1.9794736839999999e+01 -1.9784210529999999e+01 -1.9773684209999999e+01 -1.9763157889999999e+01 -1.9752631579999999e+01 -1.9742105259999999e+01 -1.9731578949999999e+01 -1.9721052629999999e+01 -1.9710526320000000e+01 -1.9699999999999999e+01 -1.9689473679999999e+01 -1.9678947369999999e+01 -1.9668421049999999e+01 -1.9657894740000000e+01 -1.9647368419999999e+01 -1.9636842110000000e+01 -1.9626315790000000e+01 -1.9615789469999999e+01 -1.9605263160000000e+01 -1.9594736839999999e+01 -1.9584210530000000e+01 -1.9573684210000000e+01 -1.9563157889999999e+01 -1.9552631580000000e+01 -1.9542105260000000e+01 -1.9531578950000000e+01 -1.9521052630000000e+01 -1.9510526320000000e+01 -1.9500000000000000e+01
-2.0500000000000000e+01 -2.0489473680000000e+01 -2.0478947370000000e+01 -2.0468421050000000e+01 -2.0457894740000000e+01 -2.0447368420000000e+01 -2.0436842110000001e+01 -2.0426315790000000e+01 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.9573684210000000e+01 -1.9563157889999999e+01 -1.9552631580000000e+01 -1.9542105260000000e+01 -1.9531578950000000e+01 -1.9521052630000000e+01 -1.9510526320000000e+01 -1.9500000000000000e+01
-1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.4460000000000001e+01
-1.4460000000000001e+01 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01
-1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.4460000000000001e+01 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02

View File

@@ -1,8 +0,0 @@
7.0000000000000000e+01 1.1700000000000000e+02 1.0800000000000000e+02 1.0800000000000000e+02 3.2000000000000000e+01 7.0000000000000000e+01 1.0800000000000000e+02 9.7000000000000000e+01 1.1600000000000000e+02 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01
7.9000000000000000e+01 1.1000000000000000e+02 1.0100000000000000e+02 3.2000000000000000e+01 7.1000000000000000e+01 1.1400000000000000e+02 1.1100000000000000e+02 1.1700000000000000e+02 1.1200000000000000e+02 3.2000000000000000e+01 6.6000000000000000e+01 1.0800000000000000e+02 1.1700000000000000e+02 1.0100000000000000e+02 3.2000000000000000e+01
7.9000000000000000e+01 1.1000000000000000e+02 1.0100000000000000e+02 3.2000000000000000e+01 7.1000000000000000e+01 1.1400000000000000e+02 1.1100000000000000e+02 1.1700000000000000e+02 1.1200000000000000e+02 3.2000000000000000e+01 8.2000000000000000e+01 1.0100000000000000e+02 1.0000000000000000e+02 3.2000000000000000e+01 3.2000000000000000e+01
7.0000000000000000e+01 1.1700000000000000e+02 1.0800000000000000e+02 1.0800000000000000e+02 3.2000000000000000e+01 1.1900000000000000e+02 3.2000000000000000e+01 8.3000000000000000e+01 8.2000000000000000e+01 8.3000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01
6.6000000000000000e+01 1.1100000000000000e+02 1.1600000000000000e+02 1.0400000000000000e+02 3.2000000000000000e+01 6.9000000000000000e+01 1.1000000000000000e+02 1.0000000000000000e+02 1.1500000000000000e+02 3.2000000000000000e+01 1.1900000000000000e+02 3.2000000000000000e+01 8.3000000000000000e+01 8.2000000000000000e+01 8.3000000000000000e+01
1.0400000000000000e+02 1.0100000000000000e+02 9.7000000000000000e+01 1.1800000000000000e+02 1.2100000000000000e+02 3.2000000000000000e+01 9.8000000000000000e+01 1.0800000000000000e+02 1.1700000000000000e+02 1.0100000000000000e+02 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01
1.0400000000000000e+02 1.0100000000000000e+02 9.7000000000000000e+01 1.1800000000000000e+02 1.2100000000000000e+02 3.2000000000000000e+01 1.1400000000000000e+02 1.0100000000000000e+02 1.0000000000000000e+02 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01
1.1900000000000000e+02 1.1100000000000000e+02 1.1400000000000000e+02 1.1500000000000000e+02 1.1600000000000000e+02 3.2000000000000000e+01 9.9000000000000000e+01 9.7000000000000000e+01 1.1500000000000000e+02 1.0100000000000000e+02 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01

View File

@@ -1,301 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Nov 27 12:32:04 2017
@author: briantaylor
"""
import numpy as np
from numpy import polyfit, polyval, mean
from utilities import lin2db, db2lin, itufs, freq2wavelength
import matplotlib.pyplot as plt
from scipy.constants import h
def noise_profile(nf, gain, ffs, df):
""" noise_profile(nf, gain, ffs, df) computes amplifier ase
:param nf: Noise figure in dB
:param gain: Actual gain calculated for the EDFA in dB units
:param ffs: A numpy array of frequencies
:param df: the reference bw in THz
:type nf: numpy.ndarray
:type gain: numpy.ndarray
:type ffs: numpy.ndarray
:type df: float
:return: the asepower in dBm
:rtype: numpy.ndarray
ASE POWER USING PER CHANNEL GAIN PROFILE
INPUTS:
NF_dB - Noise figure in dB, vector of length number of channels or
spectral slices
G_dB - Actual gain calculated for the EDFA, vector of length number of
channels or spectral slices
ffs - Center frequency grid of the channels or spectral slices in THz,
vector of length number of channels or spectral slices
dF - width of each channel or spectral slice in THz,
vector of length number of channels or spectral slices
OUTPUT:
ase_dBm - ase in dBm per channel or spectral slice
NOTE: the output is the total ASE in the channel or spectral slice. For
50GHz channels the ASE BW is effectively 0.4nm. To get to noise power in
0.1nm, subtract 6dB.
ONSR is usually quoted as channel power divided by
the ASE power in 0.1nm RBW, regardless of the width of the actual
channel. This is a historical convention from the days when optical
signals were much smaller (155Mbps, 2.5Gbps, ... 10Gbps) than the
resolution of the OSAs that were used to measure spectral power which
were set to 0.1nm resolution for convenience. Moving forward into
flexible grid and high baud rate signals, it may be convenient to begin
quoting power spectral density in the same BW for both signal and ASE,
e.g. 12.5GHz."""
h_mWThz = 1e-3 * h * (1e14)**2
nf_lin = db2lin(nf)
g_lin = db2lin(gain)
ase = h_mWThz * df * ffs * (nf_lin * g_lin - 1)
asedb = lin2db(ase)
return asedb
def gain_profile(dfg, dgt, Pin, gp, gtp):
"""
:param dfg: design flat gain
:param dgt: design gain tilt
:param Pin: channing input power profile
:param gp: Average gain setpoint in dB units
:param gtp: gain tilt setting
:type dfg: numpy.ndarray
:type dgt: numpy.ndarray
:type Pin: numpy.ndarray
:type gp: float
:type gtp: float
:return: gain profile in dBm
:rtype: numpy.ndarray
AMPLIFICATION USING INPUT PROFILE
INPUTS:
DFG - vector of length number of channels or spectral slices
DGT - vector of length number of channels or spectral slices
Pin - input powers vector of length number of channels or
spectral slices
Gp - provisioned gain length 1
GTp - provisioned tilt length 1
OUTPUT:
amp gain per channel or spectral slice
NOTE: there is no checking done for violations of the total output power
capability of the amp.
Ported from Matlab version written by David Boerges at Ciena.
Based on:
R. di Muro, "The Er3+ fiber gain coefficient derived from a dynamic
gain
tilt technique", Journal of Lightwave Technology, Vol. 18, Iss. 3,
Pp. 343-347, 2000.
"""
err_tolerance = 1.0e-11
simple_opt = True
# TODO make all values linear unit and convert to dB units as needed within
# this function.
nchan = list(range(len(Pin)))
# TODO find a way to use these or lose them. Primarily we should have a
# way to determine if exceeding the gain or output power of the amp
tot_in_power_db = lin2db(np.sum(db2lin(Pin)))
avg_gain_db = lin2db(mean(db2lin(dfg)))
# Linear fit to get the
p = polyfit(nchan, dgt, 1)
dgt_slope = p[0]
# Calculate the target slope- Currently assumes equal spaced channels
# TODO make it so that supports arbitrary channel spacing.
targ_slope = gtp / (len(nchan) - 1)
# 1st estimate of DGT scaling
dgts1 = targ_slope / dgt_slope
# when simple_opt is true code makes 2 attempts to compute gain and
# the internal voa value. This is currently here to provide direct
# comparison with original Matlab code. Will be removed.
# TODO replace with loop
if simple_opt:
# 1st estimate of Er gain & voa loss
g1st = dfg + dgt * dgts1
voa = lin2db(mean(db2lin(g1st))) - gp
# 2nd estimate of Amp ch gain using the channel input profile
g2nd = g1st - voa
pout_db = lin2db(np.sum(db2lin(Pin + g2nd)))
dgts2 = gp - (pout_db - tot_in_power_db)
# Center estimate of amp ch gain
xcent = dgts2
gcent = g1st - voa + dgt * xcent
pout_db = lin2db(np.sum(db2lin(Pin + gcent)))
gavg_cent = pout_db - tot_in_power_db
# Lower estimate of Amp ch gain
deltax = np.max(g1st) - np.min(g1st)
xlow = dgts2 - deltax
glow = g1st - voa + xlow * dgt
pout_db = lin2db(np.sum(db2lin(Pin + glow)))
gavg_low = pout_db - tot_in_power_db
# Upper gain estimate
xhigh = dgts2 + deltax
ghigh = g1st - voa + xhigh * dgt
pout_db = lin2db(np.sum(db2lin(Pin + ghigh)))
gavg_high = pout_db - tot_in_power_db
# compute slope
slope1 = (gavg_low - gavg_cent) / (xlow - xcent)
slope2 = (gavg_cent - gavg_high) / (xcent - xhigh)
if np.abs(gp - gavg_cent) <= err_tolerance:
dgts3 = xcent
elif gp < gavg_cent:
dgts3 = xcent - (gavg_cent - gp) / slope1
else:
dgts3 = xcent + (-gavg_cent + gp) / slope2
gprofile = g1st - voa + dgt * dgts3
else:
gprofile = None
return gprofile
if __name__ == '__main__':
plt.close('all')
fc = itufs(0.05)
lc = freq2wavelength(fc) / 1000
nchan = list(range(len(lc)))
df = np.array([0.05] * (nchan[-1] + 1))
# TODO remove path dependence
path = ''
"""
DFG_96: Design flat gain at each wavelength in the 96 channel 50GHz ITU
grid in dB. This can be experimentally determined by measuring the gain
at each wavelength using a full, flat channel (or ASE) load at the input.
The amplifier should be set to its maximum flat gain (tilt = 0dB). This
measurement captures the ripple of the amplifier. If the amplifier was
designed to be mimimum ripple at some other tilt value, then the ripple
reflected in this measurement will not be that minimum. However, when
the DGT gets applied through the provisioning of tilt, the model should
accurately reproduce the expected ripple at that tilt value. One could
also do the measurement at some expected tilt value and back-calculate
this vector using the DGT method. Alternatively, one could re-write the
algorithm to accept a nominal tilt and a tiled version of this vector.
"""
dfg_96 = np.loadtxt(path + 'DFG_96.txt')
"""maximum gain for flat operation - the amp in the data file was designed
for 25dB gain and has an internal VOA for setting the external gain
"""
avg_dfg = dfg_96.mean()
"""
DGT_96: This is the so-called Dynamic Gain Tilt of the EDFA in dB/dB. It
is the change in gain at each wavelength corresponding to a 1dB change at
the longest wavelength supported. The value can be obtained
experimentally or through analysis of the cross sections or Giles
parameters of the Er fibre. This is experimentally measured by changing
the gain of the amplifier above the maximum flat gain while not changing
the internal VOA (i.e. the mid-stage VOA is set to minimum and does not
change during the measurement). Note that the measurement can change the
gain by an arbitrary amount and divide by the gain change (in dB) which
is measured at the reference wavelength (the red end of the band).
"""
dgt_96 = np.loadtxt(path + 'DGT_96.txt')
"""
pNFfit3: Cubic polynomial fit coefficients to noise figure in dB
averaged across wavelength as a function of gain change from design flat:
NFavg = pNFfit3(1)*dG^3 + pNFfit3(2)*dG^2 pNFfit3(3)*dG + pNFfit3(4)
where
dG = GainTarget - average(DFG_96)
note that dG will normally be a negative value.
"""
nf_fitco = np.loadtxt(path + 'pNFfit3.txt')
"""NFR_96: Noise figure ripple in dB away from the average noise figure
across the band. This captures the wavelength dependence of the NF. To
calculate the NF across channels, one uses the cubic fit coefficients
with the external gain target to get the average nosie figure, NFavg and
then adds this to NFR_96:
NF_96 = NFR_96 + NFavg
"""
nf_ripple = np.loadtxt(path + 'NFR_96.txt')
# This is an example to set the provisionable gain and gain-tilt values
# Tilt is in units of dB/THz
gain_target = 20.0
tilt_target = -0.7
# calculate the NF for the EDFA at this gain setting
dg = gain_target - avg_dfg
nf_avg = polyval(nf_fitco, dg)
nf_96 = nf_ripple + nf_avg
# get the input power profiles to show
pch2d = np.loadtxt(path + 'Pchan2D.txt')
# Load legend and assemble legend text
pch2d_legend_data = np.loadtxt(path + 'Pchan2DLegend.txt')
pch2d_legend = []
for ea in pch2d_legend_data:
s = ''.join([chr(xx) for xx in ea.astype(dtype=int)]).strip()
pch2d_legend.append(s)
# assemble plot
axis_font = {'fontname': 'Arial', 'size': '16', 'fontweight': 'bold'}
title_font = {'fontname': 'Arial', 'size': '17', 'fontweight': 'bold'}
tic_font = {'fontname': 'Arial', 'size': '12'}
plt.rcParams["font.family"] = "Arial"
plt.figure()
plt.plot(nchan, pch2d.T, '.-', lw=2)
plt.xlabel('Channel Number', **axis_font)
plt.ylabel('Channel Power [dBm]', **axis_font)
plt.title('Input Power Profiles for Different Channel Loading',
**title_font)
plt.legend(pch2d_legend, loc=5)
plt.grid()
plt.ylim((-100, -10))
plt.xlim((0, 110))
plt.xticks(np.arange(0, 100, 10), **tic_font)
plt.yticks(np.arange(-110, -10, 10), **tic_font)
plt.figure()
ea = pch2d[1, :]
for ea in pch2d:
chgain = gain_profile(dfg_96, dgt_96, ea, gain_target, tilt_target)
pase = noise_profile(nf_96, chgain, fc, df)
pout = lin2db(db2lin(ea + chgain) + db2lin(pase))
plt.plot(nchan, pout, '.-', lw=2)
plt.title('Output Power with ASE for Different Channel Loading',
**title_font)
plt.xlabel('Channel Number', **axis_font)
plt.ylabel('Channel Power [dBm]', **axis_font)
plt.grid()
plt.ylim((-50, 10))
plt.xlim((0, 100))
plt.xticks(np.arange(0, 100, 10), **tic_font)
plt.yticks(np.arange(-50, 10, 10), **tic_font)
plt.legend(pch2d_legend, loc=5)
plt.show()

View File

@@ -0,0 +1,300 @@
*********************************************
Amplifier models and configuration
*********************************************
1. Equipment configuration description
#######################################
Equipment description defines equipment types and parameters.
It takes place in the default **eqpt_config.json** file.
By default **transmission_main_example.py** 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::
{"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*
.. code-block::
"Edfa":[{
"type_variety": "high_detail_model_example",
"type_def": "advanced_model",
"gain_flatmax": 25,
"gain_min": 15,
"p_max": 21,
"advanced_config_from_json": "std_medium_gain_advanced_config.json",
"out_voa_auto": false,
"allowed_for_design": false
}
]
- *"variable_gain"*
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::
"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::
"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::
"Edfa":[{
"type_variety": "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::
{
"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/examples/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:
.. code-block::
{
"nf_fit_coeff": "nf_filename.txt",
"nf_ripple": "nf_ripple_filename.txt",
"gain_ripple": "DFG_filename.txt",
"dgt": "DGT_filename.txt",
}

View File

@@ -4,7 +4,6 @@
Created on Tue Jan 30 12:32:00 2018
@author: jeanluc-auge
@comments about amplifier input files from Brian Taylor & Dave Boertjes
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
@@ -18,46 +17,29 @@ from gnpy.core.utils import lin2db, db2lin
"""amplifier file names
convert a set of amplifier files + input json definiton file into a valid edfa_json_file:
nf_fit_coeff: NF polynomial coefficients txt file (optional)
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
dfg: gain 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:
{
"gain_flatmax": 25,
"gain_min": 15,
"p_max": 21,
"nf_fit_coeff": "pNFfit3.txt",
"nf_ripple": "NFR_96.txt",
"dfg": "DFG_96.txt",
"dgt": "DGT_96.txt",
"nf_model":
{
"enabled": true,
"nf_min": 5.8,
"nf_max": 10
}
"nf_fit_coeff": "nf_filename.txt",
"nf_ripple": "nf_ripple_filename.txt",
"gain_ripple": "DFG_filename.txt",
"dgt": "DGT_filename.txt",
}
gain_flat = max flat gain (dB)
gain_min = min gain (dB) : will consider an input VOA if below (TBD vs throwing an exception)
p_max = max power (dBm)
nf_fit = boolean (True, False) :
if False nf_fit_coeff are ignored and nf_model fields are used
"""
input_json_file_name = "OA.json" #default path
output_json_file_name = "default_edfa_config.json"
param_field ="params"
gain_min_field = "gain_min"
gain_max_field = "gain_flatmax"
gain_ripple_field = "dfg"
gain_ripple_field = "gain_ripple"
nf_ripple_field = "nf_ripple"
nf_fit_coeff = "nf_fit_coeff"
nf_model_field = "nf_model"
nf_model_enabled_field = "enabled"
nf_min_field ="nf_min"
nf_max_field = "nf_max"
def read_file(field, file_name):
"""read and format the 96 channels txt files describing the amplifier NF and ripple
@@ -76,6 +58,7 @@ def read_file(field, file_name):
#consider ripple excursion only to avoid redundant information
#because the max flat_gain is already given by the 'gain_flat' field in json
#remove the mean component
print(file_name, ', mean value =', data.mean(), ' is substracted')
data = data - data.mean()
data = data.tolist()
return data

View File

@@ -1,313 +0,0 @@
{
"params": {
"gain_flatmax": 25,
"gain_min": 15,
"p_max": 21,
"nf_fit_coeff": [
0.000168241,
0.0469961,
0.0359549,
5.82851
],
"nf_ripple": [
-0.3110761646066259,
-0.3110761646066259,
-0.31110274831665313,
-0.31419329378173544,
-0.3172854168606314,
-0.32037911876162584,
-0.3233255190215882,
-0.31624321721895354,
-0.30915729645781326,
-0.30206775396360075,
-0.2949045115165272,
-0.26632156113294336,
-0.23772399031437283,
-0.20911178784023846,
-0.18048410390821285,
-0.14379944379052215,
-0.10709599992470213,
-0.07037375788020579,
-0.03372858157230583,
-0.015660302006048,
0.0024172385953583004,
0.020504047353947653,
0.03860013139908377,
0.05670549786742816,
0.07482015390297145,
0.0838762040768461,
0.09284481475528361,
0.1018180306253394,
0.11079585523492333,
0.1020395478432815,
0.09310160456603413,
0.08415906712621996,
0.07521193198077789,
0.0676340601339394,
0.06005437964543287,
0.052470799141237305,
0.044883315610536455,
0.037679759069084225,
0.03047647598902483,
0.02326948274513522,
0.01605877647020772,
0.021248462316134083,
0.02657315875107553,
0.03190060058247842,
0.03723078993416436,
0.04256372893215024,
0.047899419704645264,
0.03915515813685565,
0.030289222542492025,
0.021418708618354456,
0.012573926129294415,
0.006240488799898697,
-9.622162373026585e-05,
-0.006436207679519103,
-0.012779471908040341,
-0.02038153550619876,
-0.027999803010447587,
-0.035622012697103154,
-0.043236398934156144,
-0.04493583574805963,
-0.04663615264317309,
-0.048337350303318156,
-0.050039429413028365,
-0.051742390657545205,
-0.05342028484370278,
-0.05254242298580185,
-0.05166410580536087,
-0.05078533294804249,
-0.04990610405914272,
-0.05409792133358102,
-0.05832916277634124,
-0.06256260169582961,
-0.06660356886269536,
-0.04779792991567815,
-0.028982516728038848,
-0.010157321677553965,
0.00861320615127981,
0.01913736978785662,
0.029667009055877668,
0.04020212822983975,
0.050742731588695494,
0.061288823415841555,
0.07184040799914815,
0.1043252636301016,
0.13687829834471027,
0.1694483010211072,
0.202035284929368,
0.23624619427167134,
0.27048596623174515,
0.30474360397422756,
0.3390191214858807,
0.36358851509924695,
0.38814205928193013,
0.41270842850729195,
0.4372876328262819,
0.4372876328262819
],
"dgt": [
2.714526681131686,
2.705443819238505,
2.6947834587664494,
2.6841217449620203,
2.6681935771243177,
2.6521732021128046,
2.630396440815385,
2.602860350286428,
2.5696460593920065,
2.5364027376452056,
2.499446286796604,
2.4587748041127506,
2.414398437185221,
2.3699990328716107,
2.322373696229342,
2.271520771371253,
2.2174389328192197,
2.16337565384239,
2.1183028432496016,
2.082225099873648,
2.055100772005235,
2.0279625371819305,
2.0008103857988204,
1.9736443063300082,
1.9482128147680253,
1.9245345552113182,
1.9026104247588487,
1.8806927939516411,
1.862235672444246,
1.847275503201129,
1.835814081380705,
1.824381436842932,
1.8139629377087627,
1.8045606557581335,
1.7961751115773796,
1.7877868031023945,
1.7793941781790852,
1.7709972329654864,
1.7625959636196327,
1.7541903672600494,
1.7459181197626403,
1.737780757913635,
1.7297783508684146,
1.7217732861435076,
1.7137640932265894,
1.7057507692361864,
1.6918150918099673,
1.6719047669939942,
1.6460167077689267,
1.6201194134191075,
1.5986915141218316,
1.5817353179379183,
1.569199764184379,
1.5566577309558969,
1.545374152761467,
1.5353620432989845,
1.5266220576235803,
1.5178910621476225,
1.5097346239790443,
1.502153039909686,
1.495145456062699,
1.488134243479226,
1.48111939735681,
1.474100442252211,
1.4670307626366115,
1.4599103316162523,
1.45273959485914,
1.445565137158368,
1.4340878115214444,
1.418273806730323,
1.3981208704326855,
1.3779439775587023,
1.3598972673004606,
1.3439818461440451,
1.3301807335621048,
1.316383926863083,
1.3040618749785347,
1.2932153453410835,
1.2838336236692311,
1.2744470198196236,
1.2650555289898042,
1.2556591482982988,
1.2428104897182262,
1.2264996957264114,
1.2067249615595257,
1.1869318618366975,
1.1672278304018044,
1.1476135933863398,
1.1280891949729075,
1.108555289615659,
1.0895983485572227,
1.0712204022764056,
1.0534217504465226,
1.0356155337864215,
1.017807767853702,
1.0
],
"nf_model": {
"enabled": true,
"nf1": 5.727887800964238,
"nf2": 7.727887800964238,
"delta_p": 5.238350271545567
},
"gain_ripple": [
0.1359703369791596,
0.11822862697916037,
0.09542181697916163,
0.06245819697916133,
0.02602813697916062,
-0.0036199830208403228,
-0.018326963020840026,
-0.0246928330208398,
-0.016792253020838643,
-0.0028138630208403015,
0.017572956979162058,
0.038328296979159404,
0.054956336979159914,
0.0670723869791594,
0.07091459697916136,
0.07094413697916124,
0.07114372697916238,
0.07533675697916209,
0.08731066697916035,
0.10313984697916112,
0.12276252697916235,
0.14239527697916188,
0.15945681697916214,
0.1739275269791598,
0.1767381569791624,
0.17037189697916233,
0.15216302697916007,
0.13114358697916018,
0.10802383697916085,
0.08548825697916129,
0.06916723697916183,
0.05848224697916038,
0.05447361697916264,
0.05154489697916276,
0.04946107697915991,
0.04717897697916129,
0.04551704697916037,
0.04467697697916151,
0.04072968697916224,
0.03285456697916089,
0.023488786979161347,
0.01659282697915998,
0.013321846979160057,
0.011234826979162449,
0.01030063697916006,
0.00936596697916059,
0.00874012697916271,
0.00842583697916055,
0.006965146979162284,
0.0040435869791615175,
0.0007104669791608842,
-0.0015763130208377163,
-0.006936193020838033,
-0.016475303020840215,
-0.028748483020837767,
-0.039618433020837784,
-0.051112303020840244,
-0.06468462302083822,
-0.07868024302083754,
-0.09101254302083817,
-0.10103437302083762,
-0.11041488302083735,
-0.11916081302083725,
-0.12789859302083784,
-0.1353792530208402,
-0.14160178302083892,
-0.1455411330208385,
-0.1484450830208388,
-0.14823350302084037,
-0.14591937302083835,
-0.1409032730208395,
-0.13525493302083902,
-0.1279646530208396,
-0.11963431302083904,
-0.11089282302084058,
-0.1027863830208382,
-0.09717347302083823,
-0.09343261302083761,
-0.0913487130208388,
-0.08906007302083907,
-0.0865687230208394,
-0.08407607302083875,
-0.07844600302084004,
-0.06968090302083851,
-0.05947139302083926,
-0.05095282302083959,
-0.042428283020839785,
-0.03218106302083967,
-0.01819858302084043,
-0.0021726530208390216,
0.01393231697916164,
0.028098946979159933,
0.040326236979161934,
0.05257029697916238,
0.06479749697916048,
0.07704745697916238
]
}
}

View File

@@ -1,12 +1,22 @@
{ "Edfa":[{
"type_variety": "high_detail_model_example",
"type_def": "advanced_model",
"gain_flatmax": 25,
"gain_min": 15,
"p_max": 21,
"advanced_config_from_json": "std_medium_gain_advanced_config.json",
"out_voa_auto": false,
"allowed_for_design": false
},
}, {
"type_variety": "Juniper_BoosterHG",
"type_def": "advanced_model",
"gain_flatmax": 25,
"gain_min": 10,
"p_max": 21,
"advanced_config_from_json": "Juniper-BoosterHG.json",
"out_voa_auto": false,
"allowed_for_design": false
},
{
"type_variety": "operator_model_example",
"type_def": "variable_gain",
@@ -37,6 +47,17 @@
"allowed_for_design": false
},
{
"type_variety": "std_high_gain",
"type_def": "variable_gain",
"gain_flatmax": 35,
"gain_min": 25,
"p_max": 21,
"nf_min": 5.5,
"nf_max": 7,
"out_voa_auto": false,
"allowed_for_design": true
},
{
"type_variety": "std_medium_gain",
"type_def": "variable_gain",
"gain_flatmax": 26,
@@ -59,6 +80,17 @@
"allowed_for_design": true
},
{
"type_variety": "high_power",
"type_def": "variable_gain",
"gain_flatmax": 16,
"gain_min": 8,
"p_max": 25,
"nf_min": 9,
"nf_max": 15,
"out_voa_auto": false,
"allowed_for_design": false
},
{
"type_variety": "std_fixed_gain",
"type_def": "fixed_gain",
"gain_flatmax": 21,
@@ -66,7 +98,50 @@
"p_max": 21,
"nf0": 5.5,
"allowed_for_design": false
}
},
{
"type_variety": "4pumps_raman",
"type_def": "fixed_gain",
"gain_flatmax": 12,
"gain_min": 12,
"p_max": 21,
"nf0": -1,
"allowed_for_design": false
},
{
"type_variety": "hybrid_4pumps_lowgain",
"type_def": "dual_stage",
"raman": true,
"gain_min": 25,
"preamp_variety": "4pumps_raman",
"booster_variety": "std_low_gain",
"allowed_for_design": true
},
{
"type_variety": "hybrid_4pumps_mediumgain",
"type_def": "dual_stage",
"raman": true,
"gain_min": 25,
"preamp_variety": "4pumps_raman",
"booster_variety": "std_medium_gain",
"allowed_for_design": true
},
{
"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
},
{
"type_variety": "medium+high_power",
"type_def": "dual_stage",
"gain_min": 25,
"preamp_variety": "std_medium_gain",
"booster_variety": "high_power",
"allowed_for_design": false
}
],
"Fiber":[{
"type_variety": "SSMF",
@@ -84,9 +159,11 @@
"gamma": 0.000843
}
],
"Spans":[{
"Span":[{
"power_mode":true,
"delta_power_range_db": [0,0,0.5],
"delta_power_range_db": [-2,3,0.5],
"max_fiber_lineic_loss_for_raman": 0.25,
"target_extended_gain": 2.5,
"max_length": 150,
"length_units": "km",
"max_loss": 28,
@@ -96,10 +173,13 @@
"con_out": 0
}
],
"Roadms":[{
"gain_mode_default_loss": 20,
"power_mode_pout_target": -20,
"add_drop_osnr": 38
"Roadm":[{
"target_pch_out_db": -20,
"add_drop_osnr": 38,
"restrictions": {
"preamp_variety_list":["low_gain_preamp", "high_gain_preamp"],
"booster_variety_list":["std_booster"]
}
}],
"SI":[{
"f_min": 191.3e12,
@@ -107,10 +187,10 @@
"f_max":195.1e12,
"spacing": 50e9,
"power_dbm": 0,
"power_range_db": [0,0,0.5],
"power_range_db": [0,0,1],
"roll_off": 0.15,
"tx_osnr": 40,
"sys_margins": 0
"sys_margins": 2
}],
"Transceiver":[
{

View File

@@ -623,31 +623,473 @@
"con_in": null,
"con_out": null
}
},
{
"uid": "east edfa in Lannion_CAS to Corlay",
"metadata": {
"location": {
"city": "Lannion_CAS",
"region": "RLD",
"latitude": 2.0,
"longitude": 0.0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": null,
"delta_p": 1.0,
"tilt_target": 0,
"out_voa": null
}
},
{
"uid": "east edfa in Corlay to Loudeac",
"metadata": {
"location": {
"city": "Corlay",
"region": "RLD",
"latitude": 2.0,
"longitude": 1.0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": null,
"delta_p": 1.0,
"tilt_target": 0,
"out_voa": null
}
},
{
"uid": "east edfa in Loudeac to Lorient_KMA",
"metadata": {
"location": {
"city": "Loudeac",
"region": "RLD",
"latitude": 2.0,
"longitude": 2.0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": null,
"delta_p": 1.0,
"tilt_target": 0,
"out_voa": null
}
},
{
"uid": "east edfa in Lorient_KMA to Vannes_KBE",
"metadata": {
"location": {
"city": "Lorient_KMA",
"region": "RLD",
"latitude": 2.0,
"longitude": 3.0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": null,
"delta_p": 1.0,
"tilt_target": 0,
"out_voa": null
}
},
{
"uid": "east edfa in Lannion_CAS to Stbrieuc",
"metadata": {
"location": {
"city": "Lannion_CAS",
"region": "RLD",
"latitude": 2.0,
"longitude": 0.0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": null,
"delta_p": 1.0,
"tilt_target": 0,
"out_voa": null
}
},
{
"uid": "east edfa in Stbrieuc to Rennes_STA",
"metadata": {
"location": {
"city": "Stbrieuc",
"region": "RLD",
"latitude": 1.0,
"longitude": 0.0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": null,
"delta_p": 1.0,
"tilt_target": 0,
"out_voa": null
}
},
{
"uid": "east edfa in Lannion_CAS to Morlaix",
"metadata": {
"location": {
"city": "Lannion_CAS",
"region": "RLD",
"latitude": 2.0,
"longitude": 0.0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": null,
"delta_p": 1.0,
"tilt_target": 0,
"out_voa": null
}
},
{
"uid": "east edfa in Lorient_KMA to Loudeac",
"metadata": {
"location": {
"city": "Lorient_KMA",
"region": "RLD",
"latitude": 2.0,
"longitude": 3.0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": null,
"delta_p": 1.0,
"tilt_target": 0,
"out_voa": null
}
},
{
"uid": "east edfa in Vannes_KBE to Lorient_KMA",
"metadata": {
"location": {
"city": "Vannes_KBE",
"region": "RLD",
"latitude": 2.0,
"longitude": 4.0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": null,
"delta_p": 1.0,
"tilt_target": 0,
"out_voa": null
}
},
{
"uid": "east edfa in Rennes_STA to Stbrieuc",
"metadata": {
"location": {
"city": "Rennes_STA",
"region": "RLD",
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": null,
"delta_p": 1.0,
"tilt_target": 0,
"out_voa": null
}
},
{
"uid": "east edfa in Brest_KLA to Morlaix",
"metadata": {
"location": {
"city": "Brest_KLA",
"region": "RLD",
"latitude": 4.0,
"longitude": 0.0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": null,
"delta_p": 1.0,
"tilt_target": 0,
"out_voa": null
}
},
{
"uid": "west edfa in Lannion_CAS to Corlay",
"metadata": {
"location": {
"city": "Lannion_CAS",
"region": "RLD",
"latitude": 2.0,
"longitude": 0.0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": null,
"delta_p": 1.0,
"tilt_target": 0,
"out_voa": null
}
},
{
"uid": "west edfa in Corlay to Loudeac",
"metadata": {
"location": {
"city": "Corlay",
"region": "RLD",
"latitude": 2.0,
"longitude": 1.0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": null,
"delta_p": 1.0,
"tilt_target": 0,
"out_voa": null
}
},
{
"uid": "west edfa in Loudeac to Lorient_KMA",
"metadata": {
"location": {
"city": "Loudeac",
"region": "RLD",
"latitude": 2.0,
"longitude": 2.0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": null,
"delta_p": 1.0,
"tilt_target": 0,
"out_voa": null
}
},
{
"uid": "west edfa in Lorient_KMA to Vannes_KBE",
"metadata": {
"location": {
"city": "Lorient_KMA",
"region": "RLD",
"latitude": 2.0,
"longitude": 3.0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": null,
"delta_p": 1.0,
"tilt_target": 0,
"out_voa": null
}
},
{
"uid": "west edfa in Lannion_CAS to Stbrieuc",
"metadata": {
"location": {
"city": "Lannion_CAS",
"region": "RLD",
"latitude": 2.0,
"longitude": 0.0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": null,
"delta_p": 1.0,
"tilt_target": 0,
"out_voa": null
}
},
{
"uid": "west edfa in Stbrieuc to Rennes_STA",
"metadata": {
"location": {
"city": "Stbrieuc",
"region": "RLD",
"latitude": 1.0,
"longitude": 0.0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": null,
"delta_p": 1.0,
"tilt_target": 0,
"out_voa": null
}
},
{
"uid": "west edfa in Lannion_CAS to Morlaix",
"metadata": {
"location": {
"city": "Lannion_CAS",
"region": "RLD",
"latitude": 2.0,
"longitude": 0.0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": null,
"delta_p": 1.0,
"tilt_target": 0,
"out_voa": null
}
},
{
"uid": "west edfa in Lorient_KMA to Loudeac",
"metadata": {
"location": {
"city": "Lorient_KMA",
"region": "RLD",
"latitude": 2.0,
"longitude": 3.0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": null,
"delta_p": 1.0,
"tilt_target": 0,
"out_voa": null
}
},
{
"uid": "west edfa in Vannes_KBE to Lorient_KMA",
"metadata": {
"location": {
"city": "Vannes_KBE",
"region": "RLD",
"latitude": 2.0,
"longitude": 4.0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": null,
"delta_p": 1.0,
"tilt_target": 0,
"out_voa": null
}
},
{
"uid": "west edfa in Rennes_STA to Stbrieuc",
"metadata": {
"location": {
"city": "Rennes_STA",
"region": "RLD",
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": null,
"delta_p": 1.0,
"tilt_target": 0,
"out_voa": null
}
},
{
"uid": "west edfa in Brest_KLA to Morlaix",
"metadata": {
"location": {
"city": "Brest_KLA",
"region": "RLD",
"latitude": 4.0,
"longitude": 0.0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": null,
"delta_p": 1.0,
"tilt_target": 0,
"out_voa": null
}
}
],
"connections": [
{
"from_node": "roadm Lannion_CAS",
"to_node": "east edfa in Lannion_CAS to Corlay"
},
{
"from_node": "east edfa in Lannion_CAS to Corlay",
"to_node": "fiber (Lannion_CAS → Corlay)-F061"
},
{
"from_node": "fiber (Corlay → Lannion_CAS)-F061",
"to_node": "west edfa in Lannion_CAS to Corlay"
},
{
"from_node": "west edfa in Lannion_CAS to Corlay",
"to_node": "roadm Lannion_CAS"
},
{
"from_node": "roadm Lannion_CAS",
"to_node": "east edfa in Lannion_CAS to Stbrieuc"
},
{
"from_node": "east edfa in Lannion_CAS to Stbrieuc",
"to_node": "fiber (Lannion_CAS → Stbrieuc)-F056"
},
{
"from_node": "fiber (Stbrieuc → Lannion_CAS)-F056",
"to_node": "west edfa in Lannion_CAS to Stbrieuc"
},
{
"from_node": "west edfa in Lannion_CAS to Stbrieuc",
"to_node": "roadm Lannion_CAS"
},
{
"from_node": "roadm Lannion_CAS",
"to_node": "east edfa in Lannion_CAS to Morlaix"
},
{
"from_node": "east edfa in Lannion_CAS to Morlaix",
"to_node": "fiber (Lannion_CAS → Morlaix)-F059"
},
{
"from_node": "fiber (Morlaix → Lannion_CAS)-F059",
"to_node": "west edfa in Lannion_CAS to Morlaix"
},
{
"from_node": "west edfa in Lannion_CAS to Morlaix",
"to_node": "roadm Lannion_CAS"
},
{
@@ -684,18 +1126,34 @@
},
{
"from_node": "roadm Lorient_KMA",
"to_node": "east edfa in Lorient_KMA to Loudeac"
},
{
"from_node": "east edfa in Lorient_KMA to Loudeac",
"to_node": "fiber (Lorient_KMA → Loudeac)-F054"
},
{
"from_node": "fiber (Loudeac → Lorient_KMA)-F054",
"to_node": "west edfa in Lorient_KMA to Loudeac"
},
{
"from_node": "west edfa in Lorient_KMA to Loudeac",
"to_node": "roadm Lorient_KMA"
},
{
"from_node": "roadm Lorient_KMA",
"to_node": "east edfa in Lorient_KMA to Vannes_KBE"
},
{
"from_node": "east edfa in Lorient_KMA to Vannes_KBE",
"to_node": "fiber (Lorient_KMA → Vannes_KBE)-F055"
},
{
"from_node": "fiber (Vannes_KBE → Lorient_KMA)-F055",
"to_node": "west edfa in Lorient_KMA to Vannes_KBE"
},
{
"from_node": "west edfa in Lorient_KMA to Vannes_KBE",
"to_node": "roadm Lorient_KMA"
},
{
@@ -708,10 +1166,18 @@
},
{
"from_node": "roadm Vannes_KBE",
"to_node": "east edfa in Vannes_KBE to Lorient_KMA"
},
{
"from_node": "east edfa in Vannes_KBE to Lorient_KMA",
"to_node": "fiber (Vannes_KBE → Lorient_KMA)-F055"
},
{
"from_node": "fiber (Lorient_KMA → Vannes_KBE)-F055",
"to_node": "west edfa in Vannes_KBE to Lorient_KMA"
},
{
"from_node": "west edfa in Vannes_KBE to Lorient_KMA",
"to_node": "roadm Vannes_KBE"
},
{
@@ -724,18 +1190,34 @@
},
{
"from_node": "fiber (Lannion_CAS → Stbrieuc)-F056",
"to_node": "east edfa in Stbrieuc to Rennes_STA"
},
{
"from_node": "east edfa in Stbrieuc to Rennes_STA",
"to_node": "fiber (Stbrieuc → Rennes_STA)-F057"
},
{
"from_node": "fiber (Rennes_STA → Stbrieuc)-F057",
"to_node": "west edfa in Stbrieuc to Rennes_STA"
},
{
"from_node": "west edfa in Stbrieuc to Rennes_STA",
"to_node": "fiber (Stbrieuc → Lannion_CAS)-F056"
},
{
"from_node": "roadm Rennes_STA",
"to_node": "east edfa in Rennes_STA to Stbrieuc"
},
{
"from_node": "east edfa in Rennes_STA to Stbrieuc",
"to_node": "fiber (Rennes_STA → Stbrieuc)-F057"
},
{
"from_node": "fiber (Stbrieuc → Rennes_STA)-F057",
"to_node": "west edfa in Rennes_STA to Stbrieuc"
},
{
"from_node": "west edfa in Rennes_STA to Stbrieuc",
"to_node": "roadm Rennes_STA"
},
{
@@ -764,10 +1246,18 @@
},
{
"from_node": "roadm Brest_KLA",
"to_node": "east edfa in Brest_KLA to Morlaix"
},
{
"from_node": "east edfa in Brest_KLA to Morlaix",
"to_node": "fiber (Brest_KLA → Morlaix)-F060"
},
{
"from_node": "fiber (Morlaix → Brest_KLA)-F060",
"to_node": "west edfa in Brest_KLA to Morlaix"
},
{
"from_node": "west edfa in Brest_KLA to Morlaix",
"to_node": "roadm Brest_KLA"
},
{

Binary file not shown.

View File

@@ -23,7 +23,7 @@ from networkx import (draw_networkx_nodes, draw_networkx_edges,
from numpy import mean
from gnpy.core.service_sheet import convert_service_sheet, Request_element, Element
from gnpy.core.utils import load_json
from gnpy.core.network import load_network, build_network, set_roadm_loss, save_network
from gnpy.core.network import load_network, build_network, save_network
from gnpy.core.equipment import load_equipment, trx_mode_params, automatic_nch, automatic_spacing
from gnpy.core.elements import Transceiver, Roadm, Edfa, Fused, Fiber
from gnpy.core.utils import db2lin, lin2db

View File

@@ -4,6 +4,8 @@
0.0359549,
5.82851
],
"f_min": 191.35e12,
"f_max": 196.1e12,
"nf_ripple": [
-0.3110761646066259,
-0.3110761646066259,

View File

@@ -106,8 +106,8 @@ def main(network, equipment, source, destination, req = None):
}]
result_dicts.update({'network': network_data})
design_data = [{
'power_mode' : equipment['Spans']['default'].power_mode,
'span_power_range' : equipment['Spans']['default'].delta_power_range_db,
'power_mode' : equipment['Span']['default'].power_mode,
'span_power_range' : equipment['Span']['default'].delta_power_range_db,
'design_pch' : equipment['SI']['default'].power_dbm,
'baud_rate' : equipment['SI']['default'].baud_rate
}]
@@ -115,9 +115,9 @@ def main(network, equipment, source, destination, req = None):
simulation_data = []
result_dicts.update({'simulation results': simulation_data})
power_mode = equipment['Spans']['default'].power_mode
power_mode = equipment['Span']['default'].power_mode
print('\n'.join([f'Power mode is set to {power_mode}',
f'=> it can be modified in eqpt_config.json - Spans']))
f'=> it can be modified in eqpt_config.json - Span']))
pref_ch_db = lin2db(req.power*1e3) #reference channel power / span (SL=20dB)
pref_total_db = pref_ch_db + lin2db(req.nb_channel) #reference total power / span (SL=20dB)
@@ -136,25 +136,44 @@ def main(network, equipment, source, destination, req = None):
print('invalid power range definition in eqpt_config, should be power_range_db: [lower, upper, step]')
power_range = [0]
if not power_mode:
#power cannot be changed in gain mode
power_range = [0]
for dp_db in power_range:
req.power = db2lin(pref_ch_db + dp_db)*1e-3
print(f'\nPropagating with input power = {lin2db(req.power*1e3):.2f}dBm :')
if power_mode:
print(f'\nPropagating with input power = {lin2db(req.power*1e3):.2f}dBm :')
else:
print(f'\nPropagating in gain mode: power cannot be set manually')
infos = propagate2(path, req, equipment, show=len(power_range)==1)
print(f'\nTransmission result for input power = {lin2db(req.power*1e3):.2f}dBm :')
if power_mode:
print(f'\nTransmission result for input power = {lin2db(req.power*1e3):.2f}dBm :')
else:
print(f'\nTransmission results:')
#info message in gain mode
print(destination)
#print(f'\n !!!!!!!!!!!!!!!!! TEST POINT !!!!!!!!!!!!!!!!!!!!!')
#print(f'carriers ase output of {path[1]} =\n {list(path[1].carriers("out", "nli"))}')
# => use "in" or "out" parameter
# => use "nli" or "ase" or "signal" or "total" parameter
simulation_data.append({
'Pch_dBm' : pref_ch_db + dp_db,
'OSNR_ASE_0.1nm' : round(mean(destination.osnr_ase_01nm),2),
'OSNR_ASE_signal_bw' : round(mean(destination.osnr_ase),2),
'SNR_nli_signal_bw' : round(mean(destination.osnr_nli),2),
'SNR_total_signal_bw' : round(mean(destination.snr),2)
})
# => use "nli" or "ase" or "signal" or "total" parameter
if power_mode:
simulation_data.append({
'Pch_dBm' : pref_ch_db + dp_db,
'OSNR_ASE_0.1nm' : round(mean(destination.osnr_ase_01nm),2),
'OSNR_ASE_signal_bw' : round(mean(destination.osnr_ase),2),
'SNR_nli_signal_bw' : round(mean(destination.osnr_nli),2),
'SNR_total_signal_bw' : round(mean(destination.snr),2)
})
else:
simulation_data.append({
'gain_mode' : 'power canot be set',
'OSNR_ASE_0.1nm' : round(mean(destination.osnr_ase_01nm),2),
'OSNR_ASE_signal_bw' : round(mean(destination.osnr_ase),2),
'SNR_nli_signal_bw' : round(mean(destination.osnr_nli),2),
'SNR_total_signal_bw' : round(mean(destination.snr),2)
})
#info message in gain mode
write_csv(result_dicts, 'simulation_result.csv')
return path, infos

View File

@@ -111,11 +111,12 @@ class Eqpt(object):
{
'from_city': '',
'to_city': '',
'east_amp_type': '',
'east_att_in': 0,
'east_amp_gain': 0,
'east_tilt': 0,
'east_att_out': 0
'east_amp_type': '',
'east_att_in': 0,
'east_amp_gain': None,
'east_amp_dp': None,
'east_tilt': 0,
'east_att_out': None
}
@@ -163,8 +164,8 @@ def parse_headers(my_sheet, input_headers_dict, headers, start_line, slice_in):
slice_out = read_slice(my_sheet, start_line+iteration, slice_in, h0)
iteration += 1
if slice_out == (-1, -1):
if h0 == 'east':
print(f'\x1b[1;31;40m'+f'CRITICAL: missing _east_ header above other headers (hierarchical) _ ABORT'+ '\x1b[0m')
if h0 in ('east', 'Node A', 'Node Z', 'City') :
print(f'\x1b[1;31;40m'+f'CRITICAL: missing _{h0}_ header: EXECUTION ENDS'+ '\x1b[0m')
exit()
else:
print(f'missing header {h0}')
@@ -344,6 +345,7 @@ def convert_file(input_filename, names_matching=False, filter_region=[]):
'type': 'Edfa',
'type_variety': e.east_amp_type,
'operational': {'gain_target': e.east_amp_gain,
'delta_p': e.east_amp_dp,
'tilt_target': e.east_tilt,
'out_voa' : e.east_att_out}
}
@@ -356,6 +358,7 @@ def convert_file(input_filename, names_matching=False, filter_region=[]):
'type': 'Edfa',
'type_variety': e.west_amp_type,
'operational': {'gain_target': e.west_amp_gain,
'delta_p': e.west_amp_dp,
'tilt_target': e.west_tilt,
'out_voa' : e.west_att_out}
}
@@ -420,6 +423,7 @@ def parse_excel(input_filename):
'amp type': 'east_amp_type',
'att_in': 'east_att_in',
'amp gain': 'east_amp_gain',
'delta p': 'east_amp_dp',
'tilt': 'east_tilt',
'att_out': 'east_att_out'
},
@@ -427,6 +431,7 @@ def parse_excel(input_filename):
'amp type': 'west_amp_type',
'att_in': 'west_att_in',
'amp gain': 'west_amp_gain',
'delta p': 'west_amp_dp',
'tilt': 'west_tilt',
'att_out': 'west_att_out'
}
@@ -566,12 +571,12 @@ def midpoint(city_a, city_b):
#output_json_file_name = 'coronet_conus_example.json'
#TODO get column size automatically from tupple size
NODES_COLUMN = 7
NODES_COLUMN = 8
NODES_LINE = 4
LINKS_COLUMN = 16
LINKS_LINE = 3
EQPTS_LINE = 3
EQPTS_COLUMN = 12
EQPTS_COLUMN = 14
parser = ArgumentParser()
parser.add_argument('workbook', nargs='?', type=Path , default='meshTopologyExampleV2.xls')
parser.add_argument('-f', '--filter-region', action='append', default=[])

View File

@@ -25,7 +25,7 @@ from collections import namedtuple
from gnpy.core.node import Node
from gnpy.core.units import UNITS
from gnpy.core.utils import lin2db, db2lin, itufs, snr_sum
from gnpy.core.utils import lin2db, db2lin, itufs, itufl, snr_sum
class Transceiver(Node):
def __init__(self, *args, **kwargs):
@@ -41,7 +41,6 @@ class Transceiver(Node):
with errstate(divide='ignore'):
self.baud_rate = [c.baud_rate for c in spectral_info.carriers]
ratio_01nm = [lin2db(12.5e9/b_rate) for b_rate in self.baud_rate]
#set raw values to record original calculation, before update_snr()
self.raw_osnr_ase = [lin2db(divide(c.power.signal, c.power.ase))
for c in spectral_info.carriers]
@@ -51,11 +50,14 @@ class Transceiver(Node):
for c in spectral_info.carriers]
self.raw_snr = [lin2db(divide(c.power.signal, c.power.nli+c.power.ase))
for c in spectral_info.carriers]
self.raw_snr_01nm = [snr - ratio for snr, ratio
in zip(self.raw_snr, ratio_01nm)]
self.osnr_ase = self.raw_osnr_ase
self.osnr_ase_01nm = self.raw_osnr_ase_01nm
self.osnr_nli = self.raw_osnr_nli
self.snr = self.raw_snr
self.snr_01nm = self.raw_snr_01nm
def update_snr(self, *args):
"""
@@ -75,6 +77,8 @@ class Transceiver(Node):
self.raw_snr, self.baud_rate))
self.osnr_ase_01nm = list(map(lambda x:snr_sum(x,12.5e9,snr_added),
self.raw_osnr_ase_01nm))
self.snr_01nm = list(map(lambda x:snr_sum(x,12.5e9,snr_added),
self.raw_snr_01nm))
@property
def to_json(self):
@@ -100,37 +104,34 @@ class Transceiver(Node):
snr = round(mean(self.snr),2)
osnr_ase = round(mean(self.osnr_ase),2)
osnr_ase_01nm = round(mean(self.osnr_ase_01nm), 2)
snr_01nm = round(mean(self.snr_01nm),2)
return '\n'.join([f'{type(self).__name__} {self.uid}',
f' OSNR ASE (0.1nm, dB): {osnr_ase_01nm:.2f}',
f' OSNR ASE (signal bw, dB): {osnr_ase:.2f}',
f' SNR total (signal bw, dB): {snr:.2f}'])
f' SNR total (signal bw, dB): {snr:.2f}',
f' SNR total (0.1nm, dB): {snr_01nm:.2f}'])
def __call__(self, spectral_info):
self._calc_snr(spectral_info)
return spectral_info
RoadmParams = namedtuple('RoadmParams', 'loss')
RoadmParams = namedtuple('RoadmParams', 'target_pch_out_db add_drop_osnr')
class Roadm(Node):
def __init__(self, *args, params=None, **kwargs):
if params is None:
# default loss value if not mentioned in loaded network json
params = {'loss':None}
def __init__(self, *args, params, **kwargs):
super().__init__(*args, params=RoadmParams(**params), **kwargs)
self.loss = self.params.loss
self.target_pch_out_db = None #set in Networks.py by def set_roadm_loss
self.effective_pch_out_db = None
self.effective_loss = None #set in self.propagate
self.loss = 0 #auto-design interest
self.effective_loss = None
self.effective_pch_out_db = self.params.target_pch_out_db
self.passive = True
@property
def to_json(self):
return {'uid' : self.uid,
'type' : type(self).__name__,
'params' : {'loss' : self.loss},
'params' : {'target_pch_out_db' : self.effective_pch_out_db},
'metadata' : {
'location': self.metadata['location']._asdict()
}
@@ -141,26 +142,25 @@ class Roadm(Node):
def __str__(self):
return '\n'.join([f'{type(self).__name__} {self.uid}',
f' loss (dB): {self.effective_loss:.2f}',
f' pch out (dBm): {self.effective_pch_out_db!r}'])
f' effective loss (dB): {self.effective_loss:.2f}',
f' pch out (dBm): {self.effective_pch_out_db!r}'])
def propagate(self, pref, *carriers):
#pin_target and loss are read from eqpt_config.json['Roadm']
#all ingress channels in xpress are set to this power level
#but add channels are not, so we define an effective loss
#in the case of add channels
if self.target_pch_out_db:
self.effective_loss = pref.pi - self.target_pch_out_db
else:
self.effective_loss = self.loss
self.effective_pch_out_db = pref.pi - self.effective_loss
attenuation = db2lin(self.effective_loss)
for carrier in carriers:
self.effective_pch_out_db = min(pref.pi, self.params.target_pch_out_db)
self.effective_loss = pref.pi - self.effective_pch_out_db
carriers_power = array([c.power.signal +c.power.nli+c.power.ase for c in carriers])
carriers_att = list(map(lambda x : lin2db(x*1e3)-self.params.target_pch_out_db, carriers_power))
exceeding_att = -min(list(filter(lambda x: x < 0, carriers_att)), default = 0)
carriers_att = list(map(lambda x: db2lin(x+exceeding_att), carriers_att))
for carrier_att, carrier in zip(carriers_att, carriers) :
pwr = carrier.power
pwr = pwr._replace(signal=pwr.signal/attenuation,
nonlinear_interference=pwr.nli/attenuation,
amplified_spontaneous_emission=pwr.ase/attenuation)
pwr = pwr._replace( signal = pwr.signal/carrier_att,
nonlinear_interference = pwr.nli/carrier_att,
amplified_spontaneous_emission = pwr.ase/carrier_att)
yield carrier._replace(power=pwr)
def update_pref(self, pref):
@@ -430,16 +430,16 @@ class EdfaParams:
if params == {}:
self.type_variety = ''
self.type_def = ''
self.gain_flatmax = 0
self.gain_min = 0
self.p_max = 0
self.nf_model = None
self.nf_fit_coeff = None
self.nf_ripple = None
self.dgt = None
self.gain_ripple = None
self.out_voa_auto = False
self.allowed_for_design = None
# self.gain_flatmax = 0
# self.gain_min = 0
# self.p_max = 0
# self.nf_model = None
# self.nf_fit_coeff = None
# self.nf_ripple = None
# self.dgt = None
# self.gain_ripple = None
# self.out_voa_auto = False
# self.allowed_for_design = None
def update_params(self, kwargs):
for k,v in kwargs.items() :
@@ -447,10 +447,22 @@ class EdfaParams:
if isinstance(v, dict) else v)
class EdfaOperational:
def __init__(self, gain_target, tilt_target, out_voa=None):
self.gain_target = gain_target
self.tilt_target = tilt_target
self.out_voa = out_voa
default_values = \
{
'gain_target': None,
'delta_p': None,
'out_voa': None,
'tilt_target': 0
}
def __init__(self, **operational):
self.update_attr(operational)
def update_attr(self, kwargs):
clean_kwargs = {k:v for k,v in kwargs.items() if v !=''}
for k,v in self.default_values.items():
setattr(self, k, clean_kwargs.get(k,v))
def __repr__(self):
return (f'{type(self).__name__}('
f'gain_target={self.gain_target!r}, '
@@ -479,14 +491,16 @@ class Edfa(Node):
self.pin_db = None
self.nch = None
self.pout_db = None
self.dp_db = None #delta P with Pref (power swwep) in power mode
self.target_pch_out_db = None
self.effective_pch_out_db = None
self.passive = False
self.effective_gain = self.operational.gain_target
self.att_in = None
self.carriers_in = None
self.carriers_out = None
self.effective_gain = self.operational.gain_target
self.delta_p = self.operational.delta_p #delta P with Pref (power swwep) in power mode
self.tilt_target = self.operational.tilt_target
self.out_voa = self.operational.out_voa
@property
def to_json(self):
@@ -494,9 +508,10 @@ class Edfa(Node):
'type' : type(self).__name__,
'type_variety' : self.params.type_variety,
'operational' : {
'gain_target' : self.operational.gain_target,
'tilt_target' : self.operational.tilt_target,
'out_voa' : self.operational.out_voa
'gain_target' : self.effective_gain,
'delta_p' : self.delta_p,
'tilt_target' : self.tilt_target,
'out_voa' : self.out_voa
},
'metadata' : {
'location': self.metadata['location']._asdict()
@@ -528,10 +543,10 @@ class Edfa(Node):
f' pad att_in (dB): {self.att_in:.2f}',
f' Power In (dBm): {self.pin_db:.2f}',
f' Power Out (dBm): {self.pout_db:.2f}',
f' Delta_P (dB): {self.dp_db!r}',
f' Delta_P (dB): {self.delta_p!r}',
f' target pch (dBm): {self.target_pch_out_db!r}',
f' effective pch (dBm): {self.effective_pch_out_db!r}',
f' output VOA (dB): {self.operational.out_voa:.2f}'])
f' output VOA (dB): {self.out_voa:.2f}'])
def carriers(self, loc, attr):
"""retrieve carriers information
@@ -558,61 +573,104 @@ class Edfa(Node):
self.channel_freq, self.nf, self.interpol_dgt and self.interpol_gain_ripple
"""
# TODO|jla: read amplifier actual frequencies from additional params in json
amplifier_freq = itufs(0.05) * 1e12 # Hz
amplifier_freq = itufl(len(self.params.dgt), self.params.f_min, self.params.f_max) * 1e12 # Hz
self.channel_freq = frequencies
self.interpol_dgt = interp(self.channel_freq, amplifier_freq, self.params.dgt)
self.interpol_gain_ripple = interp(self.channel_freq, amplifier_freq, self.params.gain_ripple)
self.interpol_nf_ripple =interp(self.channel_freq, amplifier_freq, self.params.nf_ripple)
self.nch = frequencies.size
self.pin_db = lin2db(sum(pin*1e3))
"""in power mode: dp_db is defined and can be used to calculate the power target
"""in power mode: delta_p is defined and can be used to calculate the power target
This power target is used calculate the amplifier gain"""
if self.dp_db is not None:
self.target_pch_out_db = round(self.dp_db + pref.p0, 2)
if self.delta_p is not None:
self.target_pch_out_db = round(self.delta_p + pref.p0, 2)
self.effective_gain = self.target_pch_out_db - pref.pi
else:
self.effective_gain = self.operational.gain_target
"""check power saturation and correct target_gain accordingly:"""
self.effective_gain = min(self.effective_gain, self.params.p_max - self.pin_db)
"""check power saturation and correct effective gain & power accordingly:"""
self.effective_gain = min(
self.effective_gain,
self.params.p_max - (pref.pi + pref.neq_ch)
)
#print(self.uid, self.effective_gain, self.operational.gain_target)
self.effective_pch_out_db = round(pref.pi + self.effective_gain, 2)
"""check power saturation and correct target_gain accordingly:"""
#print(self.uid, self.effective_gain, self.pin_db, pref.pi)
self.nf = self._calc_nf()
self.gprofile = self._gain_profile(pin)
pout = (pin + self.noise_profile(baud_rates))*db2lin(self.gprofile)
self.pout_db = lin2db(sum(pout*1e3))
self.operational.gain_target = self.effective_gain
# ase & nli are only calculated in signal bandwidth
# pout_db is not the absolute full output power (negligible if sufficient channels)
def _nf(self, type_def, nf_model, nf_fit_coeff, gain_min, gain_flatmax, gain_target):
#if hybrid raman, use edfa_gain_flatmax attribute, else use gain_flatmax
#gain_flatmax = getattr(params, 'edfa_gain_flatmax', params.gain_flatmax)
pad = max(gain_min - gain_target, 0)
gain_target += pad
dg = max(gain_flatmax - gain_target, 0)
if type_def == 'variable_gain':
g1a = gain_target - nf_model.delta_p - dg
nf_avg = lin2db(db2lin(nf_model.nf1) + db2lin(nf_model.nf2)/db2lin(g1a))
elif type_def == 'fixed_gain':
nf_avg = nf_model.nf0
elif type_def == 'openroadm':
pin_ch = self.pin_db - lin2db(self.nch)
# model OSNR = f(Pin)
nf_avg = pin_ch - polyval(nf_model.nf_coef, pin_ch) + 58
elif type_def == 'advanced_model':
nf_avg = polyval(nf_fit_coeff, -dg)
else :
print(
f'\x1b[1;31;40m'\
+ f'CRITICAL: unrecognized type def _{self.params.type_def}_\n\
=> please check eqpt_config.json'\
+ '\x1b[0m'
)
exit()
return nf_avg+pad, pad
def _calc_nf(self, avg = False):
"""nf calculation based on 2 models: self.params.nf_model.enabled from json import:
True => 2 stages amp modelling based on precalculated nf1, nf2 and delta_p in build_OA_json
False => polynomial fit based on self.params.nf_fit_coeff"""
# TODO|jla: TBD alarm rising or input VOA padding in case
# gain_min > gain_target TBD:
pad = max(self.params.gain_min - self.effective_gain, 0)
self.att_in = pad
gain_target = self.effective_gain + pad
dg = max(self.params.gain_flatmax - gain_target, 0)
if self.params.type_def == 'variable_gain':
g1a = gain_target - self.params.nf_model.delta_p - dg
nf_avg = lin2db(db2lin(self.params.nf_model.nf1) + db2lin(self.params.nf_model.nf2)/db2lin(g1a))
elif self.params.type_def == 'fixed_gain':
nf_avg = self.params.nf_model.nf0
elif self.params.type_def == 'openroadm':
pin_ch = self.pin_db - lin2db(self.nch)
# model OSNR = f(Pin)
nf_avg = pin_ch - polyval(self.params.nf_model.nf_coef, pin_ch) + 58
else:
nf_avg = polyval(self.params.nf_fit_coeff, -dg)
if self.params.type_def == 'dual_stage':
g1 = self.params.preamp_gain_flatmax
g2 = self.effective_gain - g1
nf1_avg, pad = self._nf( self.params.preamp_type_def,
self.params.preamp_nf_model,
self.params.preamp_nf_fit_coeff,
self.params.preamp_gain_min,
self.params.preamp_gain_flatmax,
g1)
#no padding expected for the 1stage because g1 = gain_max
nf2_avg, pad = self._nf( self.params.booster_type_def,
self.params.booster_nf_model,
self.params.booster_nf_fit_coeff,
self.params.booster_gain_min,
self.params.booster_gain_flatmax,
g2)
nf_avg = lin2db(db2lin(nf1_avg) + db2lin(nf2_avg-g1))
#no padding expected for the 1stage because g1 = gain_max
pad = 0
else:
nf_avg, pad = self._nf( self.params.type_def,
self.params.nf_model,
self.params.nf_fit_coeff,
self.params.gain_min,
self.params.gain_flatmax,
self.effective_gain)
self.att_in = pad # not used to attenuate carriers, only used in _repr_ and _str_
if avg:
return nf_avg + pad
return nf_avg
else:
return self.interpol_nf_ripple + nf_avg + pad # input VOA = 1 for 1 NF degradation
return self.interpol_nf_ripple + nf_avg # input VOA = 1 for 1 NF degradation
def noise_profile(self, df):
""" noise_profile(bw) computes amplifier ase (W) in signal bw (Hz)
@@ -705,7 +763,7 @@ class Edfa(Node):
# Calculate the target slope - currently assumes equal spaced channels
# TODO|jla: support arbitrary channel spacing
targ_slope = self.operational.tilt_target / (len(nb_channel) - 1)
targ_slope = self.tilt_target / (len(nb_channel) - 1)
# first estimate of DGT scaling
if abs(dgt_slope) > 0.001: # check for zero value due to flat dgt
@@ -779,7 +837,7 @@ class Edfa(Node):
gains = db2lin(self.gprofile)
carrier_ases = self.noise_profile(brate)
att = db2lin(self.operational.out_voa)
att = db2lin(self.out_voa)
for gain, carrier_ase, carrier in zip(gains, carrier_ases, carriers):
pwr = carrier.power
@@ -790,7 +848,7 @@ class Edfa(Node):
def update_pref(self, pref):
return pref._replace(p_span0=pref.p0,
p_spani=pref.pi + self.effective_gain - self.operational.out_voa)
p_spani=pref.pi + self.effective_gain - self.out_voa)
def __call__(self, spectral_info):
self.carriers_in = spectral_info.carriers

View File

@@ -17,44 +17,126 @@ from json import load
from gnpy.core.utils import lin2db, db2lin, load_json
from collections import namedtuple
from gnpy.core.elements import Edfa
import time
Model_vg = namedtuple('Model_vg', 'nf1 nf2 delta_p')
Model_fg = namedtuple('Model_fg', 'nf0')
Model_openroadm = namedtuple('Model_openroadm', 'nf_coef')
Fiber = namedtuple('Fiber', 'type_variety dispersion gamma')
Spans = namedtuple('Spans', 'power_mode delta_power_range_db max_length length_units \
max_loss padding EOL con_in con_out')
Transceiver = namedtuple('Transceiver', 'type_variety frequency mode')
Roadms = namedtuple('Roadms', 'gain_mode_default_loss power_mode_pout_target add_drop_osnr')
SI = namedtuple('SI', 'f_min f_max baud_rate spacing roll_off \
power_dbm power_range_db tx_osnr sys_margins')
AmpBase = namedtuple(
'AmpBase',
'type_variety type_def gain_flatmax gain_min p_max'
' nf_model nf_fit_coeff nf_ripple dgt gain_ripple out_voa_auto allowed_for_design')
class Amp(AmpBase):
def __new__(cls,
type_variety, type_def, gain_flatmax, gain_min, p_max, nf_model=None,
nf_fit_coeff=None, nf_ripple=None, dgt=None, gain_ripple=None,
out_voa_auto=False, allowed_for_design=True):
return super().__new__(cls,
type_variety, type_def, gain_flatmax, gain_min, p_max,
nf_model, nf_fit_coeff, nf_ripple, dgt, gain_ripple,
out_voa_auto, allowed_for_design)
Model_hybrid = namedtuple('Model_hybrid', 'nf_ram gain_ram edfa_variety')
Model_dual_stage = namedtuple('Model_dual_stage', 'preamp_variety booster_variety')
class common:
def update_attr(self, default_values, kwargs, name):
clean_kwargs = {k:v for k,v in kwargs.items() if v !=''}
for k,v in default_values.items():
setattr(self, k, clean_kwargs.get(k,v))
if k not in clean_kwargs and name != 'Amp' :
print(f'\x1b[1;31;40m'+
f'\n WARNING missing {k} attribute in eqpt_config.json[{name}]'
f'\n default value is {k} = {v}'
+ '\x1b[0m')
time.sleep(1)
class SI(common):
default_values =\
{
"f_min": 191.35e12,
"f_max": 196.1e12,
"baud_rate": 32e9,
"spacing": 50e9,
"power_dbm": 0,
"power_range_db": [0,0,0.5],
"roll_off": 0.15,
"tx_osnr": 45,
"sys_margins": 0
}
def __init__(self, **kwargs):
self.update_attr(self.default_values, kwargs, 'SI')
class Span(common):
default_values = \
{
'power_mode': True,
'delta_power_range_db': None,
'max_fiber_lineic_loss_for_raman': 0.25,
'target_extended_gain': 2.5,
'max_length': 150,
'length_units': 'km',
'max_loss': None,
'padding': 10,
'EOL': 0,
'con_in': 0,
'con_out': 0
}
def __init__(self, **kwargs):
self.update_attr(self.default_values, kwargs, 'Span')
class Roadm(common):
default_values = \
{
'target_pch_out_db': -17,
'add_drop_osnr': 100
}
def __init__(self, **kwargs):
self.update_attr(self.default_values, kwargs, 'Roadm')
class Transceiver(common):
default_values = \
{
'type_variety': None,
'frequency': None,
'mode': {}
}
def __init__(self, **kwargs):
self.update_attr(self.default_values, kwargs, 'Transceiver')
class Fiber(common):
default_values = \
{
'type_variety': '',
'dispersion': None,
'gamma': 0
}
def __init__(self, **kwargs):
self.update_attr(self.default_values, kwargs, 'Fiber')
class Amp(common):
default_values = \
{
'f_min': 191.35e12,
'f_max': 196.1e12,
'type_variety': '',
'type_def': '',
'gain_flatmax': None,
'gain_min': None,
'p_max': None,
'nf_model': None,
'dual_stage_model': None,
'nf_fit_coeff': None,
'nf_ripple': None,
'dgt': None,
'gain_ripple': None,
'out_voa_auto': False,
'allowed_for_design': False,
'raman': False
}
def __init__(self, **kwargs):
self.update_attr(self.default_values, kwargs, 'Amp')
@classmethod
def from_advanced_json(cls, filename, **kwargs):
with open(filename, encoding='utf-8') as f:
json_data = load(f)
return cls(**{**kwargs, **json_data, 'type_def':None, 'nf_model':None})
def from_json(cls, filename, **kwargs):
config = Path(filename).parent / 'default_edfa_config.json'
@classmethod
def from_default_json(cls, filename, **kwargs):
with open(filename, encoding='utf-8') as f:
json_data = load(f)
type_variety = kwargs['type_variety']
type_def = kwargs.get('type_def', 'variable_gain') #default compatibility with older json eqpt files
nf_def = None
dual_stage_def = None
if type_def == 'fixed_gain':
try:
@@ -67,6 +149,8 @@ class Amp(AmpBase):
del kwargs['nf_max']
except KeyError: pass #nf_min and nf_max are not needed for fixed gain amp
nf_def = Model_fg(nf0)
elif type_def == 'advanced_model':
config = Path(filename).parent / kwargs.pop('advanced_config_from_json')
elif type_def == 'variable_gain':
gain_min, gain_max = kwargs['gain_min'], kwargs['gain_flatmax']
try: #nf_min and nf_max are expected for a variable gain amp
@@ -87,7 +171,20 @@ class Amp(AmpBase):
print(f'missing nf_coef input for amplifier: {type_variety} in eqpt_config.json')
exit()
nf_def = Model_openroadm(nf_coef)
return cls(**{**kwargs, **json_data, 'nf_model': nf_def})
elif type_def == 'dual_stage':
try: #nf_ram and gain_ram are expected for a hybrid amp
preamp_variety = kwargs.pop('preamp_variety')
booster_variety = kwargs.pop('booster_variety')
except KeyError:
print(f'missing preamp/booster variety input for amplifier: {type_variety} in eqpt_config.json')
exit()
dual_stage_def = Model_dual_stage(preamp_variety, booster_variety)
with open(config, encoding='utf-8') as f:
json_data = load(f)
return cls(**{**kwargs, **json_data,
'nf_model': nf_def, 'dual_stage_model': dual_stage_def})
def nf_model(type_variety, gain_min, gain_max, nf_min, nf_max):
@@ -123,7 +220,7 @@ def nf_model(type_variety, gain_min, gain_max, nf_min, nf_max):
g1a_max = lin2db(db2lin(nf2) / (db2lin(nf_min) - db2lin(nf1)))
delta_p = gain_max - g1a_max
g1a_min = gain_min - (gain_max-gain_min) - delta_p
if not 1 < delta_p < 6:
if not 1 < delta_p < 11:
print(f'Computed \N{greek capital letter delta}P invalid \
\n 1st coil vs 2nd coil calculated DeltaP {delta_p:.2f} for \
\n amplifier {type_variety} is not valid: revise inputs \
@@ -145,7 +242,7 @@ def edfa_nf(gain_target, variety_type, equipment):
amp_params = equipment['Edfa'][variety_type]
amp = Edfa(
uid = f'calc_NF',
params = amp_params._asdict(),
params = amp_params.__dict__,
operational = {
'gain_target': gain_target,
'tilt_target': 0
@@ -243,6 +340,30 @@ def update_trx_osnr(equipment):
m['OSNR'] = m['OSNR'] + equipment['SI']['default'].sys_margins
return equipment
def update_dual_stage(equipment):
edfa_dict = equipment['Edfa']
for edfa in edfa_dict.values():
if edfa.type_def == 'dual_stage':
edfa_preamp = edfa_dict[edfa.dual_stage_model.preamp_variety]
edfa_booster = edfa_dict[edfa.dual_stage_model.booster_variety]
for k,v in edfa_preamp.__dict__.items():
attr_k = 'preamp_'+k
setattr(edfa, attr_k, v)
for k,v in edfa_booster.__dict__.items():
attr_k = 'booster_'+k
setattr(edfa, attr_k, v)
edfa.p_max = edfa_booster.p_max
edfa.gain_flatmax = edfa_booster.gain_flatmax + edfa_preamp.gain_flatmax
if edfa.gain_min < edfa_preamp.gain_min:
print(
f'\x1b[1;31;40m'\
+ f'CRITICAL: dual stage {edfa.type_variety} min gain is lower than its preamp min gain\
=> please increase its min gain in eqpt_config.json'\
+ '\x1b[0m'
)
exit()
return equipment
def equipment_from_json(json_data, filename):
"""build global dictionnary eqpt_library that stores all eqpt characteristics:
edfa type type_variety, fiber type_variety
@@ -259,13 +380,9 @@ def equipment_from_json(json_data, filename):
for entry in entries:
subkey = entry.get('type_variety', 'default')
if key == 'Edfa':
if 'advanced_config_from_json' in entry:
config = Path(filename).parent / entry.pop('advanced_config_from_json')
equipment[key][subkey] = Amp.from_advanced_json(config, **entry)
else:
config = Path(filename).parent / 'default_edfa_config.json'
equipment[key][subkey] = Amp.from_default_json(config, **entry)
equipment[key][subkey] = Amp.from_json(filename, **entry)
else:
equipment[key][subkey] = typ(**entry)
equipment = update_trx_osnr(equipment)
equipment = update_dual_stage(equipment)
return equipment

View File

@@ -30,7 +30,7 @@ class ConvenienceAccess:
class Power(namedtuple('Power', 'signal nonlinear_interference amplified_spontaneous_emission'), ConvenienceAccess):
"""carriers power in W"""
_ABBREVS = {'nli': 'nonlinear_interference',
'ase': 'amplified_spontaneous_emission',}
@@ -42,14 +42,18 @@ class Channel(namedtuple('Channel', 'channel_number frequency baud_rate roll_off
'ffs': 'frequency',
'freq': 'frequency',}
class Pref(namedtuple('Pref', 'p_span0, p_spani'), ConvenienceAccess):
class Pref(namedtuple('Pref', 'p_span0, p_spani, neq_ch '), ConvenienceAccess):
"""noiseless reference power in dBm:
p0: inital target carrier power
pi: carrier power after element i
neqch: equivalent channel count in dB"""
_ABBREVS = {'p0' : 'p_span0',
'pi' : 'p_spani'}
class SpectralInformation(namedtuple('SpectralInformation', 'pref carriers'), ConvenienceAccess):
def __new__(cls, pref=Pref(0, 0), *carriers):
def __new__(cls, pref, carriers):
return super().__new__(cls, pref, carriers)
def merge_input_spectral_information(*si):
@@ -60,9 +64,10 @@ def merge_input_spectral_information(*si):
def create_input_spectral_information(f_min, f_max, roll_off, baud_rate, power, spacing):
# pref in dB : convert power lin into power in dB
pref = lin2db(power * 1e3)
si = SpectralInformation(pref=Pref(pref, pref))
nb_channel = automatic_nch(f_min, f_max, spacing)
si = si.update(carriers=[
si = SpectralInformation(
pref=Pref(pref, pref, lin2db(nb_channel)),
carriers=[
Channel(f, (f_min+spacing*f),
baud_rate, roll_off, Power(power, 0, 0)) for f in range(1,nb_channel+1)
])

View File

@@ -14,7 +14,7 @@ from numpy import arange
from scipy.interpolate import interp1d
from logging import getLogger
from os import path
from operator import itemgetter
from operator import itemgetter, attrgetter
from gnpy.core import elements
from gnpy.core.elements import Fiber, Edfa, Transceiver, Roadm, Fused
from gnpy.core.equipment import edfa_nf
@@ -50,9 +50,9 @@ def network_from_json(json_data, equipment):
for el_config in json_data['elements']:
typ = el_config.pop('type')
variety = el_config.pop('type_variety', 'default')
if typ in equipment and variety in equipment[typ]:
if typ in equipment and variety in equipment[typ]:
extra_params = equipment[typ][variety]
el_config.setdefault('params', {}).update(extra_params._asdict())
el_config.setdefault('params', {}).update(extra_params.__dict__)
elif typ in ['Edfa', 'Fiber']: #catch it now because the code will crash later!
print( f'The {typ} of variety type {variety} was not recognized:'
'\nplease check it is properly defined in the eqpt_config json file')
@@ -66,7 +66,13 @@ def network_from_json(json_data, equipment):
for cx in json_data['connections']:
from_node, to_node = cx['from_node'], cx['to_node']
try:
g.add_edge(nodes[from_node], nodes[to_node])
if isinstance(nodes[from_node], Fiber):
edge_length = nodes[from_node].params.length
# print(from_node)
# print(edge_length)
else:
edge_length = 0.01
g.add_edge(nodes[from_node], nodes[to_node], weight = edge_length)
except KeyError:
msg = f'In {__name__} network_from_json function:\n\tcan not find {from_node} or {to_node} defined in {cx}'
print(msg)
@@ -87,16 +93,21 @@ def network_to_json(network):
data.update(connections)
return data
def select_edfa(gain_target, power_target, equipment):
def select_edfa(raman_allowed, gain_target, power_target, equipment, uid):
"""amplifer selection algorithm
@Orange Jean-Luc Augé
"""
Edfa_list = namedtuple('Edfa_list', 'variety power gain nf')
TARGET_EXTENDED_GAIN = 2.1
#MAX_EXTENDED_GAIN = 5
Edfa_list = namedtuple('Edfa_list', 'variety power gain_min nf')
TARGET_EXTENDED_GAIN = equipment['Span']['default'].target_extended_gain
edfa_dict = equipment['Edfa']
pin = power_target - gain_target
#create 2 list of available amplifiers with relevant attributs for their selection
#edfa list with :
#extended gain min allowance of 3dB: could be parametrized, but a bit complex
#extended gain max allowance TARGET_EXTENDED_GAIN is coming from eqpt_config.json
#power attribut include power AND gain limitations
edfa_list = [Edfa_list(
variety=edfa_variety,
power=min(
@@ -106,76 +117,114 @@ def select_edfa(gain_target, power_target, equipment):
edfa.p_max
)
-power_target,
gain=edfa.gain_flatmax-gain_target,
gain_min=
gain_target+3
-edfa.gain_min,
nf=edfa_nf(gain_target, edfa_variety, equipment)) \
for edfa_variety, edfa in edfa_dict.items()
if edfa.allowed_for_design]
if (edfa.allowed_for_design and not edfa.raman)]
acceptable_gain_list = \
list(filter(lambda x : x.gain>-TARGET_EXTENDED_GAIN, edfa_list))
if len(acceptable_gain_list) < 1:
#no amplifier satisfies the required gain, so pick the highest gain:
gain_max = max(edfa_list, key=itemgetter(2)).gain
#pick up all amplifiers that share this max gain:
acceptable_gain_list = \
list(filter(lambda x : x.gain-gain_max>-0.1, edfa_list))
acceptable_power_list = \
list(filter(lambda x : x.power>=0, acceptable_gain_list))
#consider a Raman list because of different gain_min requirement:
#do not allow extended gain min for Raman
raman_list = [Edfa_list(
variety=edfa_variety,
power=min(
pin
+edfa.gain_flatmax
+TARGET_EXTENDED_GAIN,
edfa.p_max
)
-power_target,
gain_min=
gain_target
-edfa.gain_min,
nf=edfa_nf(gain_target, edfa_variety, equipment))
for edfa_variety, edfa in edfa_dict.items()
if (edfa.allowed_for_design and edfa.raman)] \
if raman_allowed else []
#merge raman and edfa lists
amp_list = edfa_list + raman_list
#filter on min gain limitation:
acceptable_gain_min_list = [x for x in amp_list if x.gain_min>0]
if len(acceptable_gain_min_list) < 1:
#do not take this empty list into account for the rest of the code
#but issue a warning to the user and do not consider Raman
#Raman below min gain should not be allowed because i is meant to be a design requirement
#and raman padding at the amplifier input is impossible!
if len(edfa_list) < 1:
print(
f'\x1b[1;31;40m'\
+ f'CRITICAL _ ABORT: auto_design could not find any amplifier \
to satisfy min gain requirement in node {uid} \
please increase span fiber padding'\
+ '\x1b[0m'
)
exit()
else:
print(
f'\x1b[1;31;40m'\
+ f'WARNING: target gain in node {uid} is below all available amplifiers min gain: \
amplifier input padding will be assumed, consider increase span fiber padding instead'\
+ '\x1b[0m'
)
acceptable_gain_min_list = edfa_list
#filter on gain+power limitation:
#this list checks both the gain and the power requirement
#because of the way .power is calculated in the list
acceptable_power_list = [x for x in acceptable_gain_min_list if x.power>0]
if len(acceptable_power_list) < 1:
#no amplifier satisfies the required power, so pick the highest power:
power_max = \
max(acceptable_gain_list, key=itemgetter(1)).power
#pick up all amplifiers that share this max gain:
acceptable_power_list = \
list(filter(lambda x : x.power-power_max>-0.1, acceptable_gain_list))
#no amplifier satisfies the required power, so pick the highest power(s):
power_max = max(acceptable_gain_min_list, key=attrgetter('power')).power
#check and pick if other amplifiers may have a similar gain/power
#allow a 0.3dB power range
#this allows to chose an amplifier with a better NF subsequentely
acceptable_power_list = [x for x in acceptable_gain_min_list
if x.power-power_max>-0.3]
# gain and power requirements are resolved,
# =>chose the amp with the best NF among the acceptable ones:
return min(acceptable_power_list, key=itemgetter(3)).variety #filter on NF
selected_edfa = min(acceptable_power_list, key=attrgetter('nf')) #filter on NF
#check what are the gain and power limitations of this amp
power_reduction = round(min(selected_edfa.power, 0),2)
if power_reduction < -0.5:
print(
f'\x1b[1;31;40m'\
+ f'WARNING: target gain and power in node {uid}\n \
is beyond all available amplifiers capabilities and/or extended_gain_range:\n\
a power reduction of {power_reduction} is applied\n'\
+ '\x1b[0m'
)
def set_roadm_loss(network, equipment, pref_ch_db):
roadms = [roadm for roadm in network if isinstance(roadm, Roadm)]
power_mode = equipment['Spans']['default'].power_mode
default_roadm_loss = equipment['Roadms']['default'].gain_mode_default_loss
pout_target = equipment['Roadms']['default'].power_mode_pout_target
roadm_loss = pref_ch_db - pout_target
return selected_edfa.variety, power_reduction
for roadm in roadms:
if power_mode:
roadm.loss = roadm_loss
roadm.target_pch_out_db = pout_target
elif roadm.loss == None:
roadm.loss = default_roadm_loss
def target_power(dp_from_gain, network, node, equipment): #get_fiber_dp
def target_power(network, node, equipment): #get_fiber_dp
SPAN_LOSS_REF = 20
POWER_SLOPE = 0.3
power_mode = equipment['Spans']['default'].power_mode
dp_range = list(equipment['Spans']['default'].delta_power_range_db)
power_mode = equipment['Span']['default'].power_mode
dp_range = list(equipment['Span']['default'].delta_power_range_db)
node_loss = span_loss(network, node)
dp_gain_mode = 0
try:
dp_power_mode = round2float((node_loss - SPAN_LOSS_REF) * POWER_SLOPE, dp_range[2])
dp_power_mode = max(dp_range[0], dp_power_mode)
dp_power_mode = min(dp_range[1], dp_power_mode)
dp = round2float((node_loss - SPAN_LOSS_REF) * POWER_SLOPE, dp_range[2])
dp = max(dp_range[0], dp)
dp = min(dp_range[1], dp)
except KeyError:
print(f'invalid delta_power_range_db definition in eqpt_config[Spans]'
print(f'invalid delta_power_range_db definition in eqpt_config[Span]'
f'delta_power_range_db: [lower_bound, upper_bound, step]')
exit()
if dp_from_gain:
dp_power_mode = dp_from_gain
dp_gain_mode = dp_from_gain
if isinstance(node, Roadm):
dp_power_mode = 0
dp = dp_power_mode if power_mode else dp_gain_mode
#print(f'{repr(node)} delta power in:\n{dp}dB')
dp = 0
return dp
def prev_node_generator(network, node):
"""fused spans interest:
iterate over all predecessors while they are Fused or Fiber type"""
@@ -244,23 +293,22 @@ def find_last_node(network, node):
pass
return this_node
def set_amplifier_voa(amp, pref_total_db, power_mode):
VOA_MARGIN = 0
if amp.operational.out_voa is None:
def set_amplifier_voa(amp, power_target, power_mode):
VOA_MARGIN = 1 #do not maximize the VOA optimization
if amp.out_voa is None:
if power_mode:
gain_target = amp.operational.gain_target
pout = pref_total_db + amp.dp_db
voa = min(amp.params.p_max-pout,
amp.params.gain_flatmax-amp.operational.gain_target)
voa = round2float(max(voa, 0), 0.5) - VOA_MARGIN if amp.params.out_voa_auto else 0
amp.dp_db = amp.dp_db + voa
amp.operational.gain_target = amp.operational.gain_target + voa
gain_target = amp.effective_gain
voa = min(amp.params.p_max-power_target,
amp.params.gain_flatmax-amp.effective_gain)
voa = max(round2float(max(voa, 0), 0.5) - VOA_MARGIN, 0) if amp.params.out_voa_auto else 0
amp.delta_p = amp.delta_p + voa
amp.effective_gain = amp.effective_gain + voa
else:
voa = 0 # no output voa optimization in gain mode
amp.operational.out_voa = voa
amp.out_voa = voa
def set_egress_amplifier(network, roadm, equipment, pref_total_db):
power_mode = equipment['Spans']['default'].power_mode
power_mode = equipment['Span']['default'].power_mode
next_oms = (n for n in network.successors(roadm) if not isinstance(n, Transceiver))
for oms in next_oms:
#go through all the OMS departing from the Roadm
@@ -271,30 +319,56 @@ def set_egress_amplifier(network, roadm, equipment, pref_total_db):
# node = find_last_node(next_node)
# next_node = next(n for n in network.successors(node))
# next_node = find_last_node(next_node)
prev_dp = 0
dp = 0
prev_dp = getattr(node.params, 'target_pch_out_db', 0)
dp = prev_dp
prev_voa = 0
voa = 0
while True:
#go through all nodes in the OMS (loop until next Roadm instance)
if isinstance(node, Edfa):
node_loss = span_loss(network, prev_node)
dp_from_gain = prev_dp + node.operational.gain_target - node_loss \
if node.operational.gain_target > 0 else None
dp = target_power(dp_from_gain, network, next_node, equipment)
gain_target = node_loss + dp - prev_dp
voa = node.out_voa if node.out_voa else 0
if node.delta_p is None:
dp = target_power(network, next_node, equipment)
else:
dp = node.delta_p
gain_from_dp = node_loss + dp - prev_dp + prev_voa
if node.effective_gain is None or power_mode:
gain_target = gain_from_dp
else: #gain mode with effective_gain
gain_target = node.effective_gain
dp = prev_dp - node_loss + gain_target
#print(node.delta_p, dp, gain_target)
power_target = pref_total_db + dp
if power_mode:
node.dp_db = dp
node.operational.gain_target = gain_target
raman_allowed = False
if isinstance(prev_node, Fiber):
max_fiber_lineic_loss_for_raman = \
equipment['Span']['default'].max_fiber_lineic_loss_for_raman
raman_allowed = prev_node.params.loss_coef < max_fiber_lineic_loss_for_raman
if node.params.type_variety == '':
power_target = pref_total_db + dp
edfa_variety = select_edfa(gain_target, power_target, equipment)
if node.params.type_variety == '' :
edfa_variety, power_reduction = select_edfa(raman_allowed,
gain_target, power_target, equipment, node.uid)
extra_params = equipment['Edfa'][edfa_variety]
node.params.update_params(extra_params._asdict())
set_amplifier_voa(node, pref_total_db, power_mode)
node.params.update_params(extra_params.__dict__)
dp += power_reduction
gain_target += power_reduction
elif node.params.raman and not raman_allowed:
print(
f'\x1b[1;31;40m'\
+ f'WARNING: raman is used in node {node.uid}\n \
but fiber lineic loss is above threshold\n'\
+ '\x1b[0m'
)
node.delta_p = dp if power_mode else None
node.effective_gain = gain_target
set_amplifier_voa(node, power_target, power_mode)
if isinstance(next_node, Roadm) or isinstance(next_node, Transceiver):
break
prev_dp = dp
prev_voa = voa
prev_node = node
node = next_node
# print(f'{node.uid}')
@@ -319,12 +393,16 @@ def add_egress_amplifier(network, node):
}
},
operational = {
'gain_target': 0,
'gain_target': None,
'tilt_target': 0,
})
network.add_node(amp)
network.add_edge(node, amp)
network.add_edge(amp, next_node)
if isinstance(node,Fiber):
edgeweight = node.params.length
else:
edgeweight = 0.01
network.add_edge(node, amp, weight = edgeweight)
network.add_edge(amp, next_node, weight = 0.01)
def calculate_new_length(fiber_length, bounds, target_length):
@@ -385,17 +463,25 @@ def split_fiber(network, fiber, bounds, target_length, equipment):
}
},
params = fiber_params)
network.add_edge(prev_node, new_span)
prev_node = new_span
network.add_edge(prev_node, next_node)
def add_connector_loss(fibers, con_in, con_out, EOL):
for fiber in fibers:
if fiber.con_in is None: fiber.con_in = con_in
if fiber.con_out is None:
fiber.con_out = con_out #con_out includes EOL
if isinstance(prev_node,Fiber):
edgeweight = prev_node.params.length
else:
fiber.con_out = fiber.con_out+EOL
edgeweight = 0.01
network.add_edge(prev_node, new_span, weight = edgeweight)
prev_node = new_span
if isinstance(prev_node,Fiber):
edgeweight = prev_node.params.length
else:
edgeweight = 0.01
network.add_edge(prev_node, next_node, weight = edgeweight)
def add_connector_loss(network, fibers, default_con_in, default_con_out, EOL):
for fiber in fibers:
if fiber.con_in is None: fiber.con_in = default_con_in
if fiber.con_out is None: fiber.con_out = default_con_out
next_node = next(n for n in network.successors(fiber))
if not isinstance(next_node, Fused):
fiber.con_out += EOL
def add_fiber_padding(network, fibers, padding):
"""last_fibers = (fiber for n in network.nodes()
@@ -421,19 +507,18 @@ def add_fiber_padding(network, fibers, padding):
first_fiber.att_in = first_fiber.att_in + padding - this_span_loss
def build_network(network, equipment, pref_ch_db, pref_total_db):
default_span_data = equipment['Spans']['default']
default_span_data = equipment['Span']['default']
max_length = int(default_span_data.max_length * UNITS[default_span_data.length_units])
min_length = max(int(default_span_data.padding/0.2*1e3),50_000)
bounds = range(min_length, max_length)
target_length = max(min_length, 90_000)
con_in = default_span_data.con_in
con_out = default_span_data.con_out + default_span_data.EOL
default_con_in = default_span_data.con_in
default_con_out = default_span_data.con_out
padding = default_span_data.padding
#set raodm loss for gain_mode before to build network
set_roadm_loss(network, equipment, pref_ch_db)
#set roadm loss for gain_mode before to build network
fibers = [f for f in network.nodes() if isinstance(f, Fiber)]
add_connector_loss(fibers, con_in, con_out, default_span_data.EOL)
add_connector_loss(network, fibers, default_con_in, default_con_out, default_span_data.EOL)
add_fiber_padding(network, fibers, padding)
# don't group split fiber and add amp in the same loop
# =>for code clarity (at the expense of speed):

View File

@@ -18,12 +18,11 @@ See: draft-ietf-teas-yang-path-computation-01.txt
from sys import exit
from collections import namedtuple
from logging import getLogger, basicConfig, CRITICAL, DEBUG, INFO
from networkx import (dijkstra_path, NetworkXNoPath, all_simple_paths)
from networkx import (dijkstra_path, NetworkXNoPath, all_simple_paths,shortest_path_length)
from networkx.utils import pairwise
from numpy import mean
from gnpy.core.service_sheet import convert_service_sheet, Request_element, Element
from gnpy.core.elements import Transceiver, Roadm, Edfa, Fused
from gnpy.core.network import set_roadm_loss
from gnpy.core.utils import db2lin, lin2db
from gnpy.core.info import create_input_spectral_information, SpectralInformation, Channel, Power
from copy import copy, deepcopy
@@ -292,7 +291,15 @@ def compute_constrained_path(network, req):
if len(nodes_list) == 1 :
try :
total_path = dijkstra_path(network, source, destination)
total_path = dijkstra_path(network, source, destination, weight = 'weight')
# print('checking edges length is correct')
# print(shortest_path_length(network,source,destination))
# print(shortest_path_length(network,source,destination,weight ='weight'))
# s = total_path[0]
# for e in total_path[1:]:
# print(s.uid)
# print(network.get_edge_data(s,e))
# s = e
except NetworkXNoPath:
msg = f'\x1b[1;33;40m'+f'Request {req.request_id} could not find a path from {source.uid} to node : {destination.uid} in network topology'+ '\x1b[0m'
logger.critical(msg)
@@ -306,15 +313,16 @@ def compute_constrained_path(network, req):
if ispart(nodes_list, p) :
# print(f'selection{[el.uid for el in p if el in roadm]}')
candidate.append(p)
# select the shortest path (in nb of hops)
# select the shortest path (in nb of hops) -> changed to shortest path in km length
if len(candidate)>0 :
candidate.sort(key=lambda x: len(x))
# candidate.sort(key=lambda x: len(x))
candidate.sort(key=lambda x: sum(network.get_edge_data(x[i],x[i+1])['weight'] for i in range(len(x)-2)))
total_path = candidate[0]
else:
if req.loose_list[req.nodes_list.index(n)] == 'loose':
print(f'\x1b[1;33;40m'+f'Request {req.request_id} could not find a path crossing {nodes_list} in network topology'+ '\x1b[0m')
print(f'constraint ignored')
total_path = dijkstra_path(network, source, destination)
total_path = dijkstra_path(network, source, destination, weight = 'weight')
else:
msg = f'\x1b[1;33;40m'+f'Request {req.request_id} could not find a path crossing {nodes_list}.\nNo path computed'+ '\x1b[0m'
logger.critical(msg)
@@ -386,8 +394,6 @@ def compute_constrained_path(network, req):
return total_path
def propagate(path, req, equipment, show=False):
#update roadm loss in case of power sweep (power mode only)
set_roadm_loss(path, equipment, lin2db(req.power*1e3))
si = create_input_spectral_information(
req.f_min, req.f_max, req.roll_off, req.baud_rate,
req.power, req.spacing)
@@ -395,12 +401,10 @@ def propagate(path, req, equipment, show=False):
si = el(si)
if show :
print(el)
path[-1].update_snr(req.tx_osnr, equipment['Roadms']['default'].add_drop_osnr)
path[-1].update_snr(req.tx_osnr, equipment['Roadm']['default'].add_drop_osnr)
return path
def propagate2(path, req, equipment, show=False):
#update roadm loss in case of power sweep (power mode only)
set_roadm_loss(path, equipment, lin2db(req.power*1e3))
si = create_input_spectral_information(
req.f_min, req.f_max, req.roll_off, req.baud_rate,
req.power, req.spacing)
@@ -411,12 +415,10 @@ def propagate2(path, req, equipment, show=False):
infos[el] = before_si, after_si
if show :
print(el)
path[-1].update_snr(req.tx_osnr, equipment['Roadms']['default'].add_drop_osnr)
path[-1].update_snr(req.tx_osnr, equipment['Roadm']['default'].add_drop_osnr)
return infos
def propagate_and_optimize_mode(path, req, equipment):
#update roadm loss in case of power sweep (power mode only)
set_roadm_loss(path, equipment, lin2db(req.power*1e3))
def propagate_and_optimize_mode(path, req, equipment, show=False):
# if mode is unknown : loops on the modes starting from the highest baudrate fiting in the
# step 1: create an ordered list of modes based on baudrate
baudrate_to_explore = list(set([m['baud_rate'] for m in equipment['Transceiver'][req.tsp].mode
@@ -427,7 +429,7 @@ def propagate_and_optimize_mode(path, req, equipment):
# at least 1 baudrate can be tested wrt spacing
for b in baudrate_to_explore :
modes_to_explore = [m for m in equipment['Transceiver'][req.tsp].mode
if m['baud_rate'] == b]
if m['baud_rate'] == b and float(m['min_spacing'])<= req.spacing]
modes_to_explore = sorted(modes_to_explore,
key = lambda x: x['bit_rate'], reverse=True)
# print(modes_to_explore)
@@ -440,9 +442,11 @@ def propagate_and_optimize_mode(path, req, equipment):
b, req.power, req.spacing)
for el in path:
si = el(si)
if show:
print(el)
for m in modes_to_explore :
if path[-1].snr is not None:
path[-1].update_snr(m['tx_osnr'], equipment['Roadms']['default'].add_drop_osnr)
path[-1].update_snr(m['tx_osnr'], equipment['Roadm']['default'].add_drop_osnr)
if round(min(path[-1].snr+lin2db(b/(12.5e9))),2) > m['OSNR'] :
found_a_feasible_mode = True
return path, m
@@ -611,8 +615,10 @@ def compute_path_dsjctn(network, equipment, pathreqlist, disjunctions_list):
source=next(el for el in network.nodes() if el.uid == pathreq.source),\
target=next(el for el in network.nodes() if el.uid == pathreq.destination),\
cutoff=80))
# sort them
all_simp_pths = sorted(all_simp_pths, key=lambda path: len(path))
# sort them in km length instead of hop
# all_simp_pths = sorted(all_simp_pths, key=lambda path: len(path))
all_simp_pths = sorted(all_simp_pths, key=lambda \
x: sum(network.get_edge_data(x[i],x[i+1])['weight'] for i in range(len(x)-2)))
# reversed direction paths required to check disjunction on both direction
all_simp_pths_reversed = []
for pth in all_simp_pths:
@@ -825,7 +831,7 @@ def find_reversed_path(p,network) :
destination = p[0]
total_path = [source]
for node in reversed_roadm_path :
total_path.extend(dijkstra_path(network, source, node)[1:])
total_path.extend(dijkstra_path(network, source, node, weight = 'weight')[1:])
source = node
total_path.append(destination)
return total_path

View File

@@ -73,7 +73,7 @@ class Request_element(Element):
Requestmode = None
self.mode = Request.mode
except KeyError:
msg = f'Request Id: {self.request_id} - could not find tsp : \'{Request.trx_type}\' with mode: \'{Requestmode}\' in eqpt library \nComputation stopped.'
msg = f'Request Id: {self.request_id} - could not find tsp : \'{Request.trx_type}\' with mode: \'{Request.mode}\' in eqpt library \nComputation stopped.'
#print(msg)
logger.critical(msg)
exit()

View File

@@ -88,6 +88,20 @@ def itufs(spacing, startf=191.35, stopf=196.10):
"""
return np.arange(startf, stopf + spacing / 2, spacing)
def itufl(length, startf=191.35, stopf=196.10):
"""Creates an array of frequencies whose default range is
191.35-196.10 THz
:param length: number of elements
:param starf: Start frequency in THz
:param stopf: Stop frequency in THz
:type length: integer
:type startf: float
:type stopf: float
:return an array of frequnecies determined by the spacing parameter
:rtype: numpy.ndarray
"""
return np.linspace(startf, stopf, length)
def h():
"""

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,11 @@
{ "Edfa":[{
"type_variety": "CienaDB_medium_gain",
"type_def": "advanced_model",
"gain_flatmax": 25,
"gain_min": 15,
"p_max": 21,
"advanced_config_from_json": "std_medium_gain_advanced_config.json",
"out_voa_auto": false,
"allowed_for_design": true
},
{
@@ -14,6 +16,7 @@
"p_max": 21,
"nf_min": 6,
"nf_max": 10,
"out_voa_auto": false,
"allowed_for_design": true
},
{
@@ -24,6 +27,7 @@
"p_max": 21,
"nf_min": 7,
"nf_max": 11,
"out_voa_auto": false,
"allowed_for_design": true
},
{
@@ -34,6 +38,7 @@
"p_max": 21,
"nf_min": 5.8,
"nf_max": 10,
"out_voa_auto": false,
"allowed_for_design": true
},
{
@@ -52,9 +57,11 @@
"gamma": 0.00127
}
],
"Spans":[{
"power_mode": true,
"delta_power_range_db": [0,0,1],
"Span":[{
"power_mode":true,
"delta_power_range_db": [0,0,0.5],
"max_fiber_lineic_loss_for_raman": 0.25,
"target_extended_gain": 2.5,
"max_length": 150,
"length_units": "km",
"max_loss": 28,
@@ -64,10 +71,13 @@
"con_out": 0
}
],
"Roadms":[{
"gain_mode_default_loss": 20,
"power_mode_pout_target": -20,
"add_drop_osnr": 100
"Roadm":[{
"target_pch_out_db": -20,
"add_drop_osnr": 38,
"restrictions": {
"preamp_variety_list":["low_gain_preamp", "high_gain_preamp"],
"booster_variety_list":["std_booster"]
}
}],
"SI":[{
"f_min": 191.3e12,
@@ -75,7 +85,7 @@
"baud_rate": 32e9,
"spacing": 50e9,
"power_dbm": 0,
"power_range_db": [0,0.5,0.5],
"power_range_db": [0,0,0.5],
"roll_off": 0.15,
"tx_osnr": 100,
"sys_margins": 0

Binary file not shown.

View File

@@ -1,698 +0,0 @@
{
"elements": [
{
"uid": "trx Lannion_CAS",
"metadata": {
"location": {
"city": "Lannion_CAS",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Transceiver"
},
{
"uid": "trx Lorient_KMA",
"metadata": {
"location": {
"city": "Lorient_KMA",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Transceiver"
},
{
"uid": "trx Vannes_KBE",
"metadata": {
"location": {
"city": "Vannes_KBE",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Transceiver"
},
{
"uid": "trx Rennes_STA",
"metadata": {
"location": {
"city": "Rennes_STA",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Transceiver"
},
{
"uid": "trx Brest_KLA",
"metadata": {
"location": {
"city": "Brest_KLA",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Transceiver"
},
{
"uid": "roadm Lannion_CAS",
"metadata": {
"location": {
"city": "Lannion_CAS",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Roadm"
},
{
"uid": "roadm Lorient_KMA",
"metadata": {
"location": {
"city": "Lorient_KMA",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Roadm"
},
{
"uid": "roadm Vannes_KBE",
"metadata": {
"location": {
"city": "Vannes_KBE",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Roadm"
},
{
"uid": "roadm Rennes_STA",
"metadata": {
"location": {
"city": "Rennes_STA",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Roadm"
},
{
"uid": "roadm Brest_KLA",
"metadata": {
"location": {
"city": "Brest_KLA",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Roadm"
},
{
"uid": "west fused spans in Corlay",
"metadata": {
"location": {
"city": "Corlay",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Fused"
},
{
"uid": "west fused spans in Loudeac",
"metadata": {
"location": {
"city": "Loudeac",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Fused"
},
{
"uid": "east fused spans in Corlay",
"metadata": {
"location": {
"city": "Corlay",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Fused"
},
{
"uid": "east fused spans in Loudeac",
"metadata": {
"location": {
"city": "Loudeac",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Fused"
},
{
"uid": "fiber (Lannion_CAS → Corlay)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 20.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Corlay → Loudeac)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 50.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Loudeac → Lorient_KMA)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Lorient_KMA → Vannes_KBE)-F01",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 10.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Lannion_CAS → Stbrieuc)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Stbrieuc → Rennes_STA)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 65.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Lannion_CAS → Morlaix)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 40.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Morlaix → Brest_KLA)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 35.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Corlay → Lannion_CAS)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 20.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Loudeac → Corlay)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 50.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Lorient_KMA → Loudeac)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Vannes_KBE → Lorient_KMA)-F01",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 10.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Stbrieuc → Lannion_CAS)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Rennes_STA → Stbrieuc)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 65.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Morlaix → Lannion_CAS)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 40.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Brest_KLA → Morlaix)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 35.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "east edfa in Lannion_CAS to Morlaix",
"metadata": {
"location": {
"city": "Lannion_CAS",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Edfa",
"type_variety": "test",
"operational": {
"gain_target": 0,
"tilt_target": 0,
"out_voa": 0
}
},
{
"uid": "east edfa in Lannion_CAS to Corlay",
"metadata": {
"location": {
"city": "Lannion_CAS",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Edfa",
"type_variety": "test",
"operational": {
"gain_target": 0,
"tilt_target": 0,
"out_voa": 0
}
},
{
"uid": "east edfa in Lannion_CAS to Stbrieuc",
"metadata": {
"location": {
"city": "Lannion_CAS",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Edfa",
"type_variety": "test",
"operational": {
"gain_target": 0,
"tilt_target": 0,
"out_voa": 0
}
},
{
"uid": "east edfa in Corlay to Loudeac",
"metadata": {
"location": {
"city": "Corlay",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Edfa",
"type_variety": "test",
"operational": {
"gain_target": 0,
"tilt_target": 0,
"out_voa": 0
}
}
],
"connections": [
{
"from_node": "roadm Lannion_CAS",
"to_node": "east edfa in Lannion_CAS to Corlay"
},
{
"from_node": "east edfa in Lannion_CAS to Corlay",
"to_node": "fiber (Lannion_CAS → Corlay)-"
},
{
"from_node": "fiber (Corlay → Lannion_CAS)-",
"to_node": "roadm Lannion_CAS"
},
{
"from_node": "roadm Lannion_CAS",
"to_node": "east edfa in Lannion_CAS to Stbrieuc"
},
{
"from_node": "east edfa in Lannion_CAS to Stbrieuc",
"to_node": "fiber (Lannion_CAS → Stbrieuc)-"
},
{
"from_node": "fiber (Stbrieuc → Lannion_CAS)-",
"to_node": "roadm Lannion_CAS"
},
{
"from_node": "roadm Lannion_CAS",
"to_node": "east edfa in Lannion_CAS to Morlaix"
},
{
"from_node": "east edfa in Lannion_CAS to Morlaix",
"to_node": "fiber (Lannion_CAS → Morlaix)-"
},
{
"from_node": "fiber (Morlaix → Lannion_CAS)-",
"to_node": "roadm Lannion_CAS"
},
{
"from_node": "fiber (Lannion_CAS → Corlay)-",
"to_node": "west fused spans in Corlay"
},
{
"from_node": "west fused spans in Corlay",
"to_node": "fiber (Corlay → Loudeac)-"
},
{
"from_node": "fiber (Loudeac → Corlay)-",
"to_node": "east fused spans in Corlay"
},
{
"from_node": "east fused spans in Corlay",
"to_node": "fiber (Corlay → Lannion_CAS)-"
},
{
"from_node": "fiber (Corlay → Loudeac)-",
"to_node": "west fused spans in Loudeac"
},
{
"from_node": "west fused spans in Loudeac",
"to_node": "fiber (Loudeac → Lorient_KMA)-"
},
{
"from_node": "fiber (Lorient_KMA → Loudeac)-",
"to_node": "east fused spans in Loudeac"
},
{
"from_node": "east fused spans in Loudeac",
"to_node": "fiber (Loudeac → Corlay)-"
},
{
"from_node": "roadm Lorient_KMA",
"to_node": "fiber (Lorient_KMA → Loudeac)-"
},
{
"from_node": "fiber (Loudeac → Lorient_KMA)-",
"to_node": "roadm Lorient_KMA"
},
{
"from_node": "roadm Lorient_KMA",
"to_node": "fiber (Lorient_KMA → Vannes_KBE)-F01"
},
{
"from_node": "fiber (Vannes_KBE → Lorient_KMA)-F01",
"to_node": "roadm Lorient_KMA"
},
{
"from_node": "roadm Vannes_KBE",
"to_node": "fiber (Vannes_KBE → Lorient_KMA)-F01"
},
{
"from_node": "fiber (Lorient_KMA → Vannes_KBE)-F01",
"to_node": "roadm Vannes_KBE"
},
{
"from_node": "fiber (Lannion_CAS → Stbrieuc)-",
"to_node": "fiber (Stbrieuc → Rennes_STA)-"
},
{
"from_node": "fiber (Rennes_STA → Stbrieuc)-",
"to_node": "fiber (Stbrieuc → Lannion_CAS)-"
},
{
"from_node": "roadm Rennes_STA",
"to_node": "fiber (Rennes_STA → Stbrieuc)-"
},
{
"from_node": "fiber (Stbrieuc → Rennes_STA)-",
"to_node": "roadm Rennes_STA"
},
{
"from_node": "fiber (Lannion_CAS → Morlaix)-",
"to_node": "fiber (Morlaix → Brest_KLA)-"
},
{
"from_node": "fiber (Brest_KLA → Morlaix)-",
"to_node": "fiber (Morlaix → Lannion_CAS)-"
},
{
"from_node": "roadm Brest_KLA",
"to_node": "fiber (Brest_KLA → Morlaix)-"
},
{
"from_node": "fiber (Morlaix → Brest_KLA)-",
"to_node": "roadm Brest_KLA"
},
{
"from_node": "trx Lannion_CAS",
"to_node": "roadm Lannion_CAS"
},
{
"from_node": "roadm Lannion_CAS",
"to_node": "trx Lannion_CAS"
},
{
"from_node": "trx Lorient_KMA",
"to_node": "roadm Lorient_KMA"
},
{
"from_node": "roadm Lorient_KMA",
"to_node": "trx Lorient_KMA"
},
{
"from_node": "trx Vannes_KBE",
"to_node": "roadm Vannes_KBE"
},
{
"from_node": "roadm Vannes_KBE",
"to_node": "trx Vannes_KBE"
},
{
"from_node": "trx Rennes_STA",
"to_node": "roadm Rennes_STA"
},
{
"from_node": "roadm Rennes_STA",
"to_node": "trx Rennes_STA"
},
{
"from_node": "trx Brest_KLA",
"to_node": "roadm Brest_KLA"
},
{
"from_node": "roadm Brest_KLA",
"to_node": "trx Brest_KLA"
}
]
}

View File

@@ -1,84 +0,0 @@
{
"path-request": [
{
"request-id": "0",
"source": "BREST_KLA",
"destination": "Vannes_KBE",
"src-tp-id": "trx BREST_KLA",
"dst-tp-id": "trx Vannes_KBE",
"path-constraints": {
"te-bandwidth": {
"technology": "flexi-grid",
"trx_type": "Voyager_16QAM",
"trx_mode": "16QAM",
"effective-freq-slot": [
{
"n": "null",
"m": "null"
}
],
"spacing": 50000000000.0,
"max-nb-of-channel": 80,
"output-power": 0.001,
"path_bandwidth": 0
}
},
"optimizations": {
"explicit-route-include-objects": []
}
},
{
"request-id": "1",
"source": "Lorient_KMA",
"destination": "Vannes_KBE",
"src-tp-id": "trx Lorient_KMA",
"dst-tp-id": "trx Vannes_KBE",
"path-constraints": {
"te-bandwidth": {
"technology": "flexi-grid",
"trx_type": "Voyager_16QAM",
"trx_mode": "16QAM",
"effective-freq-slot": [
{
"n": "null",
"m": "null"
}
],
"spacing": 50000000000.0,
"max-nb-of-channel": 80,
"output-power": 0.001,
"path_bandwidth": 0
}
},
"optimizations": {
"explicit-route-include-objects": []
}
}
],
"synchronization": [
{
"synchronization-id": "0",
"svec": {
"relaxable": "False",
"link-diverse": "True",
"node-diverse": "True",
"request-id-number": [
"0",
"1"
]
}
},
{
"synchronization-id": "1",
"svec": {
"relaxable": "False",
"link-diverse": "True",
"node-diverse": "True",
"request-id-number": [
"1",
"0"
]
}
}
]
}

View File

@@ -1,806 +0,0 @@
{
"elements": [
{
"uid": "trx Lannion_CAS",
"metadata": {
"location": {
"city": "Lannion_CAS",
"region": "RLD",
"latitude": 2.0,
"longitude": 0.0
}
},
"type": "Transceiver"
},
{
"uid": "trx Lorient_KMA",
"metadata": {
"location": {
"city": "Lorient_KMA",
"region": "RLD",
"latitude": 2.0,
"longitude": 3.0
}
},
"type": "Transceiver"
},
{
"uid": "trx Vannes_KBE",
"metadata": {
"location": {
"city": "Vannes_KBE",
"region": "RLD",
"latitude": 2.0,
"longitude": 4.0
}
},
"type": "Transceiver"
},
{
"uid": "trx Rennes_STA",
"metadata": {
"location": {
"city": "Rennes_STA",
"region": "RLD",
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Transceiver"
},
{
"uid": "trx Brest_KLA",
"metadata": {
"location": {
"city": "Brest_KLA",
"region": "RLD",
"latitude": 4.0,
"longitude": 0.0
}
},
"type": "Transceiver"
},
{
"uid": "trx toto",
"metadata": {
"location": {
"city": "toto",
"region": "",
"latitude": 6.0,
"longitude": 0.0
}
},
"type": "Transceiver"
},
{
"uid": "trx tata",
"metadata": {
"location": {
"city": "tata",
"region": "",
"latitude": 7.0,
"longitude": 0.0
}
},
"type": "Transceiver"
},
{
"uid": "roadm Lannion_CAS",
"metadata": {
"location": {
"city": "Lannion_CAS",
"region": "RLD",
"latitude": 2.0,
"longitude": 0.0
}
},
"type": "Roadm"
},
{
"uid": "roadm Lorient_KMA",
"metadata": {
"location": {
"city": "Lorient_KMA",
"region": "RLD",
"latitude": 2.0,
"longitude": 3.0
}
},
"type": "Roadm"
},
{
"uid": "roadm Vannes_KBE",
"metadata": {
"location": {
"city": "Vannes_KBE",
"region": "RLD",
"latitude": 2.0,
"longitude": 4.0
}
},
"type": "Roadm"
},
{
"uid": "roadm Rennes_STA",
"metadata": {
"location": {
"city": "Rennes_STA",
"region": "RLD",
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Roadm"
},
{
"uid": "roadm Brest_KLA",
"metadata": {
"location": {
"city": "Brest_KLA",
"region": "RLD",
"latitude": 4.0,
"longitude": 0.0
}
},
"type": "Roadm"
},
{
"uid": "roadm toto",
"metadata": {
"location": {
"city": "toto",
"region": "",
"latitude": 6.0,
"longitude": 0.0
}
},
"type": "Roadm"
},
{
"uid": "roadm tata",
"metadata": {
"location": {
"city": "tata",
"region": "",
"latitude": 7.0,
"longitude": 0.0
}
},
"type": "Roadm"
},
{
"uid": "west fused spans in Corlay",
"metadata": {
"location": {
"city": "Corlay",
"region": "RLD",
"latitude": 2.0,
"longitude": 1.0
}
},
"type": "Fused"
},
{
"uid": "west fused spans in Loudeac",
"metadata": {
"location": {
"city": "Loudeac",
"region": "RLD",
"latitude": 2.0,
"longitude": 2.0
}
},
"type": "Fused"
},
{
"uid": "west fused spans in Morlaix",
"metadata": {
"location": {
"city": "Morlaix",
"region": "RLD",
"latitude": 3.0,
"longitude": 0.0
}
},
"type": "Fused"
},
{
"uid": "east fused spans in Corlay",
"metadata": {
"location": {
"city": "Corlay",
"region": "RLD",
"latitude": 2.0,
"longitude": 1.0
}
},
"type": "Fused"
},
{
"uid": "east fused spans in Loudeac",
"metadata": {
"location": {
"city": "Loudeac",
"region": "RLD",
"latitude": 2.0,
"longitude": 2.0
}
},
"type": "Fused"
},
{
"uid": "east fused spans in Morlaix",
"metadata": {
"location": {
"city": "Morlaix",
"region": "RLD",
"latitude": 3.0,
"longitude": 0.0
}
},
"type": "Fused"
},
{
"uid": "fiber (Lannion_CAS → Corlay)-F061",
"metadata": {
"location": {
"latitude": 2.0,
"longitude": 0.5
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 20.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Corlay → Loudeac)-F010",
"metadata": {
"location": {
"latitude": 2.0,
"longitude": 1.5
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 50.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Loudeac → Lorient_KMA)-F054",
"metadata": {
"location": {
"latitude": 2.0,
"longitude": 2.5
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Lorient_KMA → Vannes_KBE)-F055",
"metadata": {
"location": {
"latitude": 2.0,
"longitude": 3.5
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 10.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Lannion_CAS → Stbrieuc)-F056",
"metadata": {
"location": {
"latitude": 1.5,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Stbrieuc → Rennes_STA)-F057",
"metadata": {
"location": {
"latitude": 0.5,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 65.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Lannion_CAS → Morlaix)-F059",
"metadata": {
"location": {
"latitude": 2.5,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 40.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Morlaix → Brest_KLA)-F060",
"metadata": {
"location": {
"latitude": 3.5,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 35.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (toto → tata)-",
"metadata": {
"location": {
"latitude": 6.5,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 80.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Corlay → Lannion_CAS)-F061",
"metadata": {
"location": {
"latitude": 2.0,
"longitude": 0.5
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 20.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Loudeac → Corlay)-F010",
"metadata": {
"location": {
"latitude": 2.0,
"longitude": 1.5
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 50.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Lorient_KMA → Loudeac)-F054",
"metadata": {
"location": {
"latitude": 2.0,
"longitude": 2.5
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Vannes_KBE → Lorient_KMA)-F055",
"metadata": {
"location": {
"latitude": 2.0,
"longitude": 3.5
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 10.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Stbrieuc → Lannion_CAS)-F056",
"metadata": {
"location": {
"latitude": 1.5,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Rennes_STA → Stbrieuc)-F057",
"metadata": {
"location": {
"latitude": 0.5,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 65.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Morlaix → Lannion_CAS)-F059",
"metadata": {
"location": {
"latitude": 2.5,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 40.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Brest_KLA → Morlaix)-F060",
"metadata": {
"location": {
"latitude": 3.5,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 35.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (tata → toto)-",
"metadata": {
"location": {
"latitude": 6.5,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 80.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "east edfa in Lannion_CAS to Corlay",
"metadata": {
"location": {
"city": "Lannion_CAS",
"region": "RLD",
"latitude": 2.0,
"longitude": 0.0
}
},
"type": "Edfa",
"type_variety": "test",
"operational": {
"gain_target": 0,
"tilt_target": 0,
"out_voa": 0
}
},
{
"uid": "east edfa in Lorient_KMA to Loudeac",
"metadata": {
"location": {
"city": "Lorient_KMA",
"region": "RLD",
"latitude": 2.0,
"longitude": 3.0
}
},
"type": "Edfa",
"type_variety": "test",
"operational": {
"gain_target": 0,
"tilt_target": 0,
"out_voa": 0
}
}
],
"connections": [
{
"from_node": "roadm Lannion_CAS",
"to_node": "east edfa in Lannion_CAS to Corlay"
},
{
"from_node": "east edfa in Lannion_CAS to Corlay",
"to_node": "fiber (Lannion_CAS → Corlay)-F061"
},
{
"from_node": "fiber (Corlay → Lannion_CAS)-F061",
"to_node": "roadm Lannion_CAS"
},
{
"from_node": "roadm Lannion_CAS",
"to_node": "fiber (Lannion_CAS → Stbrieuc)-F056"
},
{
"from_node": "fiber (Stbrieuc → Lannion_CAS)-F056",
"to_node": "roadm Lannion_CAS"
},
{
"from_node": "roadm Lannion_CAS",
"to_node": "fiber (Lannion_CAS → Morlaix)-F059"
},
{
"from_node": "fiber (Morlaix → Lannion_CAS)-F059",
"to_node": "roadm Lannion_CAS"
},
{
"from_node": "fiber (Lannion_CAS → Corlay)-F061",
"to_node": "west fused spans in Corlay"
},
{
"from_node": "west fused spans in Corlay",
"to_node": "fiber (Corlay → Loudeac)-F010"
},
{
"from_node": "fiber (Loudeac → Corlay)-F010",
"to_node": "east fused spans in Corlay"
},
{
"from_node": "east fused spans in Corlay",
"to_node": "fiber (Corlay → Lannion_CAS)-F061"
},
{
"from_node": "fiber (Corlay → Loudeac)-F010",
"to_node": "west fused spans in Loudeac"
},
{
"from_node": "west fused spans in Loudeac",
"to_node": "fiber (Loudeac → Lorient_KMA)-F054"
},
{
"from_node": "fiber (Lorient_KMA → Loudeac)-F054",
"to_node": "east fused spans in Loudeac"
},
{
"from_node": "east fused spans in Loudeac",
"to_node": "fiber (Loudeac → Corlay)-F010"
},
{
"from_node": "roadm Lorient_KMA",
"to_node": "east edfa in Lorient_KMA to Loudeac"
},
{
"from_node": "east edfa in Lorient_KMA to Loudeac",
"to_node": "fiber (Lorient_KMA → Loudeac)-F054"
},
{
"from_node": "fiber (Loudeac → Lorient_KMA)-F054",
"to_node": "roadm Lorient_KMA"
},
{
"from_node": "roadm Lorient_KMA",
"to_node": "fiber (Lorient_KMA → Vannes_KBE)-F055"
},
{
"from_node": "fiber (Vannes_KBE → Lorient_KMA)-F055",
"to_node": "roadm Lorient_KMA"
},
{
"from_node": "roadm Vannes_KBE",
"to_node": "fiber (Vannes_KBE → Lorient_KMA)-F055"
},
{
"from_node": "fiber (Lorient_KMA → Vannes_KBE)-F055",
"to_node": "roadm Vannes_KBE"
},
{
"from_node": "fiber (Lannion_CAS → Stbrieuc)-F056",
"to_node": "fiber (Stbrieuc → Rennes_STA)-F057"
},
{
"from_node": "fiber (Rennes_STA → Stbrieuc)-F057",
"to_node": "fiber (Stbrieuc → Lannion_CAS)-F056"
},
{
"from_node": "roadm Rennes_STA",
"to_node": "fiber (Rennes_STA → Stbrieuc)-F057"
},
{
"from_node": "fiber (Stbrieuc → Rennes_STA)-F057",
"to_node": "roadm Rennes_STA"
},
{
"from_node": "fiber (Lannion_CAS → Morlaix)-F059",
"to_node": "west fused spans in Morlaix"
},
{
"from_node": "west fused spans in Morlaix",
"to_node": "fiber (Morlaix → Brest_KLA)-F060"
},
{
"from_node": "fiber (Brest_KLA → Morlaix)-F060",
"to_node": "east fused spans in Morlaix"
},
{
"from_node": "east fused spans in Morlaix",
"to_node": "fiber (Morlaix → Lannion_CAS)-F059"
},
{
"from_node": "roadm Brest_KLA",
"to_node": "fiber (Brest_KLA → Morlaix)-F060"
},
{
"from_node": "fiber (Morlaix → Brest_KLA)-F060",
"to_node": "roadm Brest_KLA"
},
{
"from_node": "roadm toto",
"to_node": "fiber (toto → tata)-"
},
{
"from_node": "fiber (tata → toto)-",
"to_node": "roadm toto"
},
{
"from_node": "roadm tata",
"to_node": "fiber (tata → toto)-"
},
{
"from_node": "fiber (toto → tata)-",
"to_node": "roadm tata"
},
{
"from_node": "trx Lannion_CAS",
"to_node": "roadm Lannion_CAS"
},
{
"from_node": "roadm Lannion_CAS",
"to_node": "trx Lannion_CAS"
},
{
"from_node": "trx Lorient_KMA",
"to_node": "roadm Lorient_KMA"
},
{
"from_node": "roadm Lorient_KMA",
"to_node": "trx Lorient_KMA"
},
{
"from_node": "trx Vannes_KBE",
"to_node": "roadm Vannes_KBE"
},
{
"from_node": "roadm Vannes_KBE",
"to_node": "trx Vannes_KBE"
},
{
"from_node": "trx Rennes_STA",
"to_node": "roadm Rennes_STA"
},
{
"from_node": "roadm Rennes_STA",
"to_node": "trx Rennes_STA"
},
{
"from_node": "trx Brest_KLA",
"to_node": "roadm Brest_KLA"
},
{
"from_node": "roadm Brest_KLA",
"to_node": "trx Brest_KLA"
},
{
"from_node": "trx toto",
"to_node": "roadm toto"
},
{
"from_node": "roadm toto",
"to_node": "trx toto"
},
{
"from_node": "trx tata",
"to_node": "roadm tata"
},
{
"from_node": "roadm tata",
"to_node": "trx tata"
}
]
}

View File

@@ -1,762 +0,0 @@
{
"elements": [
{
"uid": "trx Lannion_CAS",
"metadata": {
"location": {
"city": "Lannion_CAS",
"region": "RLD",
"latitude": 2.0,
"longitude": 0.0
}
},
"type": "Transceiver"
},
{
"uid": "trx Lorient_KMA",
"metadata": {
"location": {
"city": "Lorient_KMA",
"region": "RLD",
"latitude": 2.0,
"longitude": 3.0
}
},
"type": "Transceiver"
},
{
"uid": "trx Vannes_KBE",
"metadata": {
"location": {
"city": "Vannes_KBE",
"region": "RLD",
"latitude": 2.0,
"longitude": 4.0
}
},
"type": "Transceiver"
},
{
"uid": "trx Rennes_STA",
"metadata": {
"location": {
"city": "Rennes_STA",
"region": "RLD",
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Transceiver"
},
{
"uid": "trx Brest_KLA",
"metadata": {
"location": {
"city": "Brest_KLA",
"region": "RLD",
"latitude": 4.0,
"longitude": 0.0
}
},
"type": "Transceiver"
},
{
"uid": "trx toto",
"metadata": {
"location": {
"city": "toto",
"region": "",
"latitude": 6.0,
"longitude": 0.0
}
},
"type": "Transceiver"
},
{
"uid": "trx tata",
"metadata": {
"location": {
"city": "tata",
"region": "",
"latitude": 7.0,
"longitude": 0.0
}
},
"type": "Transceiver"
},
{
"uid": "roadm Lannion_CAS",
"metadata": {
"location": {
"city": "Lannion_CAS",
"region": "RLD",
"latitude": 2.0,
"longitude": 0.0
}
},
"type": "Roadm"
},
{
"uid": "roadm Lorient_KMA",
"metadata": {
"location": {
"city": "Lorient_KMA",
"region": "RLD",
"latitude": 2.0,
"longitude": 3.0
}
},
"type": "Roadm"
},
{
"uid": "roadm Vannes_KBE",
"metadata": {
"location": {
"city": "Vannes_KBE",
"region": "RLD",
"latitude": 2.0,
"longitude": 4.0
}
},
"type": "Roadm"
},
{
"uid": "roadm Rennes_STA",
"metadata": {
"location": {
"city": "Rennes_STA",
"region": "RLD",
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Roadm"
},
{
"uid": "roadm Brest_KLA",
"metadata": {
"location": {
"city": "Brest_KLA",
"region": "RLD",
"latitude": 4.0,
"longitude": 0.0
}
},
"type": "Roadm"
},
{
"uid": "roadm toto",
"metadata": {
"location": {
"city": "toto",
"region": "",
"latitude": 6.0,
"longitude": 0.0
}
},
"type": "Roadm"
},
{
"uid": "roadm tata",
"metadata": {
"location": {
"city": "tata",
"region": "",
"latitude": 7.0,
"longitude": 0.0
}
},
"type": "Roadm"
},
{
"uid": "west fused spans in Corlay",
"metadata": {
"location": {
"city": "Corlay",
"region": "RLD",
"latitude": 2.0,
"longitude": 1.0
}
},
"type": "Fused"
},
{
"uid": "west fused spans in Loudeac",
"metadata": {
"location": {
"city": "Loudeac",
"region": "RLD",
"latitude": 2.0,
"longitude": 2.0
}
},
"type": "Fused"
},
{
"uid": "west fused spans in Morlaix",
"metadata": {
"location": {
"city": "Morlaix",
"region": "RLD",
"latitude": 3.0,
"longitude": 0.0
}
},
"type": "Fused"
},
{
"uid": "east fused spans in Corlay",
"metadata": {
"location": {
"city": "Corlay",
"region": "RLD",
"latitude": 2.0,
"longitude": 1.0
}
},
"type": "Fused"
},
{
"uid": "east fused spans in Loudeac",
"metadata": {
"location": {
"city": "Loudeac",
"region": "RLD",
"latitude": 2.0,
"longitude": 2.0
}
},
"type": "Fused"
},
{
"uid": "east fused spans in Morlaix",
"metadata": {
"location": {
"city": "Morlaix",
"region": "RLD",
"latitude": 3.0,
"longitude": 0.0
}
},
"type": "Fused"
},
{
"uid": "fiber (Lannion_CAS → Corlay)-F061",
"metadata": {
"location": {
"latitude": 2.0,
"longitude": 0.5
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 20.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Corlay → Loudeac)-F010",
"metadata": {
"location": {
"latitude": 2.0,
"longitude": 1.5
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 50.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Loudeac → Lorient_KMA)-F054",
"metadata": {
"location": {
"latitude": 2.0,
"longitude": 2.5
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Lorient_KMA → Vannes_KBE)-F055",
"metadata": {
"location": {
"latitude": 2.0,
"longitude": 3.5
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 10.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Lannion_CAS → Stbrieuc)-F056",
"metadata": {
"location": {
"latitude": 1.5,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Stbrieuc → Rennes_STA)-F057",
"metadata": {
"location": {
"latitude": 0.5,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 65.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Lannion_CAS → Morlaix)-F059",
"metadata": {
"location": {
"latitude": 2.5,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 40.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Morlaix → Brest_KLA)-F060",
"metadata": {
"location": {
"latitude": 3.5,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 35.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (toto → tata)-",
"metadata": {
"location": {
"latitude": 6.5,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 80.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Corlay → Lannion_CAS)-F061",
"metadata": {
"location": {
"latitude": 2.0,
"longitude": 0.5
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 20.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Loudeac → Corlay)-F010",
"metadata": {
"location": {
"latitude": 2.0,
"longitude": 1.5
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 50.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Lorient_KMA → Loudeac)-F054",
"metadata": {
"location": {
"latitude": 2.0,
"longitude": 2.5
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Vannes_KBE → Lorient_KMA)-F055",
"metadata": {
"location": {
"latitude": 2.0,
"longitude": 3.5
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 10.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Stbrieuc → Lannion_CAS)-F056",
"metadata": {
"location": {
"latitude": 1.5,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Rennes_STA → Stbrieuc)-F057",
"metadata": {
"location": {
"latitude": 0.5,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 65.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Morlaix → Lannion_CAS)-F059",
"metadata": {
"location": {
"latitude": 2.5,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 40.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (Brest_KLA → Morlaix)-F060",
"metadata": {
"location": {
"latitude": 3.5,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 35.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (tata → toto)-",
"metadata": {
"location": {
"latitude": 6.5,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 80.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
}
],
"connections": [
{
"from_node": "roadm Lannion_CAS",
"to_node": "fiber (Lannion_CAS → Corlay)-F061"
},
{
"from_node": "fiber (Corlay → Lannion_CAS)-F061",
"to_node": "roadm Lannion_CAS"
},
{
"from_node": "roadm Lannion_CAS",
"to_node": "fiber (Lannion_CAS → Stbrieuc)-F056"
},
{
"from_node": "fiber (Stbrieuc → Lannion_CAS)-F056",
"to_node": "roadm Lannion_CAS"
},
{
"from_node": "roadm Lannion_CAS",
"to_node": "fiber (Lannion_CAS → Morlaix)-F059"
},
{
"from_node": "fiber (Morlaix → Lannion_CAS)-F059",
"to_node": "roadm Lannion_CAS"
},
{
"from_node": "fiber (Lannion_CAS → Corlay)-F061",
"to_node": "west fused spans in Corlay"
},
{
"from_node": "west fused spans in Corlay",
"to_node": "fiber (Corlay → Loudeac)-F010"
},
{
"from_node": "fiber (Loudeac → Corlay)-F010",
"to_node": "east fused spans in Corlay"
},
{
"from_node": "east fused spans in Corlay",
"to_node": "fiber (Corlay → Lannion_CAS)-F061"
},
{
"from_node": "fiber (Corlay → Loudeac)-F010",
"to_node": "west fused spans in Loudeac"
},
{
"from_node": "west fused spans in Loudeac",
"to_node": "fiber (Loudeac → Lorient_KMA)-F054"
},
{
"from_node": "fiber (Lorient_KMA → Loudeac)-F054",
"to_node": "east fused spans in Loudeac"
},
{
"from_node": "east fused spans in Loudeac",
"to_node": "fiber (Loudeac → Corlay)-F010"
},
{
"from_node": "roadm Lorient_KMA",
"to_node": "fiber (Lorient_KMA → Loudeac)-F054"
},
{
"from_node": "fiber (Loudeac → Lorient_KMA)-F054",
"to_node": "roadm Lorient_KMA"
},
{
"from_node": "roadm Lorient_KMA",
"to_node": "fiber (Lorient_KMA → Vannes_KBE)-F055"
},
{
"from_node": "fiber (Vannes_KBE → Lorient_KMA)-F055",
"to_node": "roadm Lorient_KMA"
},
{
"from_node": "roadm Vannes_KBE",
"to_node": "fiber (Vannes_KBE → Lorient_KMA)-F055"
},
{
"from_node": "fiber (Lorient_KMA → Vannes_KBE)-F055",
"to_node": "roadm Vannes_KBE"
},
{
"from_node": "fiber (Lannion_CAS → Stbrieuc)-F056",
"to_node": "fiber (Stbrieuc → Rennes_STA)-F057"
},
{
"from_node": "fiber (Rennes_STA → Stbrieuc)-F057",
"to_node": "fiber (Stbrieuc → Lannion_CAS)-F056"
},
{
"from_node": "roadm Rennes_STA",
"to_node": "fiber (Rennes_STA → Stbrieuc)-F057"
},
{
"from_node": "fiber (Stbrieuc → Rennes_STA)-F057",
"to_node": "roadm Rennes_STA"
},
{
"from_node": "fiber (Lannion_CAS → Morlaix)-F059",
"to_node": "west fused spans in Morlaix"
},
{
"from_node": "west fused spans in Morlaix",
"to_node": "fiber (Morlaix → Brest_KLA)-F060"
},
{
"from_node": "fiber (Brest_KLA → Morlaix)-F060",
"to_node": "east fused spans in Morlaix"
},
{
"from_node": "east fused spans in Morlaix",
"to_node": "fiber (Morlaix → Lannion_CAS)-F059"
},
{
"from_node": "roadm Brest_KLA",
"to_node": "fiber (Brest_KLA → Morlaix)-F060"
},
{
"from_node": "fiber (Morlaix → Brest_KLA)-F060",
"to_node": "roadm Brest_KLA"
},
{
"from_node": "roadm toto",
"to_node": "fiber (toto → tata)-"
},
{
"from_node": "fiber (tata → toto)-",
"to_node": "roadm toto"
},
{
"from_node": "roadm tata",
"to_node": "fiber (tata → toto)-"
},
{
"from_node": "fiber (toto → tata)-",
"to_node": "roadm tata"
},
{
"from_node": "trx Lannion_CAS",
"to_node": "roadm Lannion_CAS"
},
{
"from_node": "roadm Lannion_CAS",
"to_node": "trx Lannion_CAS"
},
{
"from_node": "trx Lorient_KMA",
"to_node": "roadm Lorient_KMA"
},
{
"from_node": "roadm Lorient_KMA",
"to_node": "trx Lorient_KMA"
},
{
"from_node": "trx Vannes_KBE",
"to_node": "roadm Vannes_KBE"
},
{
"from_node": "roadm Vannes_KBE",
"to_node": "trx Vannes_KBE"
},
{
"from_node": "trx Rennes_STA",
"to_node": "roadm Rennes_STA"
},
{
"from_node": "roadm Rennes_STA",
"to_node": "trx Rennes_STA"
},
{
"from_node": "trx Brest_KLA",
"to_node": "roadm Brest_KLA"
},
{
"from_node": "roadm Brest_KLA",
"to_node": "trx Brest_KLA"
},
{
"from_node": "trx toto",
"to_node": "roadm toto"
},
{
"from_node": "roadm toto",
"to_node": "trx toto"
},
{
"from_node": "trx tata",
"to_node": "roadm tata"
},
{
"from_node": "roadm tata",
"to_node": "trx tata"
}
]
}

View File

@@ -1,224 +0,0 @@
{
"path-request": [
{
"request-id": "0",
"source": "Lorient_KMA",
"destination": "Vannes_KBE",
"src-tp-id": "trx Lorient_KMA",
"dst-tp-id": "trx Vannes_KBE",
"path-constraints": {
"te-bandwidth": {
"technology": "flexi-grid",
"trx_type": "Voyager_16QAM",
"trx_mode": "16QAM",
"effective-freq-slot": [
{
"n": "null",
"m": "null"
}
],
"spacing": 50000000000.0,
"max-nb-of-channel": 80,
"output-power": 0.0012589254117941673,
"path_bandwidth": 0
}
},
"optimizations": {
"explicit-route-include-objects": []
}
},
{
"request-id": "1",
"source": "Brest_KLA",
"destination": "Vannes_KBE",
"src-tp-id": "trx Brest_KLA",
"dst-tp-id": "trx Vannes_KBE",
"path-constraints": {
"te-bandwidth": {
"technology": "flexi-grid",
"trx_type": "Voyager_16QAM",
"trx_mode": "16QAM",
"effective-freq-slot": [
{
"n": "null",
"m": "null"
}
],
"spacing": 50000000000.0,
"max-nb-of-channel": 80,
"output-power": 0.0012589254117941673,
"path_bandwidth": 0
}
},
"optimizations": {
"explicit-route-include-objects": [
{
"index": 0,
"unnumbered-hop": {
"node-id": "Lannion_CAS",
"link-tp-id": "link-tp-id is not used",
"hop-type": "loose",
"direction": "direction is not used"
},
"label-hop": {
"te-label": {
"generic": "generic is not used",
"direction": "direction is not used"
}
}
},
{
"index": 1,
"unnumbered-hop": {
"node-id": "Lorient_KMA",
"link-tp-id": "link-tp-id is not used",
"hop-type": "loose",
"direction": "direction is not used"
},
"label-hop": {
"te-label": {
"generic": "generic is not used",
"direction": "direction is not used"
}
}
}
]
}
},
{
"request-id": "3",
"source": "Lannion_CAS",
"destination": "Rennes_STA",
"src-tp-id": "trx Lannion_CAS",
"dst-tp-id": "trx Rennes_STA",
"path-constraints": {
"te-bandwidth": {
"technology": "flexi-grid",
"trx_type": "vendorA_trx-type1",
"trx_mode": "PS_SP64_1",
"effective-freq-slot": [
{
"n": "null",
"m": "null"
}
],
"spacing": 50000000000.0,
"max-nb-of-channel": 80,
"output-power": 0.0012589254117941673,
"path_bandwidth": 0
}
},
"optimizations": {
"explicit-route-include-objects": []
}
},
{
"request-id": "4",
"source": "Rennes_STA",
"destination": "Lannion_CAS",
"src-tp-id": "trx Rennes_STA",
"dst-tp-id": "trx Lannion_CAS",
"path-constraints": {
"te-bandwidth": {
"technology": "flexi-grid",
"trx_type": "vendorA_trx-type1",
"trx_mode": "PS_SP64_2",
"effective-freq-slot": [
{
"n": "null",
"m": "null"
}
],
"spacing": 75000000000.0,
"max-nb-of-channel": 64,
"output-power": 0.0019952623149688794,
"path_bandwidth": 0
}
},
"optimizations": {
"explicit-route-include-objects": []
}
},
{
"request-id": "5",
"source": "Lorient_KMA",
"destination": "Lannion_CAS",
"src-tp-id": "trx Lorient_KMA",
"dst-tp-id": "trx Lannion_CAS",
"path-constraints": {
"te-bandwidth": {
"technology": "flexi-grid",
"trx_type": "Voyager_16QAM",
"trx_mode": "16QAM",
"effective-freq-slot": [
{
"n": "null",
"m": "null"
}
],
"spacing": 50000000000.0,
"max-nb-of-channel": 80,
"output-power": 0.0012589254117941673,
"path_bandwidth": 0
}
},
"optimizations": {
"explicit-route-include-objects": [
{
"index": 0,
"unnumbered-hop": {
"node-id": "toto",
"link-tp-id": "link-tp-id is not used",
"hop-type": "loose",
"direction": "direction is not used"
},
"label-hop": {
"te-label": {
"generic": "generic is not used",
"direction": "direction is not used"
}
}
}
]
}
}
],
"synchronization": [
{
"synchronization-id": "0",
"svec": {
"relaxable": "False",
"link-diverse": "True",
"node-diverse": "True",
"request-id-number": [
"0",
"0"
]
}
},
{
"synchronization-id": "3",
"svec": {
"relaxable": "False",
"link-diverse": "True",
"node-diverse": "True",
"request-id-number": [
"3",
"4"
]
}
},
{
"synchronization-id": "5",
"svec": {
"relaxable": "False",
"link-diverse": "True",
"node-diverse": "True",
"request-id-number": [
"5",
"0"
]
}
}
]
}

View File

@@ -1,730 +0,0 @@
{
"elements": [
{
"uid": "trx a",
"metadata": {
"location": {
"city": "a",
"region": "",
"latitude": 0,
"longitude": 0
}
},
"type": "Transceiver"
},
{
"uid": "trx b",
"metadata": {
"location": {
"city": "b",
"region": "",
"latitude": 0,
"longitude": 0
}
},
"type": "Transceiver"
},
{
"uid": "trx c",
"metadata": {
"location": {
"city": "c",
"region": "",
"latitude": 0,
"longitude": 0
}
},
"type": "Transceiver"
},
{
"uid": "trx d",
"metadata": {
"location": {
"city": "d",
"region": "",
"latitude": 0,
"longitude": 0
}
},
"type": "Transceiver"
},
{
"uid": "trx e",
"metadata": {
"location": {
"city": "e",
"region": "",
"latitude": 0,
"longitude": 0
}
},
"type": "Transceiver"
},
{
"uid": "trx f",
"metadata": {
"location": {
"city": "f",
"region": "",
"latitude": 0,
"longitude": 0
}
},
"type": "Transceiver"
},
{
"uid": "trx g",
"metadata": {
"location": {
"city": "g",
"region": "",
"latitude": 0,
"longitude": 0
}
},
"type": "Transceiver"
},
{
"uid": "trx h",
"metadata": {
"location": {
"city": "h",
"region": "",
"latitude": 0,
"longitude": 0
}
},
"type": "Transceiver"
},
{
"uid": "roadm a",
"metadata": {
"location": {
"city": "a",
"region": "",
"latitude": 0,
"longitude": 0
}
},
"type": "Roadm"
},
{
"uid": "roadm b",
"metadata": {
"location": {
"city": "b",
"region": "",
"latitude": 0,
"longitude": 0
}
},
"type": "Roadm"
},
{
"uid": "roadm c",
"metadata": {
"location": {
"city": "c",
"region": "",
"latitude": 0,
"longitude": 0
}
},
"type": "Roadm"
},
{
"uid": "roadm d",
"metadata": {
"location": {
"city": "d",
"region": "",
"latitude": 0,
"longitude": 0
}
},
"type": "Roadm"
},
{
"uid": "roadm e",
"metadata": {
"location": {
"city": "e",
"region": "",
"latitude": 0,
"longitude": 0
}
},
"type": "Roadm"
},
{
"uid": "roadm f",
"metadata": {
"location": {
"city": "f",
"region": "",
"latitude": 0,
"longitude": 0
}
},
"type": "Roadm"
},
{
"uid": "roadm g",
"metadata": {
"location": {
"city": "g",
"region": "",
"latitude": 0,
"longitude": 0
}
},
"type": "Roadm"
},
{
"uid": "roadm h",
"metadata": {
"location": {
"city": "h",
"region": "",
"latitude": 0,
"longitude": 0
}
},
"type": "Roadm"
},
{
"uid": "fiber (a \u2192 b)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 30.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (a \u2192 c)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 30.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (c \u2192 d)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 50.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (c \u2192 f)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (b \u2192 f)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 70.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (e \u2192 d)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 80.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (e \u2192 g)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 90.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (f \u2192 h)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 100.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (h \u2192 g)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 110.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (b \u2192 a)-F061",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 30.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (c \u2192 a)-F010",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 30.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (d \u2192 c)-F054",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 50.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (f \u2192 c)-F055",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 60.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (f \u2192 b)-F056",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 70.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (d \u2192 e)-F057",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 80.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (g \u2192 e)-F059",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 90.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (h \u2192 f)-F060",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 100.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
},
{
"uid": "fiber (g \u2192 h)-",
"metadata": {
"location": {
"latitude": 0.0,
"longitude": 0.0
}
},
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 110.0,
"length_units": "km",
"loss_coef": 0.2,
"con_in": null,
"con_out": null
}
}
],
"connections": [
{
"from_node": "roadm a",
"to_node": "fiber (a \u2192 b)-"
},
{
"from_node": "fiber (b \u2192 a)-F061",
"to_node": "roadm a"
},
{
"from_node": "roadm a",
"to_node": "fiber (a \u2192 c)-"
},
{
"from_node": "fiber (c \u2192 a)-F010",
"to_node": "roadm a"
},
{
"from_node": "roadm b",
"to_node": "fiber (b \u2192 a)-F061"
},
{
"from_node": "fiber (a \u2192 b)-",
"to_node": "roadm b"
},
{
"from_node": "roadm b",
"to_node": "fiber (b \u2192 f)-"
},
{
"from_node": "fiber (f \u2192 b)-F056",
"to_node": "roadm b"
},
{
"from_node": "roadm c",
"to_node": "fiber (c \u2192 a)-F010"
},
{
"from_node": "fiber (a \u2192 c)-",
"to_node": "roadm c"
},
{
"from_node": "roadm c",
"to_node": "fiber (c \u2192 d)-"
},
{
"from_node": "fiber (d \u2192 c)-F054",
"to_node": "roadm c"
},
{
"from_node": "roadm c",
"to_node": "fiber (c \u2192 f)-"
},
{
"from_node": "fiber (f \u2192 c)-F055",
"to_node": "roadm c"
},
{
"from_node": "roadm d",
"to_node": "fiber (d \u2192 c)-F054"
},
{
"from_node": "fiber (c \u2192 d)-",
"to_node": "roadm d"
},
{
"from_node": "roadm d",
"to_node": "fiber (d \u2192 e)-F057"
},
{
"from_node": "fiber (e \u2192 d)-",
"to_node": "roadm d"
},
{
"from_node": "roadm e",
"to_node": "fiber (e \u2192 d)-"
},
{
"from_node": "fiber (d \u2192 e)-F057",
"to_node": "roadm e"
},
{
"from_node": "roadm e",
"to_node": "fiber (e \u2192 g)-"
},
{
"from_node": "fiber (g \u2192 e)-F059",
"to_node": "roadm e"
},
{
"from_node": "roadm f",
"to_node": "fiber (f \u2192 c)-F055"
},
{
"from_node": "fiber (c \u2192 f)-",
"to_node": "roadm f"
},
{
"from_node": "roadm f",
"to_node": "fiber (f \u2192 b)-F056"
},
{
"from_node": "fiber (b \u2192 f)-",
"to_node": "roadm f"
},
{
"from_node": "roadm f",
"to_node": "fiber (f \u2192 h)-"
},
{
"from_node": "fiber (h \u2192 f)-F060",
"to_node": "roadm f"
},
{
"from_node": "roadm g",
"to_node": "fiber (g \u2192 e)-F059"
},
{
"from_node": "fiber (e \u2192 g)-",
"to_node": "roadm g"
},
{
"from_node": "roadm g",
"to_node": "fiber (g \u2192 h)-"
},
{
"from_node": "fiber (h \u2192 g)-",
"to_node": "roadm g"
},
{
"from_node": "roadm h",
"to_node": "fiber (h \u2192 f)-F060"
},
{
"from_node": "fiber (f \u2192 h)-",
"to_node": "roadm h"
},
{
"from_node": "roadm h",
"to_node": "fiber (h \u2192 g)-"
},
{
"from_node": "fiber (g \u2192 h)-",
"to_node": "roadm h"
},
{
"from_node": "trx a",
"to_node": "roadm a"
},
{
"from_node": "roadm a",
"to_node": "trx a"
},
{
"from_node": "trx b",
"to_node": "roadm b"
},
{
"from_node": "roadm b",
"to_node": "trx b"
},
{
"from_node": "trx c",
"to_node": "roadm c"
},
{
"from_node": "roadm c",
"to_node": "trx c"
},
{
"from_node": "trx d",
"to_node": "roadm d"
},
{
"from_node": "roadm d",
"to_node": "trx d"
},
{
"from_node": "trx e",
"to_node": "roadm e"
},
{
"from_node": "roadm e",
"to_node": "trx e"
},
{
"from_node": "trx f",
"to_node": "roadm f"
},
{
"from_node": "roadm f",
"to_node": "trx f"
},
{
"from_node": "trx g",
"to_node": "roadm g"
},
{
"from_node": "roadm g",
"to_node": "trx g"
},
{
"from_node": "trx h",
"to_node": "roadm h"
},
{
"from_node": "roadm h",
"to_node": "trx h"
}
]
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -9,8 +9,8 @@
"path-constraints": {
"te-bandwidth": {
"technology": "flexi-grid",
"trx_type": "Voyager_16QAM",
"trx_mode": "16QAM",
"trx_type": "Voyager",
"trx_mode": "mode 1",
"effective-freq-slot": [
{
"n": "null",
@@ -19,8 +19,8 @@
],
"spacing": 50000000000.0,
"max-nb-of-channel": 80,
"output-power": 0.0012589254117941673,
"path_bandwidth": 0
"output-power": null,
"path_bandwidth": 100000000000.0
}
},
"optimizations": {
@@ -36,8 +36,8 @@
"path-constraints": {
"te-bandwidth": {
"technology": "flexi-grid",
"trx_type": "Voyager_16QAM",
"trx_mode": "16QAM",
"trx_type": "Voyager",
"trx_mode": "mode 1",
"effective-freq-slot": [
{
"n": "null",
@@ -45,7 +45,7 @@
}
],
"spacing": 50000000000.0,
"max-nb-of-channel": 80,
"max-nb-of-channel": null,
"output-power": 0.0012589254117941673,
"path_bandwidth": 0
}
@@ -55,7 +55,7 @@
{
"index": 0,
"unnumbered-hop": {
"node-id": "Lannion_CAS",
"node-id": "roadm Brest_KLA",
"link-tp-id": "link-tp-id is not used",
"hop-type": "loose",
"direction": "direction is not used"
@@ -70,7 +70,37 @@
{
"index": 1,
"unnumbered-hop": {
"node-id": "Lorient_KMA",
"node-id": "roadm Lannion_CAS",
"link-tp-id": "link-tp-id is not used",
"hop-type": "loose",
"direction": "direction is not used"
},
"label-hop": {
"te-label": {
"generic": "generic is not used",
"direction": "direction is not used"
}
}
},
{
"index": 2,
"unnumbered-hop": {
"node-id": "roadm Lorient_KMA",
"link-tp-id": "link-tp-id is not used",
"hop-type": "loose",
"direction": "direction is not used"
},
"label-hop": {
"te-label": {
"generic": "generic is not used",
"direction": "direction is not used"
}
}
},
{
"index": 3,
"unnumbered-hop": {
"node-id": "roadm Vannes_KBE",
"link-tp-id": "link-tp-id is not used",
"hop-type": "loose",
"direction": "direction is not used"
@@ -95,7 +125,7 @@
"te-bandwidth": {
"technology": "flexi-grid",
"trx_type": "vendorA_trx-type1",
"trx_mode": "PS_SP64_1",
"trx_mode": "mode 1",
"effective-freq-slot": [
{
"n": "null",
@@ -105,7 +135,7 @@
"spacing": 50000000000.0,
"max-nb-of-channel": 80,
"output-power": 0.0012589254117941673,
"path_bandwidth": 0
"path_bandwidth": 60000000000.0
}
},
"optimizations": {
@@ -122,7 +152,7 @@
"te-bandwidth": {
"technology": "flexi-grid",
"trx_type": "vendorA_trx-type1",
"trx_mode": "PS_SP64_2",
"trx_mode": "mode 2",
"effective-freq-slot": [
{
"n": "null",
@@ -130,9 +160,9 @@
}
],
"spacing": 75000000000.0,
"max-nb-of-channel": 64,
"output-power": 0.0019952623149688794,
"path_bandwidth": 0
"max-nb-of-channel": null,
"output-power": null,
"path_bandwidth": 150000000000.0
}
},
"optimizations": {
@@ -141,61 +171,33 @@
},
{
"request-id": "5",
"source": "Lorient_KMA",
"source": "Rennes_STA",
"destination": "Lannion_CAS",
"src-tp-id": "trx Lorient_KMA",
"src-tp-id": "trx Rennes_STA",
"dst-tp-id": "trx Lannion_CAS",
"path-constraints": {
"te-bandwidth": {
"technology": "flexi-grid",
"trx_type": "Voyager_16QAM",
"trx_mode": "16QAM",
"trx_type": "vendorA_trx-type1",
"trx_mode": "mode 2",
"effective-freq-slot": [
{
"n": "null",
"m": "null"
}
],
"spacing": 50000000000.0,
"max-nb-of-channel": 80,
"output-power": 0.0012589254117941673,
"path_bandwidth": 0
"spacing": 75000000000.0,
"max-nb-of-channel": 63,
"output-power": 0.0019952623149688794,
"path_bandwidth": 20000000000.0
}
},
"optimizations": {
"explicit-route-include-objects": [
{
"index": 0,
"unnumbered-hop": {
"node-id": "toto",
"link-tp-id": "link-tp-id is not used",
"hop-type": "loose",
"direction": "direction is not used"
},
"label-hop": {
"te-label": {
"generic": "generic is not used",
"direction": "direction is not used"
}
}
}
]
"explicit-route-include-objects": []
}
}
],
"synchronization": [
{
"synchronization-id": "0",
"svec": {
"relaxable": "False",
"link-diverse": "True",
"node-diverse": "True",
"request-id-number": [
"0",
"0"
]
}
},
{
"synchronization-id": "3",
"svec": {
@@ -204,21 +206,21 @@
"node-diverse": "True",
"request-id-number": [
"3",
"4"
"1"
]
}
},
{
"synchronization-id": "5",
"synchronization-id": "4",
"svec": {
"relaxable": "False",
"link-diverse": "True",
"node-diverse": "True",
"request-id-number": [
"5",
"0"
"4",
"5"
]
}
}
]
}
}

View File

@@ -9,8 +9,8 @@ from json import load
from gnpy.core.elements import Transceiver, Fiber, Edfa
from gnpy.core.utils import lin2db, db2lin
from gnpy.core.info import create_input_spectral_information, SpectralInformation, Channel, Power, Pref
from gnpy.core.equipment import load_equipment, automatic_fmax
from gnpy.core.network import build_network, load_network, set_roadm_loss
from gnpy.core.equipment import load_equipment, automatic_fmax, automatic_nch
from gnpy.core.network import build_network, load_network
from pathlib import Path
import pytest
@@ -79,7 +79,7 @@ def test_variable_gain_nf(gain, nf_expected, setup_edfa_variable_gain, si):
pin = pin/db2lin(gain)
baud_rates = array([c.baud_rate for c in si.carriers])
edfa.operational.gain_target = gain
pref = Pref(0, -gain)
pref = Pref(0, -gain, lin2db(len(frequencies)))
edfa.interpol_params(frequencies, pin, baud_rates, pref)
result = edfa.nf
assert pytest.approx(nf_expected, abs=0.01) == result[0]
@@ -93,7 +93,7 @@ def test_fixed_gain_nf(gain, nf_expected, setup_edfa_fixed_gain, si):
pin = pin/db2lin(gain)
baud_rates = array([c.baud_rate for c in si.carriers])
edfa.operational.gain_target = gain
pref = Pref(0, -gain)
pref = Pref(0, -gain, lin2db(len(frequencies)))
edfa.interpol_params(frequencies, pin, baud_rates, pref)
assert pytest.approx(nf_expected, abs=0.01) == edfa.nf[0]
@@ -118,7 +118,7 @@ def test_compare_nf_models(gain, setup_edfa_variable_gain, si):
pin = pin/db2lin(gain)
baud_rates = array([c.baud_rate for c in si.carriers])
edfa.operational.gain_target = gain
pref = Pref(0, -gain)
pref = Pref(0, -gain, lin2db(len(frequencies)))
edfa.interpol_params(frequencies, pin, baud_rates, pref)
nf_model = edfa.nf[0]
edfa.interpol_params(frequencies, pin, baud_rates, pref)
@@ -137,7 +137,7 @@ def test_ase_noise(gain, si, setup_edfa_variable_gain, setup_trx, bw):
pin = array([c.power.signal+c.power.nli+c.power.ase for c in si.carriers])
baud_rates = array([c.baud_rate for c in si.carriers])
edfa.operational.gain_target = gain
pref = Pref(0, 0)
pref = Pref(0, 0, lin2db(len(frequencies)))
edfa.interpol_params(frequencies, pin, baud_rates, pref)
nf = edfa.nf
pin = lin2db(pin[0]*1e3)

View File

@@ -25,9 +25,9 @@ from gnpy.core.request import (compute_path_dsjctn, isdisjoint , find_reversed_p
from gnpy.core.utils import db2lin, lin2db
from gnpy.core.elements import Roadm
network_file_name = Path(__file__).parent.parent / 'tests/data/meshTopologyToy.json'
service_file_name = Path(__file__).parent.parent / 'tests/data/meshTopologyToy_services.json'
result_file_name = Path(__file__).parent.parent / 'tests/data/meshTopologyToy_results.json'
network_file_name = Path(__file__).parent.parent / 'tests/data/testTopology_expected.json'
service_file_name = Path(__file__).parent.parent / 'tests/data/testTopology_testservices.json'
result_file_name = Path(__file__).parent.parent / 'tests/data/testTopology_testresults.json'
eqpt_library_name = Path(__file__).parent.parent / 'tests/data/eqpt_config.json'
@pytest.mark.parametrize("net",[network_file_name])

View File

@@ -20,9 +20,9 @@ from gnpy.core.request import compute_path_dsjctn, isdisjoint , find_reversed_pa
from gnpy.core.utils import db2lin, lin2db
from gnpy.core.elements import Roadm
network_file_name = Path(__file__).parent.parent / 'tests/data/meshTopologyToy.json'
service_file_name = Path(__file__).parent.parent / 'tests/data/meshTopologyToy_services.json'
result_file_name = Path(__file__).parent.parent / 'tests/data/meshTopologyToy_results.json'
network_file_name = Path(__file__).parent.parent / 'tests/data/testTopology_expected.json'
service_file_name = Path(__file__).parent.parent / 'tests/data/testTopology_testservices.json'
result_file_name = Path(__file__).parent.parent / 'tests/data/testTopology_testresults.json'
eqpt_library_name = Path(__file__).parent.parent / 'tests/data/eqpt_config.json'
@pytest.mark.parametrize("net",[network_file_name])

View File

@@ -11,9 +11,12 @@ from gnpy.core import network_from_json
from gnpy.core.elements import Transceiver, Fiber, Edfa
from gnpy.core.utils import lin2db, db2lin
from gnpy.core.info import SpectralInformation, Channel, Power
from gnpy.core.network import save_network, build_network
from tests.compare import compare_networks, compare_services
from gnpy.core.convert import convert_file
from gnpy.core.service_sheet import convert_service_sheet
from gnpy.core.equipment import load_equipment, automatic_nch
from gnpy.core.network import load_network
from pathlib import Path
import filecmp
from os import unlink
@@ -28,10 +31,8 @@ eqpt_filename = DATA_DIR / 'eqpt_config.json'
# - ..._expected.json for the reference output
@pytest.mark.parametrize('xls_input,expected_json_output', {
DATA_DIR / 'excelTestFile.xls': DATA_DIR / 'excelTestFile_expected.json',
DATA_DIR / 'CORONET_Global_Topology.xls': DATA_DIR / 'CORONET_Global_Topology_expected.json',
DATA_DIR / 'meshTopologyExampleV2.xls': DATA_DIR / 'meshTopologyExampleV2_expected.json',
DATA_DIR / 'meshTopologyExampleV2Eqpt.xls': DATA_DIR / 'meshTopologyExampleV2Eqpt_expected.json',
DATA_DIR / 'testTopology.xls': DATA_DIR / 'testTopology_expected.json',
}.items())
def test_excel_json_generation(xls_input, expected_json_output):
convert_file(xls_input)
@@ -39,7 +40,7 @@ def test_excel_json_generation(xls_input, expected_json_output):
actual_json_output = xls_input.with_suffix('.json')
with open(actual_json_output, encoding='utf-8') as f:
actual = load(f)
#unlink(actual_json_output)
unlink(actual_json_output)
with open(expected_json_output, encoding='utf-8') as f:
expected = load(f)
@@ -52,14 +53,84 @@ def test_excel_json_generation(xls_input, expected_json_output):
assert not results.connections.extra
assert not results.connections.different
# assume json entries
# test that the build network gives correct results
# TODO !!
# assume xls entries
# test that the build network gives correct results in gain mode
#
@pytest.mark.parametrize('xls_input,expected_json_output', {
DATA_DIR / 'CORONET_Global_Topology.xls': DATA_DIR / 'CORONET_Global_Topology_auto_design_expected.json',
DATA_DIR / 'testTopology.xls': DATA_DIR / 'testTopology_auto_design_expected.json',
}.items())
def test_auto_design_generation_fromxlsgainmode(xls_input, expected_json_output):
equipment = load_equipment(eqpt_filename)
network = load_network(xls_input,equipment)
# in order to test the Eqpt sheet and load gain target, change the power-mode to False (to be in gain mode)
equipment['Span']['default'].power_mode = False
# Build the network once using the default power defined in SI in eqpt config
p_db = equipment['SI']['default'].power_dbm
p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,\
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing))
build_network(network, equipment, p_db, p_total_db)
save_network(xls_input, network)
actual_json_output = f'{str(xls_input)[0:len(str(xls_input))-4]}_auto_design.json'
with open(actual_json_output, encoding='utf-8') as f:
actual = load(f)
unlink(actual_json_output)
with open(expected_json_output, encoding='utf-8') as f:
expected = load(f)
results = compare_networks(expected, actual)
assert not results.elements.missing
assert not results.elements.extra
assert not results.elements.different
assert not results.connections.missing
assert not results.connections.extra
assert not results.connections.different
#test that autodesign creates same file as an input file already autodesigned
@pytest.mark.parametrize('json_input,expected_json_output', {
DATA_DIR / 'CORONET_Global_Topology_auto_design_expected.json': DATA_DIR / 'CORONET_Global_Topology_auto_design_expected.json',
DATA_DIR / 'testTopology_auto_design_expected.json': DATA_DIR / 'testTopology_auto_design_expected.json',
}.items())
def test_auto_design_generation_fromjson(json_input, expected_json_output):
equipment = load_equipment(eqpt_filename)
network = load_network(json_input,equipment)
# in order to test the Eqpt sheet and load gain target, change the power-mode to False (to be in gain mode)
equipment['Span']['default'].power_mode = False
# Build the network once using the default power defined in SI in eqpt config
p_db = equipment['SI']['default'].power_dbm
p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,\
equipment['SI']['default'].f_max, equipment['SI']['default'].spacing))
build_network(network, equipment, p_db, p_total_db)
save_network(json_input, network)
actual_json_output = f'{str(json_input)[0:len(str(json_input))-5]}_auto_design.json'
with open(actual_json_output, encoding='utf-8') as f:
actual = load(f)
unlink(actual_json_output)
with open(expected_json_output, encoding='utf-8') as f:
expected = load(f)
results = compare_networks(expected, actual)
assert not results.elements.missing
assert not results.elements.extra
assert not results.elements.different
assert not results.connections.missing
assert not results.connections.extra
assert not results.connections.different
# test services creation
@pytest.mark.parametrize('xls_input,expected_json_output', {
DATA_DIR / 'excelTestFile.xls': DATA_DIR / 'excelTestFile_services_expected.json',
DATA_DIR / 'meshTopologyExampleV2.xls': DATA_DIR / 'meshTopologyExampleV2_services_expected.json',
DATA_DIR / 'meshTopologyExampleV2Eqpt.xls': DATA_DIR / 'meshTopologyExampleV2Eqpt_services_expected.json',
DATA_DIR / 'testTopology.xls': DATA_DIR / 'testTopology_services_expected.json',
}.items())
def test_excel_service_json_generation(xls_input, expected_json_output):
convert_service_sheet(xls_input, eqpt_filename)

View File

@@ -47,12 +47,8 @@ def propagation(input_power, con_in, con_out,dest):
p = input_power
p = db2lin(p) * 1e-3
spacing = 0.05 # THz
si = SpectralInformation() # SI units: W, Hz
si = si.update(carriers=[
Channel(f, (191.3 + spacing * f) * 1e12, 32e9, 0.15, Power(p, 0, 0))
for f in range(1,80)
])
spacing = 50e9 # THz
si = create_input_spectral_information(191.3e12, 191.3e12+79*spacing, 0.15, 32e9, p, spacing)
source = next(transceivers[uid] for uid in transceivers if uid == 'trx A')
sink = next(transceivers[uid] for uid in transceivers if uid == dest)
path = dijkstra_path(network, source, sink)