mirror of
				https://github.com/Telecominfraproject/oopt-gnpy.git
				synced 2025-10-31 01:57:54 +00:00 
			
		
		
		
	Merge branch 'develop'
This commit is contained in:
		
							
								
								
									
										231
									
								
								README.rst
									
									
									
									
									
								
							
							
						
						
									
										231
									
								
								README.rst
									
									
									
									
									
								
							| @@ -21,34 +21,9 @@ Documentation: https://gnpy.readthedocs.io | |||||||
| Branches and Tagged Releases | 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 `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 | How to Install | ||||||
| -------------- | -------------- | ||||||
| @@ -62,10 +37,9 @@ How to Install | |||||||
| It is recommended that you use a "virtual environment" when installing `gnpy`. | It is recommended that you use a "virtual environment" when installing `gnpy`. | ||||||
| Do not install `gnpy` on your system Python. | Do not install `gnpy` on your system Python. | ||||||
|  |  | ||||||
| We recommend the use of the Anaconda Python distribution | We recommend the use of the `Anaconda Python distribution <https://www.anaconda.com/download>`_ which comes with many scientific computing | ||||||
| (https://www.anaconda.com/download) which comes with many scientific computing |  | ||||||
| dependencies pre-installed. Anaconda creates a base "virtual environment" for | 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: | environments" yourself (see: | ||||||
| https://conda.io/docs/user-guide/tasks/manage-environments.html) | 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 |     $ python setup.py install                                    # install | ||||||
|  |  | ||||||
| To test that `gnpy` was successfully installed, you can run this command. If it | 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`. | `gnpy`. | ||||||
|  |  | ||||||
| .. code-block:: shell | .. code-block:: shell | ||||||
| @@ -193,59 +167,59 @@ information to transmit.) | |||||||
| The EDFA equipment library is a list of supported amplifiers. New amplifiers | 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: | 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. | 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` | 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. | 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: | For all amplifier models: | ||||||
|  |  | ||||||
| +----------------------+-----------+-----------------------------------------+ | +------------------------+-----------+-----------------------------------------+ | ||||||
| | field                |   type    | description                             | | | field                  |   type    | description                             | | ||||||
| +======================+===========+=========================================+ | +========================+===========+=========================================+ | ||||||
| | `type_variety`       | (string)  | a unique name to ID the amplifier in the| | | ``type_variety``       | (string)  | a unique name to ID the amplifier in the| | ||||||
| |                      |           | JSON/Excel template topology input file | | |                        |           | JSON/Excel template topology input file | | ||||||
| +----------------------+-----------+-----------------------------------------+ | +------------------------+-----------+-----------------------------------------+ | ||||||
| | `out_voa_auto`       | (boolean) | auto_design feature to optimize the     | | | ``out_voa_auto``       | (boolean) | auto_design feature to optimize the     | | ||||||
| |                      |           | amplifier output VOA. If true, output   | | |                        |           | amplifier output VOA. If true, output   | | ||||||
| |                      |           | VOA is present and will be used to push | | |                        |           | VOA is present and will be used to push | | ||||||
| |                      |           | amplifier gain to its maximum, within   | | |                        |           | amplifier gain to its maximum, within   | | ||||||
| |                      |           | EOL power margins.                      | | |                        |           | EOL power margins.                      | | ||||||
| +----------------------+-----------+-----------------------------------------+ | +------------------------+-----------+-----------------------------------------+ | ||||||
| | `allowed_for_design` | (boolean) | If false, the amplifier will not be     | | | ``allowed_for_design`` | (boolean) | If false, the amplifier will not be     | | ||||||
| |                      |           | picked by auto-design but it can still  | | |                        |           | picked by auto-design but it can still  | | ||||||
| |                      |           | be used as a manual input (from JSON or | | |                        |           | be used as a manual input (from JSON or | | ||||||
| |                      |           | Excel template topology files.)         | | |                        |           | 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: | 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                             | | | 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   | | |                      |           | JSON or Excel template topology input   | | ||||||
| |                      |           | file                                    | | |                      |           | 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 | 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 | 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 | 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                             | | | 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     | | |                      |           | the JSON or Excel template topology     | | ||||||
| |                      |           | input file                              | | |                      |           | 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  | | |                      |           | transponder. New modes can be added at  | | ||||||
| |                      |           | will by the user. The modes are specific| | |                      |           | will by the user. The modes are specific| | ||||||
| |                      |           | to each transponder type_variety.       | | |                      |           | to each transponder type_variety.       | | ||||||
| @@ -257,34 +231,34 @@ The modes are defined as follows: | |||||||
| +----------------------+-----------+-----------------------------------------+ | +----------------------+-----------+-----------------------------------------+ | ||||||
| | field                | type      | description                             | | | field                | type      | description                             | | ||||||
| +======================+===========+=========================================+ | +======================+===========+=========================================+ | ||||||
| | `format`             | (string)  | a unique name to ID the mode.           | | | ``format``           | (string)  | a unique name to ID the mode            | | ||||||
| +----------------------+-----------+-----------------------------------------+ | +----------------------+-----------+-----------------------------------------+ | ||||||
| | `baud_rate`          | (number)  | in Hz                                   | | | ``baud_rate``        | (number)  | in Hz                                   | | ||||||
| +----------------------+-----------+-----------------------------------------+ | +----------------------+-----------+-----------------------------------------+ | ||||||
| | `OSNR`               | (number)  | min required OSNR in 0.1nm (dB)         | | | ``OSNR``             | (number)  | min required OSNR in 0.1nm (dB)         | | ||||||
| +----------------------+-----------+-----------------------------------------+ | +----------------------+-----------+-----------------------------------------+ | ||||||
| | `bit_rate`           | (number)  | in bit/s                                | | | ``bit_rate``         | (number)  | in bit/s                                | | ||||||
| +----------------------+-----------+-----------------------------------------+ | +----------------------+-----------+-----------------------------------------+ | ||||||
| | `roll_off`           | (number)  | 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. | Simulation parameters are defined as follows. | ||||||
|  |  | ||||||
| Auto-design automatically creates EDFA amplifier network elements when they are | 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 | 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` | functionality can be manually and locally deactivated by introducing a ``Fused`` | ||||||
| network element after a `Fiber` or a `Roadm` that doesn't need amplification. | 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 | 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 | 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 | For amplifiers defined in the topology JSON input but whose ``gain = 0`` | ||||||
| (placeholder), auto-design will set its gain automatically: see `power_mode` in | (placeholder), auto-design will set its gain automatically: see ``power_mode`` in | ||||||
| the `Spans` library to find out how the gain is calculated. | 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 | 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 | in later releases) and the user can only modify the value of existing | ||||||
| @@ -293,25 +267,25 @@ parameters: | |||||||
| +------------------------+-----------+---------------------------------------------+ | +------------------------+-----------+---------------------------------------------+ | ||||||
| | field                  | type      | description                                 | | | field                  | type      | description                                 | | ||||||
| +========================+===========+=============================================+ | +========================+===========+=============================================+ | ||||||
| | `power_mode`           | (boolean) | If false, gain mode. Auto-design sets       | | | ``power_mode``         | (boolean) | If false, gain mode. Auto-design sets       | | ||||||
| |                        |           | amplifier gain = preceding span loss,      | | |                        |           | amplifier gain = preceding span loss,       | | ||||||
| |                        |           | unless the amplifier exists and its         | | |                        |           | 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        | | |                        |           | If true, power mode (recommended for        | | ||||||
| |                        |           | auto-design and power sweep.)               | | |                        |           | auto-design and power sweep.)               | | ||||||
| |                        |           | Auto-design sets amplifier power            | | |                        |           | Auto-design sets amplifier power            | | ||||||
| |                        |           | according to delta_power_range. If the      | | |                        |           | according to delta_power_range. If the      | | ||||||
| |                        |           | amplifier exists with gain > 0 in 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.     | | |                        |           | translated into a power target/channel.     | | ||||||
| |                        |           | Moreover, when performing a power sweep     | | |                        |           | 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      | | |                        |           | configuration library) the power sweep      | | ||||||
| |                        |           | is performed w/r/t this power target,       | | |                        |           | is performed w/r/t this power target,       | | ||||||
| |                        |           | regardless of preceding amplifiers         | | |                        |           | regardless of preceding amplifiers          | | ||||||
| |                        |           | power saturation/limitations.               | | |                        |           | 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]        | | |                        |           | only. Specifies the [min, max, step]        | | ||||||
| |                        |           | power excursion/span. It is a relative      | | |                        |           | power excursion/span. It is a relative      | | ||||||
| |                        |           | power excursion w/r/t the                   | | |                        |           | power excursion w/r/t the                   | | ||||||
| @@ -345,22 +319,24 @@ parameters: | |||||||
| |                        |           | a 23 dB span to                             | | |                        |           | a 23 dB span to                             | | ||||||
| |                        |           | power = power_dbm + power_range_db + 1      | | |                        |           | 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              | | |                        |           | Interest to support high level              | | ||||||
| |                        |           | topologies that do not specify in line      | | |                        |           | topologies that do not specify in line      | | ||||||
| |                        |           | amplification sites. For example the        | | |                        |           | amplification sites. For example the        | | ||||||
| |                        |           | CORONET_Global_Topology.xls defines         | | |                        |           | CORONET_Global_Topology.xls defines         | | ||||||
| |                        |           | links > 1000km between 2 sites: it          | | |                        |           | links > 1000km between 2 sites: it          | | ||||||
| |                        |           | couldn't be simulated if these links        | | |                        |           | couldn't be simulated if these links        | | ||||||
| |                        |           | were not splitted in shorter span           | | |                        |           | were not split in shorter span lengths.     | | ||||||
| |                        |           | 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.                             | | |                        |           | 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         | | |                        |           | attenuator before fiber. Attenuator         | | ||||||
| |                        |           | value                                       | | |                        |           | value                                       | | ||||||
| |                        |           | Fiber.att_in = max(0, padding - span_loss). | | |                        |           | Fiber.att_in = max(0, padding - span_loss). | | ||||||
| @@ -375,25 +351,23 @@ parameters: | |||||||
| |                        |           | Therefore it is not possible to set         | | |                        |           | Therefore it is not possible to set         | | ||||||
| |                        |           | span_loss < padding.                        | | |                        |           | 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       | | |                        |           | is added to the con_out (fiber output       | | ||||||
| |                        |           | connector). So the design and the path      | | |                        |           | connector). So the design and the path      | | ||||||
| |                        |           | feasibility are performed with              | | |                        |           | feasibility are performed with              | | ||||||
| |                        |           | span_loss + EOL. EOL cannot be set          | | |                        |           | span_loss + EOL. EOL cannot be set          | | ||||||
| |                        |           | manually for a given fiber span             | | |                        |           | manually for a given fiber span             | | ||||||
| |                        |           | (workaround is to specify higher con_out    | | |                        |           | (workaround is to specify higher ``con_out`` | | ||||||
| |                        |           | loss for this fiber).                       | | |                        |           | loss for this fiber).                       | | ||||||
| +------------------------+-----------+---------------------------------------------+ | +------------------------+-----------+---------------------------------------------+ | ||||||
| | `con_in`, `con_out`    | (number)  | Default values if Fiber/params/con_in/out   | | | ``con_in``,            | (number)  | Default values if Fiber/params/con_in/out   | | ||||||
| |                        |           | is None in the topology input               | | | ``con_out``            |           | is None in the topology input               | | ||||||
| |                        |           | description. This default value is          | | |                        |           | description. This default value is          | | ||||||
| |                        |           | ignored if a Fiber/params/con_in/out        | | |                        |           | ignored if a Fiber/params/con_in/out        | | ||||||
| |                        |           | value is input in the topology for a        | | |                        |           | value is input in the topology for a        | | ||||||
| |                        |           | given Fiber.                                | | |                        |           | given Fiber.                                | | ||||||
| +------------------------+-----------+---------------------------------------------+ | +------------------------+-----------+---------------------------------------------+ | ||||||
|  |  | ||||||
| **[1]** |  | ||||||
|  |  | ||||||
| .. code-block:: json | .. code-block:: json | ||||||
|  |  | ||||||
|     { |     { | ||||||
| @@ -418,30 +392,28 @@ existing parameters: | |||||||
| +--------------------------+-----------+---------------------------------------------+ | +--------------------------+-----------+---------------------------------------------+ | ||||||
| | field                    |   type    | description                                 | | | field                    |   type    | description                                 | | ||||||
| +==========================+===========+=============================================+ | +==========================+===========+=============================================+ | ||||||
| | `gain_mode_default_loss` | (number)  | Default value if Roadm/params/loss is       | | | ``target_pch_out_db``    | (number)  | Auto-design sets the ROADM egress channel   | | ||||||
| |                          |           | None in the topology input description.     | | |                          |           | 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          | | |                          |           | This default value is ignored if a          | | ||||||
| |                          |           | params/loss value is input in the           | | |                          |           | params/target_pch_out_db value is input in  | | ||||||
| |                          |           | topology for a given ROADM.                 | | |                          |           | the topology for a given ROADM.             | | ||||||
| +--------------------------+-----------+---------------------------------------------+ | +--------------------------+-----------+---------------------------------------------+ | ||||||
| | `power_mode_pref`        | (number)  | Power mode only. Auto-design sets the       | | | ``add_drop_osnr``        | (number)  | OSNR contribution from the add/drop ports   | | ||||||
| |                          |           | power of ROADM ingress amplifiers to        | | +--------------------------+-----------+---------------------------------------------+ | ||||||
| |                          |           | power_dbm + power_range_db,                 | | | ``restrictions``         | (strings) | Authorized type_variety of amplifier for    | | ||||||
| |                          |           | regardless of existing gain settings        | | |                          |           | booster or preamp.                          | | ||||||
| |                          |           | from the topology JSON input.               | | |                          |           | Listed type_variety MUST be defined in the  | | ||||||
| |                          |           | Auto-design sets the Roadm loss so that     | | |                          |           | Edfa catalog.                               | | ||||||
| |                          |           | 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.                    | |  | ||||||
| +--------------------------+-----------+---------------------------------------------+ | +--------------------------+-----------+---------------------------------------------+ | ||||||
|  |  | ||||||
| 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 | only modify the value of existing parameters. It defines a spectrum of N | ||||||
| identical carriers. While the code libraries allow for different carriers and | identical carriers. While the code libraries allow for different carriers and | ||||||
| power levels, the current user parametrization only allows one carrier type and | power levels, the current user parametrization only allows one carrier type and | ||||||
| @@ -450,21 +422,18 @@ one power/channel definition. | |||||||
| +----------------------+-----------+-------------------------------------------+ | +----------------------+-----------+-------------------------------------------+ | ||||||
| | field                |   type    | description                               | | | 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.                                 | | | ``power_dbm``        | (number)  | Reference channel power. In gain mode     | | ||||||
| +----------------------+-----------+-------------------------------------------+ |  | ||||||
| | `tx_osnr`            | (number)  | In dB. OSNR out from transponder.         | |  | ||||||
| +----------------------+-----------+-------------------------------------------+ |  | ||||||
| | `power_dbm`          | (number)  | Reference channel power. In gain mode     | |  | ||||||
| |                      |           | (see spans/power_mode = false), all gain  | | |                      |           | (see spans/power_mode = false), all gain  | | ||||||
| |                      |           | settings are offset w/r/t this reference  | | |                      |           | settings are offset w/r/t this reference  | | ||||||
| |                      |           | power. In power mode, it is the           | | |                      |           | power. In power mode, it is the           | | ||||||
| @@ -477,17 +446,19 @@ one power/channel definition. | |||||||
| |                      |           | power sweep is defined (see after) the    | | |                      |           | power sweep is defined (see after) the    | | ||||||
| |                      |           | design is not repeated.                   | | |                      |           | 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   | | |                      |           | It is not the min and max channel power   | | ||||||
| |                      |           | values! The reference power becomes:      | | |                      |           | values! The reference power becomes:      | | ||||||
| |                      |           | power_range_db + power_dbm.               | | |                      |           | 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>`_ | 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.  | ||||||
| script propagates a spectrum of channels at 32 Gbaud, 50 GHz spacing and 0 | Launch power can be overridden by using the ``--power`` argument. | ||||||
| dBm/channel. These are not yet parametrized but can be modified directly in the | 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. | ||||||
| script (via the SpectralInformation structure) to accommodate any baud rate, | The number of channel is computed based on ``spacing`` and ``f_min``, ``f_max`` values. | ||||||
| spacing, power or channel count demand. |  | ||||||
|  |  | ||||||
| Use `examples/path_requests_run.py <examples/path_requests_run.py>`_ to run multiple optimizations as follows: | 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 |      $ python path_requests_run.py -h | ||||||
|      Usage: path_requests_run.py [-h] [-v] [-o OUTPUT] [network_filename] [service_filename] [eqpt_filename] |      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: | 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 | This program requires a list of connections to be estimated and the equipment | ||||||
| library. The program computes performances for the list of services (accepts | library. The program computes performances for the list of services (accepts | ||||||
| json or excel format) using the same spectrum propagation modules as | JSON or Excel format) using the same spectrum propagation modules as | ||||||
| transmission_main_example.py. Explanation on the Excel template is provided in | ``transmission_main_example.py``. Explanation on the Excel template is provided in | ||||||
| the `Excel_userguide.rst <Excel_userguide.rst#service-sheet>`_. Template for | 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>`_. | <service-template.json>`_. | ||||||
|  |  | ||||||
| Contributing | Contributing | ||||||
|   | |||||||
							
								
								
									
										160
									
								
								examples/Juniper-BoosterHG.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								examples/Juniper-BoosterHG.json
									
									
									
									
									
										Normal 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 | ||||||
|  |     ] | ||||||
|  | } | ||||||
| @@ -1,5 +1,6 @@ | |||||||
| { | { | ||||||
|     "nf_ripple": "NFR0_96.txt",  |     "nf_ripple": "NFR_96.txt",  | ||||||
|     "gain_ripple": "DFG0_96.txt", |     "gain_ripple": "DFG_96.txt", | ||||||
|     "dgt": "DGT_96.txt"     |     "dgt": "DGT_96.txt", | ||||||
|  |     "nf_fit_coeff": "pNFfit3.txt" | ||||||
| } | } | ||||||
| @@ -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 |  | ||||||
| @@ -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	 |  | ||||||
| @@ -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() |  | ||||||
							
								
								
									
										300
									
								
								examples/edfa_model/amplifier_models_description.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										300
									
								
								examples/edfa_model/amplifier_models_description.rst
									
									
									
									
									
										Normal 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", | ||||||
|  |         } | ||||||
|  |  | ||||||
| @@ -4,7 +4,6 @@ | |||||||
| Created on Tue Jan 30 12:32:00 2018 | Created on Tue Jan 30 12:32:00 2018 | ||||||
|  |  | ||||||
| @author: jeanluc-auge | @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 | 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 | 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 | """amplifier file names | ||||||
| convert a set of amplifier files + input json definiton file into a valid edfa_json_file: | 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 | nf_ripple: NF ripple excursion txt file | ||||||
| dfg: gain txt file | gain_ripple: gain ripple txt file | ||||||
| dgt: dynamic gain txt file | dgt: dynamic gain txt file | ||||||
| input json file in argument (defult = 'OA.json') | input json file in argument (defult = 'OA.json') | ||||||
|  |  | ||||||
| the json input file should have the following fields: | the json input file should have the following fields: | ||||||
| { | { | ||||||
|     "gain_flatmax": 25, |     "nf_fit_coeff": "nf_filename.txt", | ||||||
|     "gain_min": 15, |     "nf_ripple": "nf_ripple_filename.txt",  | ||||||
|     "p_max": 21, |     "gain_ripple": "DFG_filename.txt", | ||||||
|     "nf_fit_coeff": "pNFfit3.txt", |     "dgt": "DGT_filename.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 |  | ||||||
|         } |  | ||||||
| } | } | ||||||
| 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 | input_json_file_name = "OA.json" #default path | ||||||
| output_json_file_name = "default_edfa_config.json" | output_json_file_name = "default_edfa_config.json" | ||||||
| param_field  ="params" | gain_ripple_field = "gain_ripple" | ||||||
| gain_min_field = "gain_min" |  | ||||||
| gain_max_field = "gain_flatmax" |  | ||||||
| gain_ripple_field = "dfg" |  | ||||||
| nf_ripple_field = "nf_ripple" | nf_ripple_field = "nf_ripple" | ||||||
| nf_fit_coeff = "nf_fit_coeff" | 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): | def read_file(field, file_name): | ||||||
|     """read and format the 96 channels txt files describing the amplifier NF and ripple |     """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 |         #consider ripple excursion only to avoid redundant information | ||||||
|         #because the max flat_gain is already given by the 'gain_flat' field in json |         #because the max flat_gain is already given by the 'gain_flat' field in json | ||||||
|         #remove the mean component |         #remove the mean component | ||||||
|  |         print(file_name, ', mean value =', data.mean(), ' is substracted') | ||||||
|         data = data - data.mean() |         data = data - data.mean() | ||||||
|     data = data.tolist() |     data = data.tolist() | ||||||
|     return data |     return data | ||||||
|   | |||||||
| @@ -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 |  | ||||||
|         ] |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,12 +1,22 @@ | |||||||
| {     "Edfa":[{ | {     "Edfa":[{ | ||||||
|             "type_variety": "high_detail_model_example", |             "type_variety": "high_detail_model_example", | ||||||
|  |             "type_def": "advanced_model", | ||||||
|             "gain_flatmax": 25, |             "gain_flatmax": 25, | ||||||
|             "gain_min": 15, |             "gain_min": 15, | ||||||
|             "p_max": 21, |             "p_max": 21, | ||||||
|             "advanced_config_from_json": "std_medium_gain_advanced_config.json", |             "advanced_config_from_json": "std_medium_gain_advanced_config.json", | ||||||
|             "out_voa_auto": false, |             "out_voa_auto": false, | ||||||
|             "allowed_for_design": 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_variety": "operator_model_example", | ||||||
|             "type_def": "variable_gain", |             "type_def": "variable_gain", | ||||||
| @@ -37,6 +47,17 @@ | |||||||
|             "allowed_for_design": false |             "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_variety": "std_medium_gain", | ||||||
|             "type_def": "variable_gain", |             "type_def": "variable_gain", | ||||||
|             "gain_flatmax": 26, |             "gain_flatmax": 26, | ||||||
| @@ -59,6 +80,17 @@ | |||||||
|             "allowed_for_design": true |             "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_variety": "std_fixed_gain", | ||||||
|             "type_def": "fixed_gain", |             "type_def": "fixed_gain", | ||||||
|             "gain_flatmax": 21, |             "gain_flatmax": 21, | ||||||
| @@ -66,7 +98,50 @@ | |||||||
|             "p_max": 21, |             "p_max": 21, | ||||||
|             "nf0": 5.5, |             "nf0": 5.5, | ||||||
|             "allowed_for_design": false |             "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":[{ |       "Fiber":[{ | ||||||
|             "type_variety": "SSMF", |             "type_variety": "SSMF", | ||||||
| @@ -84,9 +159,11 @@ | |||||||
|             "gamma": 0.000843 |             "gamma": 0.000843 | ||||||
|             } |             } | ||||||
|       ], |       ], | ||||||
|       "Spans":[{ |       "Span":[{ | ||||||
|             "power_mode":true, |             "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, |             "max_length": 150, | ||||||
|             "length_units": "km", |             "length_units": "km", | ||||||
|             "max_loss": 28, |             "max_loss": 28, | ||||||
| @@ -96,10 +173,13 @@ | |||||||
|             "con_out": 0 |             "con_out": 0 | ||||||
|             } |             } | ||||||
|       ], |       ], | ||||||
|       "Roadms":[{ |       "Roadm":[{ | ||||||
|             "gain_mode_default_loss": 20, |             "target_pch_out_db": -20, | ||||||
|             "power_mode_pout_target": -20, |             "add_drop_osnr": 38, | ||||||
|             "add_drop_osnr": 38 |             "restrictions": { | ||||||
|  |                             "preamp_variety_list":["low_gain_preamp", "high_gain_preamp"], | ||||||
|  |                             "booster_variety_list":["std_booster"] | ||||||
|  |                             }             | ||||||
|             }], |             }], | ||||||
|       "SI":[{ |       "SI":[{ | ||||||
|             "f_min": 191.3e12, |             "f_min": 191.3e12, | ||||||
| @@ -107,10 +187,10 @@ | |||||||
|             "f_max":195.1e12, |             "f_max":195.1e12, | ||||||
|             "spacing": 50e9, |             "spacing": 50e9, | ||||||
|             "power_dbm": 0, |             "power_dbm": 0, | ||||||
|             "power_range_db": [0,0,0.5], |             "power_range_db": [0,0,1], | ||||||
|             "roll_off": 0.15, |             "roll_off": 0.15, | ||||||
|             "tx_osnr": 40, |             "tx_osnr": 40, | ||||||
|             "sys_margins": 0 |             "sys_margins": 2 | ||||||
|             }], |             }], | ||||||
|       "Transceiver":[ |       "Transceiver":[ | ||||||
|             { |             { | ||||||
|   | |||||||
										
											Binary file not shown.
										
									
								
							| @@ -623,31 +623,473 @@ | |||||||
|         "con_in": null, |         "con_in": null, | ||||||
|         "con_out": 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": [ |   "connections": [ | ||||||
|     { |     { | ||||||
|       "from_node": "roadm Lannion_CAS", |       "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" |       "to_node": "fiber (Lannion_CAS → Corlay)-F061" | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "from_node": "fiber (Corlay → Lannion_CAS)-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" |       "to_node": "roadm Lannion_CAS" | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "from_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" |       "to_node": "fiber (Lannion_CAS → Stbrieuc)-F056" | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "from_node": "fiber (Stbrieuc → Lannion_CAS)-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" |       "to_node": "roadm Lannion_CAS" | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "from_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" |       "to_node": "fiber (Lannion_CAS → Morlaix)-F059" | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "from_node": "fiber (Morlaix → Lannion_CAS)-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" |       "to_node": "roadm Lannion_CAS" | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
| @@ -684,18 +1126,34 @@ | |||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "from_node": "roadm Lorient_KMA", |       "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" |       "to_node": "fiber (Lorient_KMA → Loudeac)-F054" | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "from_node": "fiber (Loudeac → Lorient_KMA)-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" |       "to_node": "roadm Lorient_KMA" | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "from_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" |       "to_node": "fiber (Lorient_KMA → Vannes_KBE)-F055" | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "from_node": "fiber (Vannes_KBE → Lorient_KMA)-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" |       "to_node": "roadm Lorient_KMA" | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
| @@ -708,10 +1166,18 @@ | |||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "from_node": "roadm Vannes_KBE", |       "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" |       "to_node": "fiber (Vannes_KBE → Lorient_KMA)-F055" | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "from_node": "fiber (Lorient_KMA → Vannes_KBE)-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" |       "to_node": "roadm Vannes_KBE" | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
| @@ -724,18 +1190,34 @@ | |||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "from_node": "fiber (Lannion_CAS → Stbrieuc)-F056", |       "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" |       "to_node": "fiber (Stbrieuc → Rennes_STA)-F057" | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "from_node": "fiber (Rennes_STA → Stbrieuc)-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" |       "to_node": "fiber (Stbrieuc → Lannion_CAS)-F056" | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "from_node": "roadm Rennes_STA", |       "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" |       "to_node": "fiber (Rennes_STA → Stbrieuc)-F057" | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "from_node": "fiber (Stbrieuc → Rennes_STA)-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" |       "to_node": "roadm Rennes_STA" | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
| @@ -764,10 +1246,18 @@ | |||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "from_node": "roadm Brest_KLA", |       "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" |       "to_node": "fiber (Brest_KLA → Morlaix)-F060" | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "from_node": "fiber (Morlaix → Brest_KLA)-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" |       "to_node": "roadm Brest_KLA" | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|   | |||||||
										
											Binary file not shown.
										
									
								
							| @@ -23,7 +23,7 @@ from networkx import (draw_networkx_nodes, draw_networkx_edges, | |||||||
| from numpy import mean | from numpy import mean | ||||||
| from gnpy.core.service_sheet import convert_service_sheet, Request_element, Element | from gnpy.core.service_sheet import convert_service_sheet, Request_element, Element | ||||||
| from gnpy.core.utils import load_json | 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.equipment import load_equipment, trx_mode_params, automatic_nch, automatic_spacing | ||||||
| from gnpy.core.elements import Transceiver, Roadm, Edfa, Fused, Fiber | from gnpy.core.elements import Transceiver, Roadm, Edfa, Fused, Fiber | ||||||
| from gnpy.core.utils import db2lin, lin2db | from gnpy.core.utils import db2lin, lin2db | ||||||
|   | |||||||
| @@ -4,6 +4,8 @@ | |||||||
|       0.0359549, |       0.0359549, | ||||||
|       5.82851 |       5.82851 | ||||||
|       ], |       ], | ||||||
|  |       "f_min": 191.35e12, | ||||||
|  |       "f_max": 196.1e12, | ||||||
|       "nf_ripple": [ |       "nf_ripple": [ | ||||||
|       -0.3110761646066259, |       -0.3110761646066259, | ||||||
|       -0.3110761646066259, |       -0.3110761646066259, | ||||||
|   | |||||||
| @@ -106,8 +106,8 @@ def main(network, equipment, source, destination, req = None): | |||||||
|                     }] |                     }] | ||||||
|     result_dicts.update({'network': network_data}) |     result_dicts.update({'network': network_data}) | ||||||
|     design_data = [{ |     design_data = [{ | ||||||
|                     'power_mode'        : equipment['Spans']['default'].power_mode, |                     'power_mode'        : equipment['Span']['default'].power_mode, | ||||||
|                     'span_power_range'  : equipment['Spans']['default'].delta_power_range_db, |                     'span_power_range'  : equipment['Span']['default'].delta_power_range_db, | ||||||
|                     'design_pch'        : equipment['SI']['default'].power_dbm, |                     'design_pch'        : equipment['SI']['default'].power_dbm, | ||||||
|                     'baud_rate'         : equipment['SI']['default'].baud_rate |                     'baud_rate'         : equipment['SI']['default'].baud_rate | ||||||
|                     }] |                     }] | ||||||
| @@ -115,9 +115,9 @@ def main(network, equipment, source, destination, req = None): | |||||||
|     simulation_data = [] |     simulation_data = [] | ||||||
|     result_dicts.update({'simulation results': 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}', |     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_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) |     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]') |         print('invalid power range definition in eqpt_config, should be power_range_db: [lower, upper, step]') | ||||||
|         power_range = [0] |         power_range = [0] | ||||||
|  |  | ||||||
|  |     if not power_mode: | ||||||
|  |         #power cannot be changed in gain mode | ||||||
|  |         power_range = [0] | ||||||
|     for dp_db in power_range: |     for dp_db in power_range: | ||||||
|         req.power = db2lin(pref_ch_db + dp_db)*1e-3 |         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) |         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(destination) | ||||||
|  |  | ||||||
|         #print(f'\n !!!!!!!!!!!!!!!!!     TEST POINT         !!!!!!!!!!!!!!!!!!!!!') |         #print(f'\n !!!!!!!!!!!!!!!!!     TEST POINT         !!!!!!!!!!!!!!!!!!!!!') | ||||||
|         #print(f'carriers ase output of {path[1]} =\n {list(path[1].carriers("out", "nli"))}') |         #print(f'carriers ase output of {path[1]} =\n {list(path[1].carriers("out", "nli"))}') | ||||||
|         # => use "in" or "out" parameter |         # => use "in" or "out" parameter | ||||||
|         # => use "nli" or "ase" or "signal" or "total" parameter |         # => use "nli" or "ase" or "signal" or "total" parameter         | ||||||
|  |         if power_mode: | ||||||
|         simulation_data.append({ |             simulation_data.append({ | ||||||
|                     'Pch_dBm'               : pref_ch_db + dp_db, |                         'Pch_dBm'               : pref_ch_db + dp_db, | ||||||
|                     'OSNR_ASE_0.1nm'        : round(mean(destination.osnr_ase_01nm),2), |                         'OSNR_ASE_0.1nm'        : round(mean(destination.osnr_ase_01nm),2), | ||||||
|                     'OSNR_ASE_signal_bw'    : round(mean(destination.osnr_ase),2), |                         'OSNR_ASE_signal_bw'    : round(mean(destination.osnr_ase),2), | ||||||
|                     'SNR_nli_signal_bw'     : round(mean(destination.osnr_nli),2), |                         'SNR_nli_signal_bw'     : round(mean(destination.osnr_nli),2), | ||||||
|                     'SNR_total_signal_bw'   : round(mean(destination.snr),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') |     write_csv(result_dicts, 'simulation_result.csv') | ||||||
|     return path, infos |     return path, infos | ||||||
|  |  | ||||||
|   | |||||||
| @@ -111,11 +111,12 @@ class Eqpt(object): | |||||||
|     { |     { | ||||||
|             'from_city':        '', |             'from_city':        '', | ||||||
|             'to_city':          '', |             'to_city':          '', | ||||||
|             'east_amp_type':         '', |             'east_amp_type':    '', | ||||||
|             'east_att_in':           0, |             'east_att_in':      0, | ||||||
|             'east_amp_gain':         0, |             'east_amp_gain':    None, | ||||||
|             'east_tilt':             0, |             'east_amp_dp':      None, | ||||||
|             'east_att_out':          0 |             '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) |             slice_out = read_slice(my_sheet, start_line+iteration, slice_in, h0) | ||||||
|             iteration += 1 |             iteration += 1 | ||||||
|         if slice_out == (-1, -1): |         if slice_out == (-1, -1): | ||||||
|             if h0 == 'east': |             if h0 in ('east', 'Node A', 'Node Z', 'City') : | ||||||
|                 print(f'\x1b[1;31;40m'+f'CRITICAL: missing _east_ header above other headers (hierarchical) _ ABORT'+ '\x1b[0m') |                 print(f'\x1b[1;31;40m'+f'CRITICAL: missing _{h0}_ header: EXECUTION ENDS'+ '\x1b[0m') | ||||||
|                 exit() |                 exit() | ||||||
|             else: |             else: | ||||||
|                 print(f'missing header {h0}') |                 print(f'missing header {h0}') | ||||||
| @@ -344,6 +345,7 @@ def convert_file(input_filename, names_matching=False, filter_region=[]): | |||||||
|               'type': 'Edfa', |               'type': 'Edfa', | ||||||
|               'type_variety': e.east_amp_type, |               'type_variety': e.east_amp_type, | ||||||
|               'operational': {'gain_target': e.east_amp_gain, |               'operational': {'gain_target': e.east_amp_gain, | ||||||
|  |                               'delta_p':     e.east_amp_dp, | ||||||
|                               'tilt_target': e.east_tilt, |                               'tilt_target': e.east_tilt, | ||||||
|                               'out_voa'    : e.east_att_out} |                               'out_voa'    : e.east_att_out} | ||||||
|             } |             } | ||||||
| @@ -356,6 +358,7 @@ def convert_file(input_filename, names_matching=False, filter_region=[]): | |||||||
|               'type': 'Edfa', |               'type': 'Edfa', | ||||||
|               'type_variety': e.west_amp_type, |               'type_variety': e.west_amp_type, | ||||||
|               'operational': {'gain_target': e.west_amp_gain, |               'operational': {'gain_target': e.west_amp_gain, | ||||||
|  |                               'delta_p':     e.west_amp_dp, | ||||||
|                               'tilt_target': e.west_tilt, |                               'tilt_target': e.west_tilt, | ||||||
|                               'out_voa'    : e.west_att_out} |                               'out_voa'    : e.west_att_out} | ||||||
|               } |               } | ||||||
| @@ -420,6 +423,7 @@ def parse_excel(input_filename): | |||||||
|             'amp type':         'east_amp_type', |             'amp type':         'east_amp_type', | ||||||
|             'att_in':           'east_att_in', |             'att_in':           'east_att_in', | ||||||
|             'amp gain':         'east_amp_gain', |             'amp gain':         'east_amp_gain', | ||||||
|  |             'delta p':          'east_amp_dp', | ||||||
|             'tilt':             'east_tilt', |             'tilt':             'east_tilt', | ||||||
|             'att_out':          'east_att_out' |             'att_out':          'east_att_out' | ||||||
|        }, |        }, | ||||||
| @@ -427,6 +431,7 @@ def parse_excel(input_filename): | |||||||
|             'amp type':         'west_amp_type', |             'amp type':         'west_amp_type', | ||||||
|             'att_in':           'west_att_in', |             'att_in':           'west_att_in', | ||||||
|             'amp gain':         'west_amp_gain', |             'amp gain':         'west_amp_gain', | ||||||
|  |             'delta p':          'west_amp_dp', | ||||||
|             'tilt':             'west_tilt', |             'tilt':             'west_tilt', | ||||||
|             'att_out':          'west_att_out' |             'att_out':          'west_att_out' | ||||||
|        } |        } | ||||||
| @@ -566,12 +571,12 @@ def midpoint(city_a, city_b): | |||||||
| #output_json_file_name = 'coronet_conus_example.json' | #output_json_file_name = 'coronet_conus_example.json' | ||||||
| #TODO get column size automatically from tupple size | #TODO get column size automatically from tupple size | ||||||
|  |  | ||||||
| NODES_COLUMN = 7 | NODES_COLUMN = 8 | ||||||
| NODES_LINE = 4 | NODES_LINE = 4 | ||||||
| LINKS_COLUMN = 16 | LINKS_COLUMN = 16 | ||||||
| LINKS_LINE = 3 | LINKS_LINE = 3 | ||||||
| EQPTS_LINE = 3 | EQPTS_LINE = 3 | ||||||
| EQPTS_COLUMN = 12 | EQPTS_COLUMN = 14 | ||||||
| parser = ArgumentParser() | parser = ArgumentParser() | ||||||
| parser.add_argument('workbook', nargs='?', type=Path , default='meshTopologyExampleV2.xls') | parser.add_argument('workbook', nargs='?', type=Path , default='meshTopologyExampleV2.xls') | ||||||
| parser.add_argument('-f', '--filter-region', action='append', default=[]) | parser.add_argument('-f', '--filter-region', action='append', default=[]) | ||||||
|   | |||||||
| @@ -25,7 +25,7 @@ from collections import namedtuple | |||||||
|  |  | ||||||
| from gnpy.core.node import Node | from gnpy.core.node import Node | ||||||
| from gnpy.core.units import UNITS | 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): | class Transceiver(Node): | ||||||
|     def __init__(self, *args, **kwargs): |     def __init__(self, *args, **kwargs): | ||||||
| @@ -41,7 +41,6 @@ class Transceiver(Node): | |||||||
|         with errstate(divide='ignore'): |         with errstate(divide='ignore'): | ||||||
|             self.baud_rate = [c.baud_rate for c in spectral_info.carriers] |             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] |             ratio_01nm = [lin2db(12.5e9/b_rate) for b_rate in self.baud_rate] | ||||||
|              |  | ||||||
|         #set raw values to record original calculation, before update_snr()             |         #set raw values to record original calculation, before update_snr()             | ||||||
|             self.raw_osnr_ase = [lin2db(divide(c.power.signal, c.power.ase)) |             self.raw_osnr_ase = [lin2db(divide(c.power.signal, c.power.ase)) | ||||||
|                             for c in spectral_info.carriers] |                             for c in spectral_info.carriers] | ||||||
| @@ -51,11 +50,14 @@ class Transceiver(Node): | |||||||
|                              for c in spectral_info.carriers] |                              for c in spectral_info.carriers] | ||||||
|             self.raw_snr = [lin2db(divide(c.power.signal, c.power.nli+c.power.ase))  |             self.raw_snr = [lin2db(divide(c.power.signal, c.power.nli+c.power.ase))  | ||||||
|                         for c in spectral_info.carriers] |                         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 = self.raw_osnr_ase | ||||||
|             self.osnr_ase_01nm = self.raw_osnr_ase_01nm |             self.osnr_ase_01nm = self.raw_osnr_ase_01nm | ||||||
|             self.osnr_nli = self.raw_osnr_nli |             self.osnr_nli = self.raw_osnr_nli | ||||||
|             self.snr = self.raw_snr |             self.snr = self.raw_snr | ||||||
|  |             self.snr_01nm = self.raw_snr_01nm | ||||||
|                          |                          | ||||||
|     def update_snr(self, *args): |     def update_snr(self, *args): | ||||||
|         """ |         """ | ||||||
| @@ -75,6 +77,8 @@ class Transceiver(Node): | |||||||
|                         self.raw_snr, self.baud_rate)) |                         self.raw_snr, self.baud_rate)) | ||||||
|         self.osnr_ase_01nm = list(map(lambda x:snr_sum(x,12.5e9,snr_added),  |         self.osnr_ase_01nm = list(map(lambda x:snr_sum(x,12.5e9,snr_added),  | ||||||
|                         self.raw_osnr_ase_01nm)) |                         self.raw_osnr_ase_01nm)) | ||||||
|  |         self.snr_01nm = list(map(lambda x:snr_sum(x,12.5e9,snr_added),  | ||||||
|  |                         self.raw_snr_01nm)) | ||||||
|  |  | ||||||
|     @property |     @property | ||||||
|     def to_json(self): |     def to_json(self): | ||||||
| @@ -100,37 +104,34 @@ class Transceiver(Node): | |||||||
|         snr = round(mean(self.snr),2) |         snr = round(mean(self.snr),2) | ||||||
|         osnr_ase = round(mean(self.osnr_ase),2) |         osnr_ase = round(mean(self.osnr_ase),2) | ||||||
|         osnr_ase_01nm = round(mean(self.osnr_ase_01nm), 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}', |         return '\n'.join([f'{type(self).__name__} {self.uid}', | ||||||
|  |  | ||||||
|                           f'  OSNR ASE (0.1nm, dB):      {osnr_ase_01nm:.2f}', |                           f'  OSNR ASE (0.1nm, dB):      {osnr_ase_01nm:.2f}', | ||||||
|                           f'  OSNR ASE (signal bw, dB):  {osnr_ase:.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): |     def __call__(self, spectral_info): | ||||||
|         self._calc_snr(spectral_info) |         self._calc_snr(spectral_info) | ||||||
|         return spectral_info |         return spectral_info | ||||||
|  |  | ||||||
| RoadmParams = namedtuple('RoadmParams', 'loss') | RoadmParams = namedtuple('RoadmParams', 'target_pch_out_db add_drop_osnr') | ||||||
|  |  | ||||||
| class Roadm(Node): | class Roadm(Node): | ||||||
|     def __init__(self, *args, params=None, **kwargs): |     def __init__(self, *args, params, **kwargs): | ||||||
|         if params is None: |  | ||||||
|             # default loss value if not mentioned in loaded network json |  | ||||||
|             params = {'loss':None} |  | ||||||
|         super().__init__(*args, params=RoadmParams(**params), **kwargs) |         super().__init__(*args, params=RoadmParams(**params), **kwargs) | ||||||
|         self.loss = self.params.loss |         self.loss = 0 #auto-design interest | ||||||
|         self.target_pch_out_db = None #set in Networks.py by def set_roadm_loss |         self.effective_loss = None | ||||||
|         self.effective_pch_out_db = None |         self.effective_pch_out_db = self.params.target_pch_out_db | ||||||
|         self.effective_loss = None #set in self.propagate |  | ||||||
|         self.passive = True |         self.passive = True | ||||||
|  |  | ||||||
|     @property |     @property | ||||||
|     def to_json(self): |     def to_json(self): | ||||||
|         return {'uid'       : self.uid, |         return {'uid'       : self.uid, | ||||||
|                 'type'      : type(self).__name__, |                 'type'      : type(self).__name__, | ||||||
|                 'params'    : {'loss' : self.loss}, |                 'params'    : {'target_pch_out_db' : self.effective_pch_out_db}, | ||||||
|                 'metadata'      : { |                 'metadata'      : { | ||||||
|                     'location': self.metadata['location']._asdict() |                     'location': self.metadata['location']._asdict() | ||||||
|                                     } |                                     } | ||||||
| @@ -141,26 +142,25 @@ class Roadm(Node): | |||||||
|  |  | ||||||
|     def __str__(self): |     def __str__(self): | ||||||
|         return '\n'.join([f'{type(self).__name__} {self.uid}', |         return '\n'.join([f'{type(self).__name__} {self.uid}', | ||||||
|                           f'  loss (dB):     {self.effective_loss:.2f}', |                           f'  effective loss (dB):  {self.effective_loss:.2f}', | ||||||
|                           f'  pch out (dBm): {self.effective_pch_out_db!r}']) |                           f'  pch out (dBm):        {self.effective_pch_out_db!r}']) | ||||||
|  |  | ||||||
|     def propagate(self, pref, *carriers): |     def propagate(self, pref, *carriers): | ||||||
|         #pin_target and loss are read from eqpt_config.json['Roadm'] |         #pin_target and loss are read from eqpt_config.json['Roadm'] | ||||||
|         #all ingress channels in xpress are set to this power level |         #all ingress channels in xpress are set to this power level | ||||||
|         #but add channels are not, so we define an effective loss |         #but add channels are not, so we define an effective loss | ||||||
|         #in the case of add channels |         #in the case of add channels | ||||||
|         if self.target_pch_out_db: |         self.effective_pch_out_db = min(pref.pi, self.params.target_pch_out_db) | ||||||
|             self.effective_loss = pref.pi - self.target_pch_out_db |         self.effective_loss = pref.pi - self.effective_pch_out_db | ||||||
|         else: |         carriers_power = array([c.power.signal +c.power.nli+c.power.ase for c in carriers]) | ||||||
|              self.effective_loss = self.loss |         carriers_att = list(map(lambda x : lin2db(x*1e3)-self.params.target_pch_out_db, carriers_power)) | ||||||
|         self.effective_pch_out_db = pref.pi - self.effective_loss |         exceeding_att = -min(list(filter(lambda x: x < 0, carriers_att)), default = 0) | ||||||
|         attenuation = db2lin(self.effective_loss) |         carriers_att = list(map(lambda x: db2lin(x+exceeding_att), carriers_att)) | ||||||
|  |         for carrier_att, carrier in zip(carriers_att, carriers) : | ||||||
|         for carrier in carriers: |  | ||||||
|             pwr = carrier.power |             pwr = carrier.power | ||||||
|             pwr = pwr._replace(signal=pwr.signal/attenuation, |             pwr = pwr._replace( signal = pwr.signal/carrier_att, | ||||||
|                                nonlinear_interference=pwr.nli/attenuation, |                                 nonlinear_interference = pwr.nli/carrier_att, | ||||||
|                                amplified_spontaneous_emission=pwr.ase/attenuation) |                                 amplified_spontaneous_emission = pwr.ase/carrier_att) | ||||||
|             yield carrier._replace(power=pwr) |             yield carrier._replace(power=pwr) | ||||||
|  |  | ||||||
|     def update_pref(self, pref): |     def update_pref(self, pref): | ||||||
| @@ -430,16 +430,16 @@ class EdfaParams: | |||||||
|         if params == {}: |         if params == {}: | ||||||
|             self.type_variety = '' |             self.type_variety = '' | ||||||
|             self.type_def = '' |             self.type_def = '' | ||||||
|             self.gain_flatmax = 0 |             # self.gain_flatmax = 0 | ||||||
|             self.gain_min = 0 |             # self.gain_min = 0 | ||||||
|             self.p_max = 0 |             # self.p_max = 0 | ||||||
|             self.nf_model = None |             # self.nf_model = None | ||||||
|             self.nf_fit_coeff = None |             # self.nf_fit_coeff = None | ||||||
|             self.nf_ripple = None |             # self.nf_ripple = None | ||||||
|             self.dgt = None |             # self.dgt = None | ||||||
|             self.gain_ripple = None |             # self.gain_ripple = None | ||||||
|             self.out_voa_auto = False |             # self.out_voa_auto = False | ||||||
|             self.allowed_for_design = None |             # self.allowed_for_design = None | ||||||
|  |  | ||||||
|     def update_params(self, kwargs): |     def update_params(self, kwargs): | ||||||
|         for k,v in kwargs.items() : |         for k,v in kwargs.items() : | ||||||
| @@ -447,10 +447,22 @@ class EdfaParams: | |||||||
|                 if isinstance(v, dict) else v) |                 if isinstance(v, dict) else v) | ||||||
|  |  | ||||||
| class EdfaOperational: | class EdfaOperational: | ||||||
|     def __init__(self, gain_target, tilt_target, out_voa=None): |     default_values = \ | ||||||
|         self.gain_target = gain_target |     { | ||||||
|         self.tilt_target = tilt_target |         'gain_target':      None, | ||||||
|         self.out_voa = out_voa |         '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): |     def __repr__(self): | ||||||
|         return (f'{type(self).__name__}(' |         return (f'{type(self).__name__}(' | ||||||
|                 f'gain_target={self.gain_target!r}, ' |                 f'gain_target={self.gain_target!r}, ' | ||||||
| @@ -479,14 +491,16 @@ class Edfa(Node): | |||||||
|         self.pin_db = None |         self.pin_db = None | ||||||
|         self.nch = None |         self.nch = None | ||||||
|         self.pout_db = None |         self.pout_db = None | ||||||
|         self.dp_db = None #delta P with Pref (power swwep) in power mode |  | ||||||
|         self.target_pch_out_db = None |         self.target_pch_out_db = None | ||||||
|         self.effective_pch_out_db = None |         self.effective_pch_out_db = None | ||||||
|         self.passive = False |         self.passive = False | ||||||
|         self.effective_gain = self.operational.gain_target |  | ||||||
|         self.att_in = None |         self.att_in = None | ||||||
|         self.carriers_in = None |         self.carriers_in = None | ||||||
|         self.carriers_out = 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 |     @property | ||||||
|     def to_json(self): |     def to_json(self): | ||||||
| @@ -494,9 +508,10 @@ class Edfa(Node): | |||||||
|                 'type'          : type(self).__name__, |                 'type'          : type(self).__name__, | ||||||
|                 'type_variety'  : self.params.type_variety, |                 'type_variety'  : self.params.type_variety, | ||||||
|                 'operational'   : { |                 'operational'   : { | ||||||
|                     'gain_target' : self.operational.gain_target, |                     'gain_target' : self.effective_gain, | ||||||
|                     'tilt_target' : self.operational.tilt_target, |                     'delta_p'     : self.delta_p, | ||||||
|                     'out_voa'     : self.operational.out_voa |                     'tilt_target' : self.tilt_target, | ||||||
|  |                     'out_voa'     : self.out_voa | ||||||
|                 }, |                 }, | ||||||
|                 'metadata'      : { |                 'metadata'      : { | ||||||
|                     'location': self.metadata['location']._asdict() |                     'location': self.metadata['location']._asdict() | ||||||
| @@ -528,10 +543,10 @@ class Edfa(Node): | |||||||
|                           f'  pad att_in (dB):        {self.att_in:.2f}', |                           f'  pad att_in (dB):        {self.att_in:.2f}', | ||||||
|                           f'  Power In (dBm):         {self.pin_db:.2f}', |                           f'  Power In (dBm):         {self.pin_db:.2f}', | ||||||
|                           f'  Power Out (dBm):        {self.pout_db:.2f}', |                           f'  Power Out (dBm):        {self.pout_db:.2f}', | ||||||
|                           f'  Delta_P (dB):           {self.dp_db!r}', |                           f'  Delta_P (dB):           {self.delta_p!r}', | ||||||
|                           f'  target pch (dBm):       {self.target_pch_out_db!r}', |                           f'  target pch (dBm):       {self.target_pch_out_db!r}', | ||||||
|                           f'  effective pch (dBm):    {self.effective_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): |     def carriers(self, loc, attr): | ||||||
|         """retrieve carriers information |         """retrieve carriers information | ||||||
| @@ -558,61 +573,104 @@ class Edfa(Node): | |||||||
|                 self.channel_freq, self.nf, self.interpol_dgt and self.interpol_gain_ripple |                 self.channel_freq, self.nf, self.interpol_dgt and self.interpol_gain_ripple | ||||||
|         """ |         """ | ||||||
|         # TODO|jla: read amplifier actual frequencies from additional params in json |         # 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.channel_freq = frequencies | ||||||
|         self.interpol_dgt = interp(self.channel_freq, amplifier_freq, self.params.dgt) |         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_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.interpol_nf_ripple =interp(self.channel_freq, amplifier_freq, self.params.nf_ripple) | ||||||
|  |  | ||||||
|         self.nch = frequencies.size |         self.nch = frequencies.size | ||||||
|         self.pin_db = lin2db(sum(pin*1e3)) |         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""" |         This power target is used calculate the amplifier gain""" | ||||||
|         if self.dp_db is not None: |         if self.delta_p is not None: | ||||||
|             self.target_pch_out_db = round(self.dp_db + pref.p0, 2) |             self.target_pch_out_db = round(self.delta_p + pref.p0, 2) | ||||||
|             self.effective_gain = self.target_pch_out_db - pref.pi |             self.effective_gain = self.target_pch_out_db - pref.pi | ||||||
|         else: |  | ||||||
|             self.effective_gain = self.operational.gain_target |         """check power saturation and correct effective gain & power accordingly:"""             | ||||||
|          |         self.effective_gain = min(   | ||||||
|         """check power saturation and correct target_gain accordingly:""" |                                     self.effective_gain,  | ||||||
|         self.effective_gain = min(self.effective_gain, self.params.p_max - self.pin_db) |                                     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) |         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.nf = self._calc_nf() | ||||||
|         self.gprofile = self._gain_profile(pin) |         self.gprofile = self._gain_profile(pin) | ||||||
|  |  | ||||||
|         pout = (pin + self.noise_profile(baud_rates))*db2lin(self.gprofile) |         pout = (pin + self.noise_profile(baud_rates))*db2lin(self.gprofile) | ||||||
|         self.pout_db = lin2db(sum(pout*1e3)) |         self.pout_db = lin2db(sum(pout*1e3)) | ||||||
|         self.operational.gain_target = self.effective_gain |  | ||||||
|         # ase & nli are only calculated in signal bandwidth |         # ase & nli are only calculated in signal bandwidth | ||||||
|         #    pout_db is not the absolute full output power (negligible if sufficient channels) |         #    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): |     def _calc_nf(self, avg = False): | ||||||
|         """nf calculation based on 2 models: self.params.nf_model.enabled from json import: |         """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 |         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""" |         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: |         # gain_min > gain_target TBD: | ||||||
|         pad = max(self.params.gain_min - self.effective_gain, 0) |         if self.params.type_def == 'dual_stage': | ||||||
|         self.att_in = pad |             g1 = self.params.preamp_gain_flatmax | ||||||
|         gain_target = self.effective_gain + pad |             g2 = self.effective_gain - g1 | ||||||
|         dg = max(self.params.gain_flatmax - gain_target, 0) |             nf1_avg, pad = self._nf( self.params.preamp_type_def,  | ||||||
|         if self.params.type_def == 'variable_gain': |                                 self.params.preamp_nf_model, | ||||||
|             g1a = gain_target - self.params.nf_model.delta_p - dg |                                 self.params.preamp_nf_fit_coeff, | ||||||
|             nf_avg = lin2db(db2lin(self.params.nf_model.nf1) + db2lin(self.params.nf_model.nf2)/db2lin(g1a)) |                                 self.params.preamp_gain_min, | ||||||
|         elif self.params.type_def == 'fixed_gain': |                                 self.params.preamp_gain_flatmax,  | ||||||
|             nf_avg = self.params.nf_model.nf0 |                                 g1) | ||||||
|         elif self.params.type_def == 'openroadm': |             #no padding expected for the 1stage because g1 = gain_max | ||||||
|             pin_ch = self.pin_db - lin2db(self.nch) |             nf2_avg, pad = self._nf( self.params.booster_type_def, | ||||||
|             # model OSNR = f(Pin) |                                 self.params.booster_nf_model, | ||||||
|             nf_avg = pin_ch - polyval(self.params.nf_model.nf_coef, pin_ch) + 58 |                                 self.params.booster_nf_fit_coeff, | ||||||
|         else: |                                 self.params.booster_gain_min, | ||||||
|             nf_avg = polyval(self.params.nf_fit_coeff, -dg) |                                 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: |         if avg: | ||||||
|             return nf_avg + pad |             return nf_avg | ||||||
|         else: |         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): |     def noise_profile(self, df): | ||||||
|         """ noise_profile(bw) computes amplifier ase (W) in signal bw (Hz) |         """ 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 |         # Calculate the target slope - currently assumes equal spaced channels | ||||||
|         # TODO|jla: support arbitrary channel spacing |         # 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 |         # first estimate of DGT scaling | ||||||
|         if abs(dgt_slope) > 0.001: # check for zero value due to flat dgt |         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) |         gains = db2lin(self.gprofile) | ||||||
|         carrier_ases = self.noise_profile(brate) |         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): |         for gain, carrier_ase, carrier in zip(gains, carrier_ases, carriers): | ||||||
|             pwr = carrier.power |             pwr = carrier.power | ||||||
| @@ -790,7 +848,7 @@ class Edfa(Node): | |||||||
|  |  | ||||||
|     def update_pref(self, pref): |     def update_pref(self, pref): | ||||||
|         return pref._replace(p_span0=pref.p0, |         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): |     def __call__(self, spectral_info): | ||||||
|         self.carriers_in = spectral_info.carriers |         self.carriers_in = spectral_info.carriers | ||||||
|   | |||||||
| @@ -17,44 +17,126 @@ from json import load | |||||||
| from gnpy.core.utils import lin2db, db2lin, load_json | from gnpy.core.utils import lin2db, db2lin, load_json | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| from gnpy.core.elements import Edfa | from gnpy.core.elements import Edfa | ||||||
|  | import time | ||||||
|  |  | ||||||
| Model_vg = namedtuple('Model_vg', 'nf1 nf2 delta_p') | Model_vg = namedtuple('Model_vg', 'nf1 nf2 delta_p') | ||||||
| Model_fg = namedtuple('Model_fg', 'nf0') | Model_fg = namedtuple('Model_fg', 'nf0') | ||||||
| Model_openroadm = namedtuple('Model_openroadm', 'nf_coef') | Model_openroadm = namedtuple('Model_openroadm', 'nf_coef') | ||||||
| Fiber = namedtuple('Fiber', 'type_variety dispersion gamma') | Model_hybrid = namedtuple('Model_hybrid', 'nf_ram gain_ram edfa_variety') | ||||||
| Spans = namedtuple('Spans', 'power_mode delta_power_range_db max_length length_units \ | Model_dual_stage = namedtuple('Model_dual_stage', 'preamp_variety booster_variety') | ||||||
|                              max_loss padding EOL con_in con_out') |  | ||||||
| Transceiver = namedtuple('Transceiver', 'type_variety frequency mode') | class common: | ||||||
| Roadms = namedtuple('Roadms', 'gain_mode_default_loss power_mode_pout_target add_drop_osnr') |     def update_attr(self, default_values, kwargs, name): | ||||||
| SI = namedtuple('SI', 'f_min f_max baud_rate spacing roll_off \ |         clean_kwargs = {k:v for k,v in kwargs.items() if v !=''} | ||||||
|                        power_dbm power_range_db tx_osnr sys_margins') |         for k,v in default_values.items(): | ||||||
| AmpBase = namedtuple( |             setattr(self, k, clean_kwargs.get(k,v)) | ||||||
|     'AmpBase', |             if k not in clean_kwargs and name != 'Amp' : | ||||||
|     'type_variety type_def gain_flatmax gain_min p_max' |                 print(f'\x1b[1;31;40m'+ | ||||||
|     ' nf_model nf_fit_coeff nf_ripple dgt gain_ripple out_voa_auto allowed_for_design') |                     f'\n WARNING missing {k} attribute in eqpt_config.json[{name}]' | ||||||
| class Amp(AmpBase): |                     f'\n default value is {k} = {v}' | ||||||
|     def __new__(cls, |                     + '\x1b[0m') | ||||||
|             type_variety, type_def, gain_flatmax, gain_min, p_max, nf_model=None, |                 time.sleep(1) | ||||||
|             nf_fit_coeff=None, nf_ripple=None, dgt=None, gain_ripple=None, |  | ||||||
|              out_voa_auto=False, allowed_for_design=True): | class SI(common): | ||||||
|         return super().__new__(cls, |     default_values =\ | ||||||
|             type_variety, type_def, gain_flatmax, gain_min, p_max, |     { | ||||||
|             nf_model, nf_fit_coeff, nf_ripple, dgt, gain_ripple, |         "f_min":            191.35e12, | ||||||
|             out_voa_auto, allowed_for_design) |         "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 |     @classmethod | ||||||
|     def from_advanced_json(cls, filename, **kwargs): |     def from_json(cls, filename, **kwargs): | ||||||
|         with open(filename, encoding='utf-8') as f: |         config = Path(filename).parent / 'default_edfa_config.json' | ||||||
|             json_data = load(f) |  | ||||||
|         return cls(**{**kwargs, **json_data, 'type_def':None, 'nf_model':None}) |  | ||||||
|  |  | ||||||
|     @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_variety = kwargs['type_variety'] | ||||||
|         type_def = kwargs.get('type_def', 'variable_gain') #default compatibility with older json eqpt files |         type_def = kwargs.get('type_def', 'variable_gain') #default compatibility with older json eqpt files | ||||||
|         nf_def = None |         nf_def = None | ||||||
|  |         dual_stage_def = None | ||||||
|  |  | ||||||
|         if type_def == 'fixed_gain': |         if type_def == 'fixed_gain': | ||||||
|             try: |             try: | ||||||
| @@ -67,6 +149,8 @@ class Amp(AmpBase): | |||||||
|                 del kwargs['nf_max'] |                 del kwargs['nf_max'] | ||||||
|             except KeyError: pass #nf_min and nf_max are not needed for fixed gain amp |             except KeyError: pass #nf_min and nf_max are not needed for fixed gain amp | ||||||
|             nf_def = Model_fg(nf0) |             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': |         elif type_def == 'variable_gain': | ||||||
|             gain_min, gain_max = kwargs['gain_min'], kwargs['gain_flatmax'] |             gain_min, gain_max = kwargs['gain_min'], kwargs['gain_flatmax'] | ||||||
|             try: #nf_min and nf_max are expected for a variable gain amp |             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') |                 print(f'missing nf_coef input for amplifier: {type_variety} in eqpt_config.json') | ||||||
|                 exit() |                 exit() | ||||||
|             nf_def = Model_openroadm(nf_coef) |             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): | 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))) |         g1a_max = lin2db(db2lin(nf2) / (db2lin(nf_min) - db2lin(nf1))) | ||||||
|         delta_p = gain_max - g1a_max |         delta_p = gain_max - g1a_max | ||||||
|         g1a_min = gain_min - (gain_max-gain_min) - delta_p |         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 \ |             print(f'Computed \N{greek capital letter delta}P invalid \ | ||||||
|                 \n 1st coil vs 2nd coil calculated DeltaP {delta_p:.2f} for \ |                 \n 1st coil vs 2nd coil calculated DeltaP {delta_p:.2f} for \ | ||||||
|                 \n amplifier {type_variety} is not valid: revise inputs \ |                 \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_params = equipment['Edfa'][variety_type] | ||||||
|     amp = Edfa( |     amp = Edfa( | ||||||
|             uid = f'calc_NF', |             uid = f'calc_NF', | ||||||
|             params = amp_params._asdict(), |             params = amp_params.__dict__, | ||||||
|             operational = { |             operational = { | ||||||
|                 'gain_target': gain_target, |                 'gain_target': gain_target, | ||||||
|                 'tilt_target': 0 |                 'tilt_target': 0 | ||||||
| @@ -243,6 +340,30 @@ def update_trx_osnr(equipment): | |||||||
|             m['OSNR'] = m['OSNR'] + equipment['SI']['default'].sys_margins |             m['OSNR'] = m['OSNR'] + equipment['SI']['default'].sys_margins | ||||||
|     return equipment |     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): | def equipment_from_json(json_data, filename): | ||||||
|     """build global dictionnary eqpt_library that stores all eqpt characteristics: |     """build global dictionnary eqpt_library that stores all eqpt characteristics: | ||||||
|     edfa type type_variety, fiber type_variety |     edfa type type_variety, fiber type_variety | ||||||
| @@ -259,13 +380,9 @@ def equipment_from_json(json_data, filename): | |||||||
|         for entry in entries: |         for entry in entries: | ||||||
|             subkey = entry.get('type_variety', 'default')            |             subkey = entry.get('type_variety', 'default')            | ||||||
|             if key == 'Edfa': |             if key == 'Edfa': | ||||||
|                 if 'advanced_config_from_json' in entry: |                 equipment[key][subkey] = Amp.from_json(filename, **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) |  | ||||||
|             else:                 |             else:                 | ||||||
|                 equipment[key][subkey] = typ(**entry) |                 equipment[key][subkey] = typ(**entry) | ||||||
|     equipment = update_trx_osnr(equipment) |     equipment = update_trx_osnr(equipment) | ||||||
|  |     equipment = update_dual_stage(equipment) | ||||||
|     return equipment |     return equipment | ||||||
|   | |||||||
| @@ -30,7 +30,7 @@ class ConvenienceAccess: | |||||||
|  |  | ||||||
|  |  | ||||||
| class Power(namedtuple('Power', 'signal nonlinear_interference amplified_spontaneous_emission'), ConvenienceAccess): | class Power(namedtuple('Power', 'signal nonlinear_interference amplified_spontaneous_emission'), ConvenienceAccess): | ||||||
|  |     """carriers power in W""" | ||||||
|     _ABBREVS = {'nli': 'nonlinear_interference', |     _ABBREVS = {'nli': 'nonlinear_interference', | ||||||
|                 'ase': 'amplified_spontaneous_emission',} |                 'ase': 'amplified_spontaneous_emission',} | ||||||
|  |  | ||||||
| @@ -42,14 +42,18 @@ class Channel(namedtuple('Channel', 'channel_number frequency baud_rate roll_off | |||||||
|                 'ffs':      'frequency', |                 'ffs':      'frequency', | ||||||
|                 'freq':     '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', |     _ABBREVS = {'p0' :  'p_span0', | ||||||
|                 'pi' :  'p_spani'} |                 'pi' :  'p_spani'} | ||||||
|  |  | ||||||
| class SpectralInformation(namedtuple('SpectralInformation', 'pref carriers'), ConvenienceAccess): | 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) |         return super().__new__(cls, pref, carriers) | ||||||
|  |  | ||||||
| def merge_input_spectral_information(*si): | 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): | 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 in dB : convert power lin into power in dB | ||||||
|     pref = lin2db(power * 1e3) |     pref = lin2db(power * 1e3) | ||||||
|     si = SpectralInformation(pref=Pref(pref, pref)) |  | ||||||
|     nb_channel = automatic_nch(f_min, f_max, spacing) |     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), |             Channel(f, (f_min+spacing*f), | ||||||
|             baud_rate, roll_off, Power(power, 0, 0)) for f in range(1,nb_channel+1) |             baud_rate, roll_off, Power(power, 0, 0)) for f in range(1,nb_channel+1) | ||||||
|             ]) |             ]) | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ from numpy import arange | |||||||
| from scipy.interpolate import interp1d | from scipy.interpolate import interp1d | ||||||
| from logging import getLogger | from logging import getLogger | ||||||
| from os import path | from os import path | ||||||
| from operator import itemgetter | from operator import itemgetter, attrgetter | ||||||
| from gnpy.core import elements | from gnpy.core import elements | ||||||
| from gnpy.core.elements import Fiber, Edfa, Transceiver, Roadm, Fused | from gnpy.core.elements import Fiber, Edfa, Transceiver, Roadm, Fused | ||||||
| from gnpy.core.equipment import edfa_nf | 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']: |     for el_config in json_data['elements']: | ||||||
|         typ = el_config.pop('type') |         typ = el_config.pop('type') | ||||||
|         variety = el_config.pop('type_variety', 'default') |         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] |             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! |         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:' |             print( f'The {typ} of variety type {variety} was not recognized:' | ||||||
|                     '\nplease check it is properly defined in the eqpt_config json file') |                     '\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']: |     for cx in json_data['connections']: | ||||||
|         from_node, to_node = cx['from_node'], cx['to_node'] |         from_node, to_node = cx['from_node'], cx['to_node'] | ||||||
|         try: |         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: |         except KeyError: | ||||||
|             msg = f'In {__name__} network_from_json function:\n\tcan not find {from_node} or {to_node} defined in {cx}' |             msg = f'In {__name__} network_from_json function:\n\tcan not find {from_node} or {to_node} defined in {cx}' | ||||||
|             print(msg) |             print(msg) | ||||||
| @@ -87,16 +93,21 @@ def network_to_json(network): | |||||||
|     data.update(connections) |     data.update(connections) | ||||||
|     return data |     return data | ||||||
|  |  | ||||||
| def select_edfa(gain_target, power_target, equipment): | def select_edfa(raman_allowed, gain_target, power_target, equipment, uid): | ||||||
|     """amplifer selection algorithm |     """amplifer selection algorithm | ||||||
|     @Orange Jean-Luc Augé |     @Orange Jean-Luc Augé | ||||||
|     """ |     """ | ||||||
|     Edfa_list = namedtuple('Edfa_list', 'variety power gain nf') |     Edfa_list = namedtuple('Edfa_list', 'variety power gain_min nf') | ||||||
|     TARGET_EXTENDED_GAIN = 2.1 |     TARGET_EXTENDED_GAIN = equipment['Span']['default'].target_extended_gain | ||||||
|     #MAX_EXTENDED_GAIN = 5 |  | ||||||
|     edfa_dict = equipment['Edfa'] |     edfa_dict = equipment['Edfa'] | ||||||
|     pin = power_target - gain_target |     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( |     edfa_list = [Edfa_list( | ||||||
|                 variety=edfa_variety, |                 variety=edfa_variety, | ||||||
|                 power=min( |                 power=min( | ||||||
| @@ -106,76 +117,114 @@ def select_edfa(gain_target, power_target, equipment): | |||||||
|                     edfa.p_max |                     edfa.p_max | ||||||
|                     ) |                     ) | ||||||
|                     -power_target, |                     -power_target, | ||||||
|                 gain=edfa.gain_flatmax-gain_target, |                 gain_min= | ||||||
|  |                     gain_target+3 | ||||||
|  |                     -edfa.gain_min, | ||||||
|                 nf=edfa_nf(gain_target, edfa_variety, equipment)) \ |                 nf=edfa_nf(gain_target, edfa_variety, equipment)) \ | ||||||
|                 for edfa_variety, edfa in edfa_dict.items() |                 for edfa_variety, edfa in edfa_dict.items() | ||||||
|                 if edfa.allowed_for_design] |                 if (edfa.allowed_for_design and not edfa.raman)] | ||||||
|  |  | ||||||
|     acceptable_gain_list = \ |     #consider a Raman list because of different gain_min requirement:  | ||||||
|     list(filter(lambda x : x.gain>-TARGET_EXTENDED_GAIN, edfa_list)) |     #do not allow extended gain min for Raman | ||||||
|     if len(acceptable_gain_list) < 1: |     raman_list = [Edfa_list( | ||||||
|         #no amplifier satisfies the required gain, so pick the highest gain: |                 variety=edfa_variety, | ||||||
|         gain_max = max(edfa_list, key=itemgetter(2)).gain |                 power=min( | ||||||
|         #pick up all amplifiers that share this max gain: |                     pin | ||||||
|         acceptable_gain_list = \ |                     +edfa.gain_flatmax | ||||||
|         list(filter(lambda x : x.gain-gain_max>-0.1, edfa_list)) |                     +TARGET_EXTENDED_GAIN, | ||||||
|     acceptable_power_list = \ |                     edfa.p_max | ||||||
|     list(filter(lambda x : x.power>=0, acceptable_gain_list)) |                     ) | ||||||
|  |                     -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: |     if len(acceptable_power_list) < 1: | ||||||
|         #no amplifier satisfies the required power, so pick the highest power: |         #no amplifier satisfies the required power, so pick the highest power(s): | ||||||
|         power_max = \ |         power_max = max(acceptable_gain_min_list, key=attrgetter('power')).power | ||||||
|         max(acceptable_gain_list, key=itemgetter(1)).power |         #check and pick if other amplifiers may have a similar gain/power | ||||||
|         #pick up all amplifiers that share this max gain: |         #allow a 0.3dB power range  | ||||||
|         acceptable_power_list = \ |         #this allows to chose an amplifier with a better NF subsequentely | ||||||
|         list(filter(lambda x : x.power-power_max>-0.1, acceptable_gain_list)) |         acceptable_power_list = [x for x in acceptable_gain_min_list | ||||||
|  |                                  if x.power-power_max>-0.3] | ||||||
|  |  | ||||||
|  |      | ||||||
|     # gain and power requirements are resolved, |     # gain and power requirements are resolved, | ||||||
|     #       =>chose the amp with the best NF among the acceptable ones: |     #       =>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): |     return selected_edfa.variety, power_reduction | ||||||
|     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 |  | ||||||
|  |  | ||||||
|     for roadm in roadms: | def target_power(network, node, equipment): #get_fiber_dp | ||||||
|         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 |  | ||||||
|     SPAN_LOSS_REF = 20 |     SPAN_LOSS_REF = 20 | ||||||
|     POWER_SLOPE = 0.3 |     POWER_SLOPE = 0.3 | ||||||
|     power_mode = equipment['Spans']['default'].power_mode |     power_mode = equipment['Span']['default'].power_mode | ||||||
|     dp_range = list(equipment['Spans']['default'].delta_power_range_db) |     dp_range = list(equipment['Span']['default'].delta_power_range_db) | ||||||
|     node_loss = span_loss(network, node) |     node_loss = span_loss(network, node) | ||||||
|  |  | ||||||
|     dp_gain_mode = 0 |  | ||||||
|     try: |     try: | ||||||
|         dp_power_mode = round2float((node_loss - SPAN_LOSS_REF) * POWER_SLOPE, dp_range[2]) |         dp = round2float((node_loss - SPAN_LOSS_REF) * POWER_SLOPE, dp_range[2]) | ||||||
|         dp_power_mode = max(dp_range[0], dp_power_mode) |         dp = max(dp_range[0], dp) | ||||||
|         dp_power_mode = min(dp_range[1], dp_power_mode) |         dp = min(dp_range[1], dp) | ||||||
|     except KeyError: |     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]') |               f'delta_power_range_db: [lower_bound, upper_bound, step]') | ||||||
|         exit() |         exit() | ||||||
|  |  | ||||||
|     if dp_from_gain: |  | ||||||
|         dp_power_mode = dp_from_gain |  | ||||||
|         dp_gain_mode = dp_from_gain |  | ||||||
|     if isinstance(node, Roadm): |     if isinstance(node, Roadm): | ||||||
|         dp_power_mode = 0 |         dp = 0 | ||||||
|  |  | ||||||
|     dp = dp_power_mode if power_mode else dp_gain_mode |  | ||||||
|     #print(f'{repr(node)} delta power in:\n{dp}dB') |  | ||||||
|  |  | ||||||
|     return dp |     return dp | ||||||
|  |  | ||||||
|  |  | ||||||
| def prev_node_generator(network, node): | def prev_node_generator(network, node): | ||||||
|     """fused spans interest: |     """fused spans interest: | ||||||
|     iterate over all predecessors while they are Fused or Fiber type""" |     iterate over all predecessors while they are Fused or Fiber type""" | ||||||
| @@ -244,23 +293,22 @@ def find_last_node(network, node): | |||||||
|         pass |         pass | ||||||
|     return this_node |     return this_node | ||||||
|  |  | ||||||
| def set_amplifier_voa(amp, pref_total_db, power_mode): | def set_amplifier_voa(amp, power_target, power_mode): | ||||||
|     VOA_MARGIN = 0 |     VOA_MARGIN = 1 #do not maximize the VOA optimization | ||||||
|     if amp.operational.out_voa is None: |     if amp.out_voa is None: | ||||||
|         if power_mode: |         if power_mode: | ||||||
|             gain_target = amp.operational.gain_target |             gain_target = amp.effective_gain | ||||||
|             pout = pref_total_db + amp.dp_db |             voa = min(amp.params.p_max-power_target, | ||||||
|             voa = min(amp.params.p_max-pout, |                       amp.params.gain_flatmax-amp.effective_gain) | ||||||
|                       amp.params.gain_flatmax-amp.operational.gain_target) |             voa = max(round2float(max(voa, 0), 0.5) - VOA_MARGIN, 0) if amp.params.out_voa_auto else 0 | ||||||
|             voa = round2float(max(voa, 0), 0.5) - VOA_MARGIN if amp.params.out_voa_auto else 0 |             amp.delta_p = amp.delta_p + voa | ||||||
|             amp.dp_db = amp.dp_db + voa |             amp.effective_gain = amp.effective_gain + voa | ||||||
|             amp.operational.gain_target = amp.operational.gain_target + voa |  | ||||||
|         else: |         else: | ||||||
|             voa = 0 # no output voa optimization in gain mode |             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): | 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)) |     next_oms = (n for n in network.successors(roadm) if not isinstance(n, Transceiver)) | ||||||
|     for oms in next_oms: |     for oms in next_oms: | ||||||
|         #go through all the OMS departing from the Roadm |         #go through all the OMS departing from the Roadm | ||||||
| @@ -271,30 +319,56 @@ def set_egress_amplifier(network, roadm, equipment, pref_total_db): | |||||||
|         #     node = find_last_node(next_node) |         #     node = find_last_node(next_node) | ||||||
|         #     next_node = next(n for n in network.successors(node)) |         #     next_node = next(n for n in network.successors(node)) | ||||||
|         #     next_node = find_last_node(next_node) |         #     next_node = find_last_node(next_node) | ||||||
|         prev_dp = 0 |         prev_dp = getattr(node.params, 'target_pch_out_db', 0) | ||||||
|         dp = 0 |         dp = prev_dp | ||||||
|  |         prev_voa = 0 | ||||||
|  |         voa = 0 | ||||||
|         while True: |         while True: | ||||||
|         #go through all nodes in the OMS (loop until next Roadm instance) |         #go through all nodes in the OMS (loop until next Roadm instance) | ||||||
|             if isinstance(node, Edfa): |             if isinstance(node, Edfa): | ||||||
|                 node_loss = span_loss(network, prev_node) |                 node_loss = span_loss(network, prev_node) | ||||||
|                 dp_from_gain = prev_dp + node.operational.gain_target - node_loss \ |                 voa = node.out_voa if node.out_voa else 0 | ||||||
|                     if node.operational.gain_target > 0 else None |                 if node.delta_p is None: | ||||||
|                 dp = target_power(dp_from_gain, network, next_node, equipment) |                     dp = target_power(network, next_node, equipment) | ||||||
|                 gain_target = node_loss + dp - prev_dp |                 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: |                 raman_allowed = False | ||||||
|                     node.dp_db = dp |                 if isinstance(prev_node, Fiber): | ||||||
|                 node.operational.gain_target = gain_target |                     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 == '': |                 if node.params.type_variety == '' :                    | ||||||
|                     power_target = pref_total_db + dp |                     edfa_variety, power_reduction = select_edfa(raman_allowed,  | ||||||
|                     edfa_variety = select_edfa(gain_target, power_target, equipment) |                                    gain_target, power_target, equipment, node.uid) | ||||||
|                     extra_params = equipment['Edfa'][edfa_variety] |                     extra_params = equipment['Edfa'][edfa_variety] | ||||||
|                     node.params.update_params(extra_params._asdict()) |                     node.params.update_params(extra_params.__dict__) | ||||||
|                 set_amplifier_voa(node, pref_total_db, power_mode) |                     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): |             if isinstance(next_node, Roadm) or isinstance(next_node, Transceiver): | ||||||
|                 break |                 break | ||||||
|             prev_dp = dp |             prev_dp = dp | ||||||
|  |             prev_voa = voa | ||||||
|             prev_node = node |             prev_node = node | ||||||
|             node = next_node |             node = next_node | ||||||
|             # print(f'{node.uid}') |             # print(f'{node.uid}') | ||||||
| @@ -319,12 +393,16 @@ def add_egress_amplifier(network, node): | |||||||
|                         } |                         } | ||||||
|                     }, |                     }, | ||||||
|                     operational = { |                     operational = { | ||||||
|                         'gain_target': 0, |                         'gain_target': None, | ||||||
|                         'tilt_target': 0, |                         'tilt_target': 0, | ||||||
|                     }) |                     }) | ||||||
|         network.add_node(amp) |         network.add_node(amp) | ||||||
|         network.add_edge(node, amp) |         if isinstance(node,Fiber): | ||||||
|         network.add_edge(amp, next_node) |             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): | 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) |                           params = fiber_params) | ||||||
|         network.add_edge(prev_node, new_span) |         if isinstance(prev_node,Fiber): | ||||||
|         prev_node = new_span |             edgeweight = prev_node.params.length | ||||||
|     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 |  | ||||||
|         else: |         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): | def add_fiber_padding(network, fibers, padding): | ||||||
|     """last_fibers = (fiber for n in network.nodes() |     """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 |                 first_fiber.att_in = first_fiber.att_in + padding - this_span_loss | ||||||
|  |  | ||||||
| def build_network(network, equipment, pref_ch_db, pref_total_db): | 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]) |     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) |     min_length = max(int(default_span_data.padding/0.2*1e3),50_000) | ||||||
|     bounds = range(min_length, max_length) |     bounds = range(min_length, max_length) | ||||||
|     target_length = max(min_length, 90_000) |     target_length = max(min_length, 90_000) | ||||||
|     con_in = default_span_data.con_in |     default_con_in = default_span_data.con_in | ||||||
|     con_out = default_span_data.con_out + default_span_data.EOL |     default_con_out = default_span_data.con_out | ||||||
|     padding = default_span_data.padding |     padding = default_span_data.padding | ||||||
|  |  | ||||||
|     #set raodm loss for gain_mode before to build network |     #set roadm loss for gain_mode before to build network | ||||||
|     set_roadm_loss(network, equipment, pref_ch_db) |  | ||||||
|     fibers = [f for f in network.nodes() if isinstance(f, Fiber)] |     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) |     add_fiber_padding(network, fibers, padding) | ||||||
|     # don't group split fiber and add amp in the same loop |     # don't group split fiber and add amp in the same loop | ||||||
|     # =>for code clarity (at the expense of speed): |     # =>for code clarity (at the expense of speed): | ||||||
|   | |||||||
| @@ -18,12 +18,11 @@ See: draft-ietf-teas-yang-path-computation-01.txt | |||||||
| from sys import exit | from sys import exit | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| from logging import getLogger, basicConfig, CRITICAL, DEBUG, INFO | 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 networkx.utils import pairwise  | ||||||
| from numpy import mean | from numpy import mean | ||||||
| from gnpy.core.service_sheet import convert_service_sheet, Request_element, Element | from gnpy.core.service_sheet import convert_service_sheet, Request_element, Element | ||||||
| from gnpy.core.elements import Transceiver, Roadm, Edfa, Fused | 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.utils import db2lin, lin2db | ||||||
| from gnpy.core.info import create_input_spectral_information, SpectralInformation, Channel, Power | from gnpy.core.info import create_input_spectral_information, SpectralInformation, Channel, Power | ||||||
| from copy import copy, deepcopy | from copy import copy, deepcopy | ||||||
| @@ -292,7 +291,15 @@ def compute_constrained_path(network, req): | |||||||
|  |  | ||||||
|     if len(nodes_list) == 1  : |     if len(nodes_list) == 1  : | ||||||
|         try : |         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: |         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' |             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) |             logger.critical(msg) | ||||||
| @@ -306,15 +313,16 @@ def compute_constrained_path(network, req): | |||||||
|             if ispart(nodes_list, p) : |             if ispart(nodes_list, p) : | ||||||
|                 # print(f'selection{[el.uid for el in p if el in roadm]}') |                 # print(f'selection{[el.uid for el in p if el in roadm]}') | ||||||
|                 candidate.append(p) |                 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 : |         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] |             total_path = candidate[0] | ||||||
|         else: |         else: | ||||||
|             if req.loose_list[req.nodes_list.index(n)] == 'loose': |             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'\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') |                 print(f'constraint ignored') | ||||||
|                 total_path = dijkstra_path(network, source, destination) |                 total_path = dijkstra_path(network, source, destination, weight = 'weight') | ||||||
|             else: |             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' |                 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) |                 logger.critical(msg) | ||||||
| @@ -386,8 +394,6 @@ def compute_constrained_path(network, req): | |||||||
|     return total_path |     return total_path | ||||||
|  |  | ||||||
| def propagate(path, req, equipment, show=False): | 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( |     si = create_input_spectral_information( | ||||||
|         req.f_min, req.f_max, req.roll_off, req.baud_rate, |         req.f_min, req.f_max, req.roll_off, req.baud_rate, | ||||||
|         req.power, req.spacing) |         req.power, req.spacing) | ||||||
| @@ -395,12 +401,10 @@ def propagate(path, req, equipment, show=False): | |||||||
|         si = el(si) |         si = el(si) | ||||||
|         if show : |         if show : | ||||||
|             print(el) |             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 |     return path | ||||||
|  |  | ||||||
| def propagate2(path, req, equipment, show=False): | 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( |     si = create_input_spectral_information( | ||||||
|         req.f_min, req.f_max, req.roll_off, req.baud_rate, |         req.f_min, req.f_max, req.roll_off, req.baud_rate, | ||||||
|         req.power, req.spacing) |         req.power, req.spacing) | ||||||
| @@ -411,12 +415,10 @@ def propagate2(path, req, equipment, show=False): | |||||||
|         infos[el] = before_si, after_si |         infos[el] = before_si, after_si | ||||||
|         if show : |         if show : | ||||||
|             print(el) |             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 |     return infos | ||||||
|  |  | ||||||
| def propagate_and_optimize_mode(path, req, equipment): | def propagate_and_optimize_mode(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)) |  | ||||||
|     # if mode is unknown : loops on the modes starting from the highest baudrate fiting in the |     # 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 |     # 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  |     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 |         # at least 1 baudrate can be tested wrt spacing | ||||||
|         for b in baudrate_to_explore : |         for b in baudrate_to_explore : | ||||||
|             modes_to_explore = [m for m in equipment['Transceiver'][req.tsp].mode  |             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,  |             modes_to_explore = sorted(modes_to_explore,  | ||||||
|                 key = lambda x: x['bit_rate'], reverse=True) |                 key = lambda x: x['bit_rate'], reverse=True) | ||||||
|             # print(modes_to_explore) |             # print(modes_to_explore) | ||||||
| @@ -440,9 +442,11 @@ def propagate_and_optimize_mode(path, req, equipment): | |||||||
|             b, req.power, req.spacing) |             b, req.power, req.spacing) | ||||||
|             for el in path: |             for el in path: | ||||||
|                 si = el(si) |                 si = el(si) | ||||||
|  |                 if show: | ||||||
|  |                     print(el) | ||||||
|             for m in modes_to_explore : |             for m in modes_to_explore : | ||||||
|                 if path[-1].snr is not None: |                 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'] : |                     if round(min(path[-1].snr+lin2db(b/(12.5e9))),2) > m['OSNR'] : | ||||||
|                         found_a_feasible_mode = True |                         found_a_feasible_mode = True | ||||||
|                         return path, m |                         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),\ |             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),\ |             target=next(el for el in network.nodes() if el.uid == pathreq.destination),\ | ||||||
|             cutoff=80)) |             cutoff=80)) | ||||||
|         # sort them |         # 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 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 |         # reversed direction paths required to check disjunction on both direction | ||||||
|         all_simp_pths_reversed = [] |         all_simp_pths_reversed = [] | ||||||
|         for pth in all_simp_pths: |         for pth in all_simp_pths: | ||||||
| @@ -825,7 +831,7 @@ def find_reversed_path(p,network) : | |||||||
|     destination = p[0] |     destination = p[0] | ||||||
|     total_path = [source] |     total_path = [source] | ||||||
|     for node in reversed_roadm_path : |     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 |         source = node | ||||||
|     total_path.append(destination) |     total_path.append(destination) | ||||||
|     return total_path |     return total_path | ||||||
|   | |||||||
| @@ -73,7 +73,7 @@ class Request_element(Element): | |||||||
|                 Requestmode = None |                 Requestmode = None | ||||||
|                 self.mode = Request.mode |                 self.mode = Request.mode | ||||||
|         except KeyError: |         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) |             #print(msg) | ||||||
|             logger.critical(msg) |             logger.critical(msg) | ||||||
|             exit() |             exit() | ||||||
|   | |||||||
| @@ -88,6 +88,20 @@ def itufs(spacing, startf=191.35, stopf=196.10): | |||||||
|     """ |     """ | ||||||
|     return np.arange(startf, stopf + spacing / 2, spacing) |     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(): | def h(): | ||||||
|     """ |     """ | ||||||
|   | |||||||
							
								
								
									
										196070
									
								
								tests/data/CORONET_Global_Topology_auto_design_expected.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										196070
									
								
								tests/data/CORONET_Global_Topology_auto_design_expected.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,9 +1,11 @@ | |||||||
| {     "Edfa":[{ | {     "Edfa":[{ | ||||||
|             "type_variety": "CienaDB_medium_gain", |             "type_variety": "CienaDB_medium_gain", | ||||||
|  |             "type_def": "advanced_model", | ||||||
|             "gain_flatmax": 25, |             "gain_flatmax": 25, | ||||||
|             "gain_min": 15, |             "gain_min": 15, | ||||||
|             "p_max": 21, |             "p_max": 21, | ||||||
|             "advanced_config_from_json": "std_medium_gain_advanced_config.json", |             "advanced_config_from_json": "std_medium_gain_advanced_config.json", | ||||||
|  |             "out_voa_auto": false, | ||||||
|             "allowed_for_design": true |             "allowed_for_design": true | ||||||
|             }, |             }, | ||||||
|             { |             { | ||||||
| @@ -14,6 +16,7 @@ | |||||||
|             "p_max": 21, |             "p_max": 21, | ||||||
|             "nf_min": 6, |             "nf_min": 6, | ||||||
|             "nf_max": 10, |             "nf_max": 10, | ||||||
|  |             "out_voa_auto": false, | ||||||
|             "allowed_for_design": true |             "allowed_for_design": true | ||||||
|             }, |             }, | ||||||
|             { |             { | ||||||
| @@ -24,6 +27,7 @@ | |||||||
|             "p_max": 21, |             "p_max": 21, | ||||||
|             "nf_min": 7, |             "nf_min": 7, | ||||||
|             "nf_max": 11, |             "nf_max": 11, | ||||||
|  |             "out_voa_auto": false, | ||||||
|             "allowed_for_design": true |             "allowed_for_design": true | ||||||
|             }, |             }, | ||||||
|             { |             { | ||||||
| @@ -34,6 +38,7 @@ | |||||||
|             "p_max": 21, |             "p_max": 21, | ||||||
|             "nf_min": 5.8, |             "nf_min": 5.8, | ||||||
|             "nf_max": 10, |             "nf_max": 10, | ||||||
|  |             "out_voa_auto": false, | ||||||
|             "allowed_for_design": true |             "allowed_for_design": true | ||||||
|             }, |             }, | ||||||
|             { |             { | ||||||
| @@ -52,9 +57,11 @@ | |||||||
|             "gamma": 0.00127 |             "gamma": 0.00127 | ||||||
|             } |             } | ||||||
|       ], |       ], | ||||||
|       "Spans":[{ |       "Span":[{ | ||||||
|             "power_mode": true, |             "power_mode":true, | ||||||
|             "delta_power_range_db": [0,0,1], |             "delta_power_range_db": [0,0,0.5], | ||||||
|  |             "max_fiber_lineic_loss_for_raman": 0.25, | ||||||
|  |             "target_extended_gain": 2.5, | ||||||
|             "max_length": 150, |             "max_length": 150, | ||||||
|             "length_units": "km", |             "length_units": "km", | ||||||
|             "max_loss": 28, |             "max_loss": 28, | ||||||
| @@ -64,10 +71,13 @@ | |||||||
|             "con_out": 0 |             "con_out": 0 | ||||||
|             } |             } | ||||||
|       ], |       ], | ||||||
|       "Roadms":[{ |       "Roadm":[{ | ||||||
|             "gain_mode_default_loss": 20, |             "target_pch_out_db": -20, | ||||||
|             "power_mode_pout_target": -20, |             "add_drop_osnr": 38, | ||||||
|             "add_drop_osnr": 100 |             "restrictions": { | ||||||
|  |                             "preamp_variety_list":["low_gain_preamp", "high_gain_preamp"], | ||||||
|  |                             "booster_variety_list":["std_booster"] | ||||||
|  |                             }     | ||||||
|             }], |             }], | ||||||
|       "SI":[{ |       "SI":[{ | ||||||
|             "f_min": 191.3e12, |             "f_min": 191.3e12, | ||||||
| @@ -75,7 +85,7 @@ | |||||||
|             "baud_rate": 32e9, |             "baud_rate": 32e9, | ||||||
|             "spacing": 50e9, |             "spacing": 50e9, | ||||||
|             "power_dbm": 0, |             "power_dbm": 0, | ||||||
|             "power_range_db": [0,0.5,0.5], |             "power_range_db": [0,0,0.5], | ||||||
|             "roll_off": 0.15, |             "roll_off": 0.15, | ||||||
|             "tx_osnr": 100, |             "tx_osnr": 100, | ||||||
|             "sys_margins": 0             |             "sys_margins": 0             | ||||||
|   | |||||||
										
											Binary file not shown.
										
									
								
							| @@ -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" |  | ||||||
|     } |  | ||||||
|   ] |  | ||||||
| } |  | ||||||
| @@ -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" |  | ||||||
|         ] |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   ] |  | ||||||
| } |  | ||||||
| @@ -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" |  | ||||||
|     } |  | ||||||
|   ] |  | ||||||
| } |  | ||||||
| @@ -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" |  | ||||||
|     } |  | ||||||
|   ] |  | ||||||
| } |  | ||||||
| @@ -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" |  | ||||||
|         ] |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   ] |  | ||||||
| } |  | ||||||
| @@ -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" |  | ||||||
|     } |  | ||||||
|   ] |  | ||||||
| } |  | ||||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										3287
									
								
								tests/data/testTopology_auto_design_expected.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3287
									
								
								tests/data/testTopology_auto_design_expected.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1769
									
								
								tests/data/testTopology_expected.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1769
									
								
								tests/data/testTopology_expected.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -9,8 +9,8 @@ | |||||||
|       "path-constraints": { |       "path-constraints": { | ||||||
|         "te-bandwidth": { |         "te-bandwidth": { | ||||||
|           "technology": "flexi-grid", |           "technology": "flexi-grid", | ||||||
|           "trx_type": "Voyager_16QAM", |           "trx_type": "Voyager", | ||||||
|           "trx_mode": "16QAM", |           "trx_mode": "mode 1", | ||||||
|           "effective-freq-slot": [ |           "effective-freq-slot": [ | ||||||
|             { |             { | ||||||
|               "n": "null", |               "n": "null", | ||||||
| @@ -19,8 +19,8 @@ | |||||||
|           ], |           ], | ||||||
|           "spacing": 50000000000.0, |           "spacing": 50000000000.0, | ||||||
|           "max-nb-of-channel": 80, |           "max-nb-of-channel": 80, | ||||||
|           "output-power": 0.0012589254117941673, |           "output-power": null, | ||||||
|           "path_bandwidth": 0 |           "path_bandwidth": 100000000000.0 | ||||||
|         } |         } | ||||||
|       }, |       }, | ||||||
|       "optimizations": { |       "optimizations": { | ||||||
| @@ -36,8 +36,8 @@ | |||||||
|       "path-constraints": { |       "path-constraints": { | ||||||
|         "te-bandwidth": { |         "te-bandwidth": { | ||||||
|           "technology": "flexi-grid", |           "technology": "flexi-grid", | ||||||
|           "trx_type": "Voyager_16QAM", |           "trx_type": "Voyager", | ||||||
|           "trx_mode": "16QAM", |           "trx_mode": "mode 1", | ||||||
|           "effective-freq-slot": [ |           "effective-freq-slot": [ | ||||||
|             { |             { | ||||||
|               "n": "null", |               "n": "null", | ||||||
| @@ -45,7 +45,7 @@ | |||||||
|             } |             } | ||||||
|           ], |           ], | ||||||
|           "spacing": 50000000000.0, |           "spacing": 50000000000.0, | ||||||
|           "max-nb-of-channel": 80, |           "max-nb-of-channel": null, | ||||||
|           "output-power": 0.0012589254117941673, |           "output-power": 0.0012589254117941673, | ||||||
|           "path_bandwidth": 0 |           "path_bandwidth": 0 | ||||||
|         } |         } | ||||||
| @@ -55,7 +55,7 @@ | |||||||
|           { |           { | ||||||
|             "index": 0, |             "index": 0, | ||||||
|             "unnumbered-hop": { |             "unnumbered-hop": { | ||||||
|               "node-id": "Lannion_CAS", |               "node-id": "roadm Brest_KLA", | ||||||
|               "link-tp-id": "link-tp-id is not used", |               "link-tp-id": "link-tp-id is not used", | ||||||
|               "hop-type": "loose", |               "hop-type": "loose", | ||||||
|               "direction": "direction is not used" |               "direction": "direction is not used" | ||||||
| @@ -70,7 +70,37 @@ | |||||||
|           { |           { | ||||||
|             "index": 1, |             "index": 1, | ||||||
|             "unnumbered-hop": { |             "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", |               "link-tp-id": "link-tp-id is not used", | ||||||
|               "hop-type": "loose", |               "hop-type": "loose", | ||||||
|               "direction": "direction is not used" |               "direction": "direction is not used" | ||||||
| @@ -95,7 +125,7 @@ | |||||||
|         "te-bandwidth": { |         "te-bandwidth": { | ||||||
|           "technology": "flexi-grid", |           "technology": "flexi-grid", | ||||||
|           "trx_type": "vendorA_trx-type1", |           "trx_type": "vendorA_trx-type1", | ||||||
|           "trx_mode": "PS_SP64_1", |           "trx_mode": "mode 1", | ||||||
|           "effective-freq-slot": [ |           "effective-freq-slot": [ | ||||||
|             { |             { | ||||||
|               "n": "null", |               "n": "null", | ||||||
| @@ -105,7 +135,7 @@ | |||||||
|           "spacing": 50000000000.0, |           "spacing": 50000000000.0, | ||||||
|           "max-nb-of-channel": 80, |           "max-nb-of-channel": 80, | ||||||
|           "output-power": 0.0012589254117941673, |           "output-power": 0.0012589254117941673, | ||||||
|           "path_bandwidth": 0 |           "path_bandwidth": 60000000000.0 | ||||||
|         } |         } | ||||||
|       }, |       }, | ||||||
|       "optimizations": { |       "optimizations": { | ||||||
| @@ -122,7 +152,7 @@ | |||||||
|         "te-bandwidth": { |         "te-bandwidth": { | ||||||
|           "technology": "flexi-grid", |           "technology": "flexi-grid", | ||||||
|           "trx_type": "vendorA_trx-type1", |           "trx_type": "vendorA_trx-type1", | ||||||
|           "trx_mode": "PS_SP64_2", |           "trx_mode": "mode 2", | ||||||
|           "effective-freq-slot": [ |           "effective-freq-slot": [ | ||||||
|             { |             { | ||||||
|               "n": "null", |               "n": "null", | ||||||
| @@ -130,9 +160,9 @@ | |||||||
|             } |             } | ||||||
|           ], |           ], | ||||||
|           "spacing": 75000000000.0, |           "spacing": 75000000000.0, | ||||||
|           "max-nb-of-channel": 64, |           "max-nb-of-channel": null, | ||||||
|           "output-power": 0.0019952623149688794, |           "output-power": null, | ||||||
|           "path_bandwidth": 0 |           "path_bandwidth": 150000000000.0 | ||||||
|         } |         } | ||||||
|       }, |       }, | ||||||
|       "optimizations": { |       "optimizations": { | ||||||
| @@ -141,61 +171,33 @@ | |||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "request-id": "5", |       "request-id": "5", | ||||||
|       "source": "Lorient_KMA", |       "source": "Rennes_STA", | ||||||
|       "destination": "Lannion_CAS", |       "destination": "Lannion_CAS", | ||||||
|       "src-tp-id": "trx Lorient_KMA", |       "src-tp-id": "trx Rennes_STA", | ||||||
|       "dst-tp-id": "trx Lannion_CAS", |       "dst-tp-id": "trx Lannion_CAS", | ||||||
|       "path-constraints": { |       "path-constraints": { | ||||||
|         "te-bandwidth": { |         "te-bandwidth": { | ||||||
|           "technology": "flexi-grid", |           "technology": "flexi-grid", | ||||||
|           "trx_type": "Voyager_16QAM", |           "trx_type": "vendorA_trx-type1", | ||||||
|           "trx_mode": "16QAM", |           "trx_mode": "mode 2", | ||||||
|           "effective-freq-slot": [ |           "effective-freq-slot": [ | ||||||
|             { |             { | ||||||
|               "n": "null", |               "n": "null", | ||||||
|               "m": "null" |               "m": "null" | ||||||
|             } |             } | ||||||
|           ], |           ], | ||||||
|           "spacing": 50000000000.0, |           "spacing": 75000000000.0, | ||||||
|           "max-nb-of-channel": 80, |           "max-nb-of-channel": 63, | ||||||
|           "output-power": 0.0012589254117941673, |           "output-power": 0.0019952623149688794, | ||||||
|           "path_bandwidth": 0 |           "path_bandwidth": 20000000000.0 | ||||||
|         } |         } | ||||||
|       }, |       }, | ||||||
|       "optimizations": { |       "optimizations": { | ||||||
|         "explicit-route-include-objects": [ |         "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": [ | ||||||
|     { |  | ||||||
|       "synchronization-id": "0", |  | ||||||
|       "svec": { |  | ||||||
|         "relaxable": "False", |  | ||||||
|         "link-diverse": "True", |  | ||||||
|         "node-diverse": "True", |  | ||||||
|         "request-id-number": [ |  | ||||||
|           "0", |  | ||||||
|           "0" |  | ||||||
|         ] |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     { |     { | ||||||
|       "synchronization-id": "3", |       "synchronization-id": "3", | ||||||
|       "svec": { |       "svec": { | ||||||
| @@ -204,21 +206,21 @@ | |||||||
|         "node-diverse": "True", |         "node-diverse": "True", | ||||||
|         "request-id-number": [ |         "request-id-number": [ | ||||||
|           "3", |           "3", | ||||||
|           "4" |           "1" | ||||||
|         ] |         ] | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "synchronization-id": "5", |       "synchronization-id": "4", | ||||||
|       "svec": { |       "svec": { | ||||||
|         "relaxable": "False", |         "relaxable": "False", | ||||||
|         "link-diverse": "True", |         "link-diverse": "True", | ||||||
|         "node-diverse": "True", |         "node-diverse": "True", | ||||||
|         "request-id-number": [ |         "request-id-number": [ | ||||||
|           "5", |           "4", | ||||||
|           "0" |           "5" | ||||||
|         ] |         ] | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   ] |   ] | ||||||
| } | } | ||||||
| @@ -9,8 +9,8 @@ from json import load | |||||||
| from gnpy.core.elements import Transceiver, Fiber, Edfa | from gnpy.core.elements import Transceiver, Fiber, Edfa | ||||||
| from gnpy.core.utils import lin2db, db2lin | from gnpy.core.utils import lin2db, db2lin | ||||||
| from gnpy.core.info import create_input_spectral_information, SpectralInformation, Channel, Power, Pref | 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.equipment import load_equipment, automatic_fmax, automatic_nch | ||||||
| from gnpy.core.network import build_network, load_network, set_roadm_loss | from gnpy.core.network import build_network, load_network | ||||||
| from pathlib import Path | from pathlib import Path | ||||||
| import pytest | import pytest | ||||||
|  |  | ||||||
| @@ -79,7 +79,7 @@ def test_variable_gain_nf(gain, nf_expected, setup_edfa_variable_gain, si): | |||||||
|     pin = pin/db2lin(gain) |     pin = pin/db2lin(gain) | ||||||
|     baud_rates = array([c.baud_rate for c in si.carriers]) |     baud_rates = array([c.baud_rate for c in si.carriers]) | ||||||
|     edfa.operational.gain_target = gain |     edfa.operational.gain_target = gain | ||||||
|     pref = Pref(0, -gain) |     pref = Pref(0, -gain, lin2db(len(frequencies))) | ||||||
|     edfa.interpol_params(frequencies, pin, baud_rates, pref) |     edfa.interpol_params(frequencies, pin, baud_rates, pref) | ||||||
|     result = edfa.nf |     result = edfa.nf | ||||||
|     assert pytest.approx(nf_expected, abs=0.01) == result[0] |     assert pytest.approx(nf_expected, abs=0.01) == result[0] | ||||||
| @@ -93,7 +93,7 @@ def test_fixed_gain_nf(gain, nf_expected, setup_edfa_fixed_gain, si): | |||||||
|     pin = pin/db2lin(gain) |     pin = pin/db2lin(gain) | ||||||
|     baud_rates = array([c.baud_rate for c in si.carriers]) |     baud_rates = array([c.baud_rate for c in si.carriers]) | ||||||
|     edfa.operational.gain_target = gain |     edfa.operational.gain_target = gain | ||||||
|     pref = Pref(0, -gain) |     pref = Pref(0, -gain, lin2db(len(frequencies))) | ||||||
|     edfa.interpol_params(frequencies, pin, baud_rates, pref) |     edfa.interpol_params(frequencies, pin, baud_rates, pref) | ||||||
|  |  | ||||||
|     assert pytest.approx(nf_expected, abs=0.01) == edfa.nf[0] |     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) |     pin = pin/db2lin(gain) | ||||||
|     baud_rates = array([c.baud_rate for c in si.carriers]) |     baud_rates = array([c.baud_rate for c in si.carriers]) | ||||||
|     edfa.operational.gain_target = gain |     edfa.operational.gain_target = gain | ||||||
|     pref = Pref(0, -gain) |     pref = Pref(0, -gain, lin2db(len(frequencies))) | ||||||
|     edfa.interpol_params(frequencies, pin, baud_rates, pref) |     edfa.interpol_params(frequencies, pin, baud_rates, pref) | ||||||
|     nf_model = edfa.nf[0] |     nf_model = edfa.nf[0] | ||||||
|     edfa.interpol_params(frequencies, pin, baud_rates, pref) |     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]) |     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]) |     baud_rates = array([c.baud_rate for c in si.carriers]) | ||||||
|     edfa.operational.gain_target = gain |     edfa.operational.gain_target = gain | ||||||
|     pref = Pref(0, 0) |     pref = Pref(0, 0, lin2db(len(frequencies))) | ||||||
|     edfa.interpol_params(frequencies, pin, baud_rates, pref) |     edfa.interpol_params(frequencies, pin, baud_rates, pref) | ||||||
|     nf = edfa.nf |     nf = edfa.nf | ||||||
|     pin = lin2db(pin[0]*1e3) |     pin = lin2db(pin[0]*1e3) | ||||||
|   | |||||||
| @@ -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.utils import db2lin, lin2db | ||||||
| from gnpy.core.elements import Roadm | from gnpy.core.elements import Roadm | ||||||
|  |  | ||||||
| network_file_name = Path(__file__).parent.parent / 'tests/data/meshTopologyToy.json' | network_file_name = Path(__file__).parent.parent / 'tests/data/testTopology_expected.json' | ||||||
| service_file_name = Path(__file__).parent.parent / 'tests/data/meshTopologyToy_services.json' | service_file_name = Path(__file__).parent.parent / 'tests/data/testTopology_testservices.json' | ||||||
| result_file_name  = Path(__file__).parent.parent / 'tests/data/meshTopologyToy_results.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' | eqpt_library_name = Path(__file__).parent.parent / 'tests/data/eqpt_config.json' | ||||||
|  |  | ||||||
| @pytest.mark.parametrize("net",[network_file_name]) | @pytest.mark.parametrize("net",[network_file_name]) | ||||||
|   | |||||||
| @@ -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.utils import db2lin, lin2db | ||||||
| from gnpy.core.elements import Roadm | from gnpy.core.elements import Roadm | ||||||
|  |  | ||||||
| network_file_name = Path(__file__).parent.parent / 'tests/data/meshTopologyToy.json' | network_file_name = Path(__file__).parent.parent / 'tests/data/testTopology_expected.json' | ||||||
| service_file_name = Path(__file__).parent.parent / 'tests/data/meshTopologyToy_services.json' | service_file_name = Path(__file__).parent.parent / 'tests/data/testTopology_testservices.json' | ||||||
| result_file_name  = Path(__file__).parent.parent / 'tests/data/meshTopologyToy_results.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' | eqpt_library_name = Path(__file__).parent.parent / 'tests/data/eqpt_config.json' | ||||||
|  |  | ||||||
| @pytest.mark.parametrize("net",[network_file_name]) | @pytest.mark.parametrize("net",[network_file_name]) | ||||||
|   | |||||||
| @@ -11,9 +11,12 @@ from gnpy.core import network_from_json | |||||||
| from gnpy.core.elements import Transceiver, Fiber, Edfa | from gnpy.core.elements import Transceiver, Fiber, Edfa | ||||||
| from gnpy.core.utils import lin2db, db2lin | from gnpy.core.utils import lin2db, db2lin | ||||||
| from gnpy.core.info import SpectralInformation, Channel, Power | 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 tests.compare import compare_networks, compare_services | ||||||
| from gnpy.core.convert import convert_file | from gnpy.core.convert import convert_file | ||||||
| from gnpy.core.service_sheet import convert_service_sheet | 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 | from pathlib import Path | ||||||
| import filecmp | import filecmp | ||||||
| from os import unlink | from os import unlink | ||||||
| @@ -28,10 +31,8 @@ eqpt_filename = DATA_DIR / 'eqpt_config.json' | |||||||
| #    - ..._expected.json for the reference output | #    - ..._expected.json for the reference output | ||||||
|  |  | ||||||
| @pytest.mark.parametrize('xls_input,expected_json_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 / 'CORONET_Global_Topology.xls':   DATA_DIR / 'CORONET_Global_Topology_expected.json', | ||||||
|     DATA_DIR / 'meshTopologyExampleV2.xls':     DATA_DIR / 'meshTopologyExampleV2_expected.json', |     DATA_DIR / 'testTopology.xls':     DATA_DIR / 'testTopology_expected.json', | ||||||
|     DATA_DIR / 'meshTopologyExampleV2Eqpt.xls': DATA_DIR / 'meshTopologyExampleV2Eqpt_expected.json', |  | ||||||
|  }.items()) |  }.items()) | ||||||
| def test_excel_json_generation(xls_input, expected_json_output): | def test_excel_json_generation(xls_input, expected_json_output): | ||||||
|     convert_file(xls_input) |     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') |     actual_json_output = xls_input.with_suffix('.json') | ||||||
|     with open(actual_json_output, encoding='utf-8') as f: |     with open(actual_json_output, encoding='utf-8') as f: | ||||||
|         actual = load(f) |         actual = load(f) | ||||||
|     #unlink(actual_json_output) |     unlink(actual_json_output) | ||||||
|  |  | ||||||
|     with open(expected_json_output, encoding='utf-8') as f: |     with open(expected_json_output, encoding='utf-8') as f: | ||||||
|         expected = load(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.extra | ||||||
|     assert not results.connections.different |     assert not results.connections.different | ||||||
|  |  | ||||||
| # assume json entries | # assume xls entries | ||||||
| # test that the build network gives correct results | # test that the build network gives correct results in gain mode | ||||||
| # TODO !! | #  | ||||||
|  | @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', { | @pytest.mark.parametrize('xls_input,expected_json_output', { | ||||||
|     DATA_DIR / 'excelTestFile.xls':             DATA_DIR / 'excelTestFile_services_expected.json', |     DATA_DIR / 'testTopology.xls':     DATA_DIR / 'testTopology_services_expected.json', | ||||||
|     DATA_DIR / 'meshTopologyExampleV2.xls':     DATA_DIR / 'meshTopologyExampleV2_services_expected.json', |  | ||||||
|     DATA_DIR / 'meshTopologyExampleV2Eqpt.xls': DATA_DIR / 'meshTopologyExampleV2Eqpt_services_expected.json', |  | ||||||
| }.items()) | }.items()) | ||||||
| def test_excel_service_json_generation(xls_input, expected_json_output): | def test_excel_service_json_generation(xls_input, expected_json_output): | ||||||
|     convert_service_sheet(xls_input, eqpt_filename) |     convert_service_sheet(xls_input, eqpt_filename) | ||||||
|   | |||||||
| @@ -47,12 +47,8 @@ def propagation(input_power, con_in, con_out,dest): | |||||||
|  |  | ||||||
|     p = input_power |     p = input_power | ||||||
|     p = db2lin(p) * 1e-3 |     p = db2lin(p) * 1e-3 | ||||||
|     spacing = 0.05 # THz |     spacing = 50e9 # THz | ||||||
|     si = SpectralInformation() # SI units: W, Hz |     si = create_input_spectral_information(191.3e12, 191.3e12+79*spacing, 0.15, 32e9, p, spacing) | ||||||
|     si = si.update(carriers=[ |  | ||||||
|         Channel(f, (191.3 + spacing * f) * 1e12, 32e9, 0.15, Power(p, 0, 0)) |  | ||||||
|         for f in range(1,80) |  | ||||||
|     ]) |  | ||||||
|     source = next(transceivers[uid] for uid in transceivers if uid == 'trx A') |     source = next(transceivers[uid] for uid in transceivers if uid == 'trx A') | ||||||
|     sink = next(transceivers[uid] for uid in transceivers if uid == dest) |     sink = next(transceivers[uid] for uid in transceivers if uid == dest) | ||||||
|     path = dijkstra_path(network, source, sink) |     path = dijkstra_path(network, source, sink) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Jan Kundrát
					Jan Kundrát