diff --git a/Excel_userguide.rst b/Excel_userguide.rst index edc53534..5471236e 100644 --- a/Excel_userguide.rst +++ b/Excel_userguide.rst @@ -189,27 +189,30 @@ Service sheet must contain 11 columns:: route id ; Source ; Destination ; TRX type ; Mode ; System: spacing ; System: input power (dBm) ; System: nb of channels ; routing: disjoint from ; routing: path ; routing: is loose? -- **route id** is mandatory. It must be unique. It is the identifier of the request. It can be an integer or a string (do not use blank or dash) +- **route id** is mandatory. It must be unique. It is the identifier of the request. It can be an integer or a string (do not use blank or dash or coma) - **Source** is mandatory. It is the name of the source node (as listed in Nodes sheet). Source MUST be a ROADM node. (TODO: relax this and accept trx entries) - **Destination** is mandatory. It is the name of the destination node (as listed in Nodes sheet). Source MUST be a ROADM node. (TODO: relax this and accept trx entries) -- **TRX type and mode** are mandatory. They are the variety type and selected mode of the transceiver to be used for the propagation simulation. These modes MUST be defined in the equipment library. The format of the mode is used as the name of the mode. (TODO: maybe add another mode id on Transceiver library ?). In particular the mode selection defines the channel baudrate to be used for the propagation simulation. +- **TRX type ** is mandatory. They are the variety type and selected mode of the transceiver to be used for the propagation simulation. These modes MUST be defined in the equipment library. The format of the mode is used as the name of the mode. (TODO: maybe add another mode id on Transceiver library ?). In particular the mode selection defines the channel baudrate to be used for the propagation simulation. -- **System: spacing ; System: input power (dBm) ; System: nb of channels** are mandatory input defining the system parameters for the propagation simulation. +- **mode** is optional. If not specified, the program will search for the mode of the defined transponder with the highest baudrate fitting within the spacing value. + +- **System: spacing** is mandatory. Spacing is the channel spacing defined in GHz difined for the feasibility propagation simulation, assuming system full load. + +- **System: input power (dBm) ; System: nb of channels** are optional input defining the system parameters for the propagation simulation. - - spacing is the channel spacing defined in GHz - input power is the channel optical input power in dBm - nb of channels is the number of channels to be used for the simulation. - **routing: disjoint from ; routing: path ; routing: is loose?** are optional. - - disjoint from: (work not started) identifies the requests from which this request must be disjoint. It is not used yet - - path: is the set of ROADM nodes that must be used by the path. It must contain the list of ROADM names that the path must cross. TODO : only ROADM nodes are accepted in this release. Relax this with any type of nodes. - - is loose? (in progress) 'no' value means that the list of nodes should be strictly followed, while any other value means that the constraint may be relaxed if the node is not reachable. + - disjoint from: identifies the requests from which this request must be disjoint. If filled it must contain request ids separated by ' | ' + - path: is the set of ROADM nodes that must be used by the path. It must contain the list of ROADM names that the path must cross. TODO : only ROADM nodes are accepted in this release. Relax this with any type of nodes. If filled it must contain ROADM ids separated by ' | '. Exact names are required. + - is loose? 'no' value means that the list of nodes should be strictly followed, while any other value means that the constraint may be relaxed if the node is not reachable. -# to be completed # +- ** path bandwidth** is optional. It is the amount of capacity required between source and destination in Gbit/s. Default value is 0.0 Gbit/s. convert_service_sheet.py ------------------------ diff --git a/README.rst b/README.rst index 290c3b5d..ddb68375 100644 --- a/README.rst +++ b/README.rst @@ -9,7 +9,7 @@ planning and optimization tools in real-world mesh optical networks.** `gnpy `__ is: -- a sponsored project of the `OOPT/PSE `_ working group of the `Telecom Infra Project `_. +- a sponsored project of the `OOPT/PSE `_ working group of the `Telecom Infra Project `_ - fully community-driven, fully open source library - driven by a consortium of operators, vendors, and academic researchers - intended for rapid development of production-grade route planning tools @@ -30,7 +30,11 @@ A brief outline of major (tagged) `gnpy` releases: +---------------+-------------+-----------------------------------------------+ | release date | version tag | notes | +===============+=============+===============================================+ -| Oct 16, 2018 | v1.0 | - first "production"-ready release | +| Jan 30, 2019 | v1.1 | - XLS parser enhancements | +| | | - carrier probe feature | +| | | - bug fixes | ++---------------+-------------+-----------------------------------------------+ +| Oct 16, 2018 | v1.0 | - first "production"-ready release | | | | - open network element model (EDFA, GN-model) | | | | - auto-design functionality | | | | - path request functionality | @@ -135,8 +139,8 @@ By default, this script operates on a single span network defined in `examples/edfa_example_network.json `_ You can specify a different network at the command line as follows. For -example, to use the CORONET Continental US (CONUS) network defined in -`examples/coronet_conus_example.json `_: +example, to use the CORONET Global network defined in +`examples/CORONET_Global_Topology.json `_: .. code-block:: shell @@ -150,10 +154,9 @@ further instructions on how to prepare the Excel input file, see `Excel_userguide.rst `_. The main transmission example will calculate the average signal OSNR and SNR -across 93 network elements (transceiver, ROADMs, fibers, and amplifiers) -between two transceivers selected by the user. (By default, for the CORONET US -network, it will show the transmission of spectral information between Abilene, -Texas and Albany, New York.) +across network elements (transceiver, ROADMs, fibers, and amplifiers) +between two transceivers selected by the user. Additional details are provided by doing ``transmission_main_example.py -h``. (By default, for the CORONET Global +network, it will show the transmission of spectral information between Abilene and Albany) This script calculates the average signal OSNR = |OSNR| and SNR = |SNR|. @@ -171,8 +174,8 @@ Further Instructions for Use (`transmission_main_example.py`, `path_requests_run Design and transmission parameters are defined in a dedicated json file. By default, this information is read from `examples/eqpt_config.json -`_. This file defines the equipement librairies that -can be customized (EDFAs, fibers, and transcievers). +`_. This file defines the equipment libraries that +can be customized (EDFAs, fibers, and transceivers). It also defines the simulation parameters (spans, ROADMs, and the spectral information to transmit.) @@ -182,7 +185,7 @@ can be added and existing ones removed. Three different noise models are availab 1. `'type_def': 'variable_gain'` is a simplified model simulating a 2-coil EDFA with internal, input and output VOAs. The NF vs gain response is calculated accordingly based on the input parameters: `nf_min`, `nf_max`, and `gain_flatmax`. It is not a simple interpolation but a 2-stage NF calculation. 2. `'type_def': 'fixed_gain'` is a fixed gain model. `NF == Cte == nf0` if `gain_min < gain < gain_flatmax` -3. `'type_def': None` is an advanced model. A detailed json configuration file is required (by default `examples/advanced_config_from.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 `_.) 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: @@ -204,12 +207,12 @@ For all amplifier models: | | | Excel template topology files.) | +----------------------+-----------+-----------------------------------------+ -The fiber library currently describes SSMF 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 | +======================+===========+=========================================+ -| `type_variety` | (string) | a unique name to ID the amplifier in the| +| `type_variety` | (string) | a unique name to ID the fiber in the | | | | JSON or Excel template topology input | | | | file | +----------------------+-----------+-----------------------------------------+ @@ -226,7 +229,7 @@ path_request_run.py routine. +----------------------+-----------+-----------------------------------------+ | field | type | description | +======================+===========+=========================================+ -| `type_variety` | (string) | a unique name to ID the amplifier in | +| `type_variety` | (string) | a unique name to ID the transceiver in | | | | the JSON or Excel template topology | | | | input file | +----------------------+-----------+-----------------------------------------+ @@ -252,7 +255,11 @@ The modes are defined as follows: +----------------------+-----------+-----------------------------------------+ | `bit_rate` | (number) | in bit/s | +----------------------+-----------+-----------------------------------------+ -| `roll_off` | (number) | | +| `roll_off` | (number) | Not used. | ++----------------------+-----------+-----------------------------------------+ +| `tx_osnr` | (number) | In dB. OSNR out from transponder. | ++----------------------+-----------+-----------------------------------------+ +| `cost` | (number) | Arbitrary unit | +----------------------+-----------+-----------------------------------------+ Simulation parameters are defined as follows. @@ -269,15 +276,15 @@ For amplifiers defined in the topology JSON input but whose gain = 0 (placeholder), auto-design will set its gain automatically: see `power_mode` in the `Spans` library to find out how the gain is calculated. -Span configuration is performed as followws. It is not a list (which may change -in later releases,) and the user can only modify the value of existing +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 parameters: +------------------------+-----------+---------------------------------------------+ | field | type | description | +========================+===========+=============================================+ | `power_mode` | (boolean) | If false, gain mode. Auto-design sets | -| | | amplifier gain = preceeding span loss, | +| | | amplifier gain = preceding span loss, | | | | unless the amplifier exists and its | | | | gain > 0 in the topology input json. | | | | If true, power mode (recommended for | @@ -291,7 +298,7 @@ parameters: | | | (see power_range_db in the SI | | | | configuration library) the power sweep | | | | is performed w/r/t this power target, | -| | | regardless of preceeding amplifiers | +| | | regardless of preceding amplifiers | | | | power saturation/limitations. | +------------------------+-----------+---------------------------------------------+ | `delta_power_range_db` | (number) | Auto-design only, power-mode | @@ -396,7 +403,7 @@ parameters: } ROADMs can be configured as follows. The user can only modify the value of -existing parmeters: +existing parameters: +-------------------------+-----------+---------------------------------------------+ | field | type | description | @@ -416,7 +423,7 @@ existing parmeters: | | | its egress channel power = power_mode_pref, | | | | regardless of existing loss settings | | | | from the topology JSON input. It means | -| | | that the ouput power from a ROADM (and | +| | | 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 | @@ -445,6 +452,8 @@ one power/channel definition. +----------------------+-----------+-------------------------------------------+ | `bit_rate` | (number) | Not used. | +----------------------+-----------+-------------------------------------------+ +| `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 | | | | settings are offset w/r/t this reference | @@ -465,16 +474,11 @@ one power/channel definition. +----------------------+-----------+-------------------------------------------+ The `transmission_main_example.py `_ -script propagates a specrum of channels at 32 Gbaud, 50 GHz spacing and 0 +script propagates a spectrum of channels at 32 Gbaud, 50 GHz spacing and 0 dBm/channel. These are not yet parametrized but can be modified directly in the -script (via the SpectralInformation structure) to accomodate any baud rate, +script (via the SpectralInformation structure) to accommodate any baud rate, spacing, power or channel count demand. -The amplifier's gain is set to exactly compensate for the loss in each network -element. The amplifier is currently defined with gain range of 15 dB to 25 dB -and 21 dBm max output power. Ripple and NF models are defined in -`examples/std_medium_gain_advanced_config.json `_ - Use `examples/path_requests_run.py `_ to run multiple optimizations as follows: .. code-block:: shell @@ -496,8 +500,8 @@ library. The program computes performances for the list of services (accepts json or excel format) using the same spectrum propagation modules as transmission_main_example.py. Explanation on the Excel template is provided in the `Excel_userguide.rst `_. Template for -the json format can be found here: `service_template.json -`_. +the json format can be found here: `service-template.json +`_. Contributing ------------ @@ -513,7 +517,7 @@ To get involved, please contact James Powell See the `Onboarding Guide `_ for -specific details on code contribtions. +specific details on code contributions. See `AUTHORS.rst `_ for past and present contributors. @@ -523,7 +527,7 @@ Project Background Data Centers are built upon interchangeable, highly standardized node and network architectures rather than a sum of isolated solutions. This also translates to optical networking. It leads to a push in enabling multi-vendor -optical network by disaggregating HW and SW functions and focussing on +optical network by disaggregating HW and SW functions and focusing on interoperability. In this paradigm, the burden of responsibility for ensuring the performance of such disaggregated open optical systems falls on the operators. Consequently, operators and vendors are collaborating in defining diff --git a/docs/index.rst b/docs/index.rst index d41d173a..14e9292d 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -43,6 +43,10 @@ Contributors in alphabetical order +==========+============+=======================+======================================+ | Alessio | Ferrari | Politecnico di Torino | alessio.ferrari@polito.it | +----------+------------+-----------------------+--------------------------------------+ +| Anders | Lindgren | Telia Company | Anders.X.Lindgren@teliacompany.com | ++----------+------------+-----------------------+--------------------------------------+ +| Andrea | d'Amico | Politecnico di Torino | andrea.damico@polito.it | ++----------+------------+-----------------------+--------------------------------------+ | Brian | Taylor | Facebook | briantaylor@fb.com | +----------+------------+-----------------------+--------------------------------------+ | David | Boertjes | Ciena | dboertje@ciena.com | @@ -59,12 +63,19 @@ Contributors in alphabetical order +----------+------------+-----------------------+--------------------------------------+ | Jeanluc | Auge | Orange | jeanluc.auge@orange.com | +----------+------------+-----------------------+--------------------------------------+ +| Jonas | Martensson | RISE Research Sweden | jonas.martensson@ri.se | ++----------+------------+-----------------------+--------------------------------------+ | Mattia | Cantono | Politecnico di Torino | mattia.cantono@polito.it | +----------+------------+-----------------------+--------------------------------------+ +| Miguel | Garrich | University Catalunya | miquel.garrich@upct.es | ++----------+------------+-----------------------+--------------------------------------+ +| Stefan | Melin | Telia Company | Stefan.Melin@teliacompany.com | ++----------+------------+-----------------------+--------------------------------------+ +| Raj | Nagarajan | Lumentum | raj.nagarajan@lumentum.com | ++----------+------------+-----------------------+--------------------------------------+ | Vittorio | Curri | Politecnico di Torino | vittorio.curri@polito.it | +----------+------------+-----------------------+--------------------------------------+ -PSE WG Charter -------------- - Goal is to build an end-to-end simulation environment which defines the diff --git a/examples/CORONET_Global_Topology.json b/examples/CORONET_Global_Topology.json index 4dd8106b..02657f9a 100644 --- a/examples/CORONET_Global_Topology.json +++ b/examples/CORONET_Global_Topology.json @@ -1,5 +1,29 @@ { "elements": [ + { + "uid": "trx Abilene", + "metadata": { + "location": { + "city": "Abilene", + "region": "CONUS", + "latitude": 32.45, + "longitude": -99.739998 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Albany", + "metadata": { + "location": { + "city": "Albany", + "region": "CONUS", + "latitude": 42.6699982, + "longitude": -73.8000029 + } + }, + "type": "Transceiver" + }, { "uid": "trx Albuquerque", "metadata": { @@ -24,6 +48,18 @@ }, "type": "Transceiver" }, + { + "uid": "trx Austin", + "metadata": { + "location": { + "city": "Austin", + "region": "CONUS", + "latitude": 30.3099988, + "longitude": -97.7500018 + } + }, + "type": "Transceiver" + }, { "uid": "trx Baltimore", "metadata": { @@ -36,6 +72,18 @@ }, "type": "Transceiver" }, + { + "uid": "trx Baton_Rouge", + "metadata": { + "location": { + "city": "Baton_Rouge", + "region": "CONUS", + "latitude": 30.4499996, + "longitude": -91.1299968 + } + }, + "type": "Transceiver" + }, { "uid": "trx Billings", "metadata": { @@ -60,6 +108,66 @@ }, "type": "Transceiver" }, + { + "uid": "trx Bismarck", + "metadata": { + "location": { + "city": "Bismarck", + "region": "CONUS", + "latitude": 46.81000154, + "longitude": -100.7699965 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Boston", + "metadata": { + "location": { + "city": "Boston", + "region": "CONUS", + "latitude": 42.3400005, + "longitude": -71.0199959 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Buffalo", + "metadata": { + "location": { + "city": "Buffalo", + "region": "CONUS", + "latitude": 42.8899993, + "longitude": -78.860001 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Charleston", + "metadata": { + "location": { + "city": "Charleston", + "region": "CONUS", + "latitude": 32.7900008, + "longitude": -79.9899982 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Charlotte", + "metadata": { + "location": { + "city": "Charlotte", + "region": "CONUS", + "latitude": 35.2, + "longitude": -80.83 + } + }, + "type": "Transceiver" + }, { "uid": "trx Chicago", "metadata": { @@ -132,6 +240,18 @@ }, "type": "Transceiver" }, + { + "uid": "trx Detroit", + "metadata": { + "location": { + "city": "Detroit", + "region": "CONUS", + "latitude": 42.3800019, + "longitude": -83.0999998 + } + }, + "type": "Transceiver" + }, { "uid": "trx El_Paso", "metadata": { @@ -168,6 +288,18 @@ }, "type": "Transceiver" }, + { + "uid": "trx Hartford", + "metadata": { + "location": { + "city": "Hartford", + "region": "CONUS", + "latitude": 41.7700004, + "longitude": -72.6800003 + } + }, + "type": "Transceiver" + }, { "uid": "trx Houston", "metadata": { @@ -216,6 +348,30 @@ }, "type": "Transceiver" }, + { + "uid": "trx Little_Rock", + "metadata": { + "location": { + "city": "Little_Rock", + "region": "CONUS", + "latitude": 34.72, + "longitude": -92.35 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Long_Island", + "metadata": { + "location": { + "city": "Long_Island", + "region": "CONUS", + "latitude": 40.5899999, + "longitude": -73.6699993 + } + }, + "type": "Transceiver" + }, { "uid": "trx Los_Angeles", "metadata": { @@ -240,6 +396,18 @@ }, "type": "Transceiver" }, + { + "uid": "trx Memphis", + "metadata": { + "location": { + "city": "Memphis", + "region": "CONUS", + "latitude": 35.110001, + "longitude": -90.010004 + } + }, + "type": "Transceiver" + }, { "uid": "trx Miami", "metadata": { @@ -252,6 +420,18 @@ }, "type": "Transceiver" }, + { + "uid": "trx Milwaukee", + "metadata": { + "location": { + "city": "Milwaukee", + "region": "CONUS", + "latitude": 43.0600013, + "longitude": -87.9700005 + } + }, + "type": "Transceiver" + }, { "uid": "trx Minneapolis", "metadata": { @@ -300,6 +480,30 @@ }, "type": "Transceiver" }, + { + "uid": "trx Newark", + "metadata": { + "location": { + "city": "Newark", + "region": "CONUS", + "latitude": 40.7200012, + "longitude": -74.1699986 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Norfolk", + "metadata": { + "location": { + "city": "Norfolk", + "region": "CONUS", + "latitude": 36.9199982, + "longitude": -76.2399978 + } + }, + "type": "Transceiver" + }, { "uid": "trx Oakland", "metadata": { @@ -312,6 +516,18 @@ }, "type": "Transceiver" }, + { + "uid": "trx Oklahoma_City", + "metadata": { + "location": { + "city": "Oklahoma_City", + "region": "CONUS", + "latitude": 35.4700015, + "longitude": -97.5100028 + } + }, + "type": "Transceiver" + }, { "uid": "trx Omaha", "metadata": { @@ -324,6 +540,18 @@ }, "type": "Transceiver" }, + { + "uid": "trx Orlando", + "metadata": { + "location": { + "city": "Orlando", + "region": "CONUS", + "latitude": 28.4999994, + "longitude": -81.370003 + } + }, + "type": "Transceiver" + }, { "uid": "trx Philadelphia", "metadata": { @@ -372,6 +600,18 @@ }, "type": "Transceiver" }, + { + "uid": "trx Providence", + "metadata": { + "location": { + "city": "Providence", + "region": "CONUS", + "latitude": 41.82, + "longitude": -71.42 + } + }, + "type": "Transceiver" + }, { "uid": "trx Raleigh", "metadata": { @@ -384,6 +624,42 @@ }, "type": "Transceiver" }, + { + "uid": "trx Richmond", + "metadata": { + "location": { + "city": "Richmond", + "region": "CONUS", + "latitude": 37.5299986, + "longitude": -77.4700015 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Rochester", + "metadata": { + "location": { + "city": "Rochester", + "region": "CONUS", + "latitude": 43.1699985, + "longitude": -77.620003 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Sacramento", + "metadata": { + "location": { + "city": "Sacramento", + "region": "CONUS", + "latitude": 38.56999946, + "longitude": -121.4700016 + } + }, + "type": "Transceiver" + }, { "uid": "trx Salt_Lake_City", "metadata": { @@ -396,6 +672,66 @@ }, "type": "Transceiver" }, + { + "uid": "trx San_Antonio", + "metadata": { + "location": { + "city": "San_Antonio", + "region": "CONUS", + "latitude": 29.459997, + "longitude": -98.510002 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx San_Diego", + "metadata": { + "location": { + "city": "San_Diego", + "region": "CONUS", + "latitude": 32.8100017, + "longitude": -117.139999 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx San_Francisco", + "metadata": { + "location": { + "city": "San_Francisco", + "region": "CONUS", + "latitude": 37.65999942, + "longitude": -122.4199987 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx San_Jose", + "metadata": { + "location": { + "city": "San_Jose", + "region": "CONUS", + "latitude": 37.29999947, + "longitude": -121.8499985 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Santa_Barbara", + "metadata": { + "location": { + "city": "Santa_Barbara", + "region": "CONUS", + "latitude": 34.43000021, + "longitude": -119.7200014 + } + }, + "type": "Transceiver" + }, { "uid": "trx Scranton", "metadata": { @@ -408,6 +744,42 @@ }, "type": "Transceiver" }, + { + "uid": "trx Seattle", + "metadata": { + "location": { + "city": "Seattle", + "region": "CONUS", + "latitude": 47.61999916, + "longitude": -122.3499985 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Spokane", + "metadata": { + "location": { + "city": "Spokane", + "region": "CONUS", + "latitude": 47.66999805, + "longitude": -117.4100038 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Springfield", + "metadata": { + "location": { + "city": "Springfield", + "region": "CONUS", + "latitude": 39.5, + "longitude": -89.4 + } + }, + "type": "Transceiver" + }, { "uid": "trx St_Louis", "metadata": { @@ -432,6 +804,66 @@ }, "type": "Transceiver" }, + { + "uid": "trx Tallahassee", + "metadata": { + "location": { + "city": "Tallahassee", + "region": "CONUS", + "latitude": 30.46, + "longitude": -84.28 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Tampa", + "metadata": { + "location": { + "city": "Tampa", + "region": "CONUS", + "latitude": 27.9599988, + "longitude": -82.4800035 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Toledo", + "metadata": { + "location": { + "city": "Toledo", + "region": "CONUS", + "latitude": 41.659997, + "longitude": -83.58 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Tucson", + "metadata": { + "location": { + "city": "Tucson", + "region": "CONUS", + "latitude": 32.2, + "longitude": -110.89 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Tulsa", + "metadata": { + "location": { + "city": "Tulsa", + "region": "CONUS", + "latitude": 36.13, + "longitude": -95.92 + } + }, + "type": "Transceiver" + }, { "uid": "trx Washington_DC", "metadata": { @@ -444,6 +876,30 @@ }, "type": "Transceiver" }, + { + "uid": "trx West_Palm_Beach", + "metadata": { + "location": { + "city": "West_Palm_Beach", + "region": "CONUS", + "latitude": 26.7499997, + "longitude": -80.1299975 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Wilmington", + "metadata": { + "location": { + "city": "Wilmington", + "region": "CONUS", + "latitude": 39.7400018, + "longitude": -75.5299989 + } + }, + "type": "Transceiver" + }, { "uid": "trx Amsterdam", "metadata": { @@ -456,6 +912,54 @@ }, "type": "Transceiver" }, + { + "uid": "trx Berlin", + "metadata": { + "location": { + "city": "Berlin", + "region": "Europe", + "latitude": 52.520002, + "longitude": 13.379995 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Brussels", + "metadata": { + "location": { + "city": "Brussels", + "region": "Europe", + "latitude": 50.830002, + "longitude": 4.330002 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Bucharest", + "metadata": { + "location": { + "city": "Bucharest", + "region": "Europe", + "latitude": 44.44, + "longitude": 26.1 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Frankfurt", + "metadata": { + "location": { + "city": "Frankfurt", + "region": "Europe", + "latitude": 50.1199992, + "longitude": 8.68000104 + } + }, + "type": "Transceiver" + }, { "uid": "trx Istanbul", "metadata": { @@ -480,6 +984,18 @@ }, "type": "Transceiver" }, + { + "uid": "trx Madrid", + "metadata": { + "location": { + "city": "Madrid", + "region": "Europe", + "latitude": 40.419998, + "longitude": -3.7100002 + } + }, + "type": "Transceiver" + }, { "uid": "trx Paris", "metadata": { @@ -528,6 +1044,42 @@ }, "type": "Transceiver" }, + { + "uid": "trx Zurich", + "metadata": { + "location": { + "city": "Zurich", + "region": "Europe", + "latitude": 47.3800015, + "longitude": 8.5399996 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Bangkok", + "metadata": { + "location": { + "city": "Bangkok", + "region": "Asia", + "latitude": 13.73, + "longitude": 100.5 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Beijing", + "metadata": { + "location": { + "city": "Beijing", + "region": "Asia", + "latitude": 39.92999979, + "longitude": 116.4000013 + } + }, + "type": "Transceiver" + }, { "uid": "trx Delhi", "metadata": { @@ -576,6 +1128,42 @@ }, "type": "Transceiver" }, + { + "uid": "trx Seoul", + "metadata": { + "location": { + "city": "Seoul", + "region": "Asia", + "latitude": 37.56000108, + "longitude": 126.9899988 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Shanghai", + "metadata": { + "location": { + "city": "Shanghai", + "region": "Asia", + "latitude": 31.23, + "longitude": 121.47 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Singapore", + "metadata": { + "location": { + "city": "Singapore", + "region": "Asia", + "latitude": 1.299999907, + "longitude": 103.8499992 + } + }, + "type": "Transceiver" + }, { "uid": "trx Sydney", "metadata": { @@ -612,6 +1200,30 @@ }, "type": "Transceiver" }, + { + "uid": "roadm Abilene", + "metadata": { + "location": { + "city": "Abilene", + "region": "CONUS", + "latitude": 32.45, + "longitude": -99.739998 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Albany", + "metadata": { + "location": { + "city": "Albany", + "region": "CONUS", + "latitude": 42.6699982, + "longitude": -73.8000029 + } + }, + "type": "Roadm" + }, { "uid": "roadm Albuquerque", "metadata": { @@ -636,6 +1248,18 @@ }, "type": "Roadm" }, + { + "uid": "roadm Austin", + "metadata": { + "location": { + "city": "Austin", + "region": "CONUS", + "latitude": 30.3099988, + "longitude": -97.7500018 + } + }, + "type": "Roadm" + }, { "uid": "roadm Baltimore", "metadata": { @@ -648,6 +1272,18 @@ }, "type": "Roadm" }, + { + "uid": "roadm Baton_Rouge", + "metadata": { + "location": { + "city": "Baton_Rouge", + "region": "CONUS", + "latitude": 30.4499996, + "longitude": -91.1299968 + } + }, + "type": "Roadm" + }, { "uid": "roadm Billings", "metadata": { @@ -672,6 +1308,66 @@ }, "type": "Roadm" }, + { + "uid": "roadm Bismarck", + "metadata": { + "location": { + "city": "Bismarck", + "region": "CONUS", + "latitude": 46.81000154, + "longitude": -100.7699965 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Boston", + "metadata": { + "location": { + "city": "Boston", + "region": "CONUS", + "latitude": 42.3400005, + "longitude": -71.0199959 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Buffalo", + "metadata": { + "location": { + "city": "Buffalo", + "region": "CONUS", + "latitude": 42.8899993, + "longitude": -78.860001 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Charleston", + "metadata": { + "location": { + "city": "Charleston", + "region": "CONUS", + "latitude": 32.7900008, + "longitude": -79.9899982 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Charlotte", + "metadata": { + "location": { + "city": "Charlotte", + "region": "CONUS", + "latitude": 35.2, + "longitude": -80.83 + } + }, + "type": "Roadm" + }, { "uid": "roadm Chicago", "metadata": { @@ -744,6 +1440,18 @@ }, "type": "Roadm" }, + { + "uid": "roadm Detroit", + "metadata": { + "location": { + "city": "Detroit", + "region": "CONUS", + "latitude": 42.3800019, + "longitude": -83.0999998 + } + }, + "type": "Roadm" + }, { "uid": "roadm El_Paso", "metadata": { @@ -780,6 +1488,18 @@ }, "type": "Roadm" }, + { + "uid": "roadm Hartford", + "metadata": { + "location": { + "city": "Hartford", + "region": "CONUS", + "latitude": 41.7700004, + "longitude": -72.6800003 + } + }, + "type": "Roadm" + }, { "uid": "roadm Houston", "metadata": { @@ -828,6 +1548,30 @@ }, "type": "Roadm" }, + { + "uid": "roadm Little_Rock", + "metadata": { + "location": { + "city": "Little_Rock", + "region": "CONUS", + "latitude": 34.72, + "longitude": -92.35 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Long_Island", + "metadata": { + "location": { + "city": "Long_Island", + "region": "CONUS", + "latitude": 40.5899999, + "longitude": -73.6699993 + } + }, + "type": "Roadm" + }, { "uid": "roadm Los_Angeles", "metadata": { @@ -852,6 +1596,18 @@ }, "type": "Roadm" }, + { + "uid": "roadm Memphis", + "metadata": { + "location": { + "city": "Memphis", + "region": "CONUS", + "latitude": 35.110001, + "longitude": -90.010004 + } + }, + "type": "Roadm" + }, { "uid": "roadm Miami", "metadata": { @@ -864,6 +1620,18 @@ }, "type": "Roadm" }, + { + "uid": "roadm Milwaukee", + "metadata": { + "location": { + "city": "Milwaukee", + "region": "CONUS", + "latitude": 43.0600013, + "longitude": -87.9700005 + } + }, + "type": "Roadm" + }, { "uid": "roadm Minneapolis", "metadata": { @@ -912,6 +1680,30 @@ }, "type": "Roadm" }, + { + "uid": "roadm Newark", + "metadata": { + "location": { + "city": "Newark", + "region": "CONUS", + "latitude": 40.7200012, + "longitude": -74.1699986 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Norfolk", + "metadata": { + "location": { + "city": "Norfolk", + "region": "CONUS", + "latitude": 36.9199982, + "longitude": -76.2399978 + } + }, + "type": "Roadm" + }, { "uid": "roadm Oakland", "metadata": { @@ -924,6 +1716,18 @@ }, "type": "Roadm" }, + { + "uid": "roadm Oklahoma_City", + "metadata": { + "location": { + "city": "Oklahoma_City", + "region": "CONUS", + "latitude": 35.4700015, + "longitude": -97.5100028 + } + }, + "type": "Roadm" + }, { "uid": "roadm Omaha", "metadata": { @@ -936,6 +1740,18 @@ }, "type": "Roadm" }, + { + "uid": "roadm Orlando", + "metadata": { + "location": { + "city": "Orlando", + "region": "CONUS", + "latitude": 28.4999994, + "longitude": -81.370003 + } + }, + "type": "Roadm" + }, { "uid": "roadm Philadelphia", "metadata": { @@ -984,6 +1800,18 @@ }, "type": "Roadm" }, + { + "uid": "roadm Providence", + "metadata": { + "location": { + "city": "Providence", + "region": "CONUS", + "latitude": 41.82, + "longitude": -71.42 + } + }, + "type": "Roadm" + }, { "uid": "roadm Raleigh", "metadata": { @@ -996,6 +1824,42 @@ }, "type": "Roadm" }, + { + "uid": "roadm Richmond", + "metadata": { + "location": { + "city": "Richmond", + "region": "CONUS", + "latitude": 37.5299986, + "longitude": -77.4700015 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Rochester", + "metadata": { + "location": { + "city": "Rochester", + "region": "CONUS", + "latitude": 43.1699985, + "longitude": -77.620003 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Sacramento", + "metadata": { + "location": { + "city": "Sacramento", + "region": "CONUS", + "latitude": 38.56999946, + "longitude": -121.4700016 + } + }, + "type": "Roadm" + }, { "uid": "roadm Salt_Lake_City", "metadata": { @@ -1008,6 +1872,66 @@ }, "type": "Roadm" }, + { + "uid": "roadm San_Antonio", + "metadata": { + "location": { + "city": "San_Antonio", + "region": "CONUS", + "latitude": 29.459997, + "longitude": -98.510002 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm San_Diego", + "metadata": { + "location": { + "city": "San_Diego", + "region": "CONUS", + "latitude": 32.8100017, + "longitude": -117.139999 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm San_Francisco", + "metadata": { + "location": { + "city": "San_Francisco", + "region": "CONUS", + "latitude": 37.65999942, + "longitude": -122.4199987 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm San_Jose", + "metadata": { + "location": { + "city": "San_Jose", + "region": "CONUS", + "latitude": 37.29999947, + "longitude": -121.8499985 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Santa_Barbara", + "metadata": { + "location": { + "city": "Santa_Barbara", + "region": "CONUS", + "latitude": 34.43000021, + "longitude": -119.7200014 + } + }, + "type": "Roadm" + }, { "uid": "roadm Scranton", "metadata": { @@ -1020,6 +1944,42 @@ }, "type": "Roadm" }, + { + "uid": "roadm Seattle", + "metadata": { + "location": { + "city": "Seattle", + "region": "CONUS", + "latitude": 47.61999916, + "longitude": -122.3499985 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Spokane", + "metadata": { + "location": { + "city": "Spokane", + "region": "CONUS", + "latitude": 47.66999805, + "longitude": -117.4100038 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Springfield", + "metadata": { + "location": { + "city": "Springfield", + "region": "CONUS", + "latitude": 39.5, + "longitude": -89.4 + } + }, + "type": "Roadm" + }, { "uid": "roadm St_Louis", "metadata": { @@ -1044,6 +2004,66 @@ }, "type": "Roadm" }, + { + "uid": "roadm Tallahassee", + "metadata": { + "location": { + "city": "Tallahassee", + "region": "CONUS", + "latitude": 30.46, + "longitude": -84.28 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Tampa", + "metadata": { + "location": { + "city": "Tampa", + "region": "CONUS", + "latitude": 27.9599988, + "longitude": -82.4800035 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Toledo", + "metadata": { + "location": { + "city": "Toledo", + "region": "CONUS", + "latitude": 41.659997, + "longitude": -83.58 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Tucson", + "metadata": { + "location": { + "city": "Tucson", + "region": "CONUS", + "latitude": 32.2, + "longitude": -110.89 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Tulsa", + "metadata": { + "location": { + "city": "Tulsa", + "region": "CONUS", + "latitude": 36.13, + "longitude": -95.92 + } + }, + "type": "Roadm" + }, { "uid": "roadm Washington_DC", "metadata": { @@ -1056,6 +2076,30 @@ }, "type": "Roadm" }, + { + "uid": "roadm West_Palm_Beach", + "metadata": { + "location": { + "city": "West_Palm_Beach", + "region": "CONUS", + "latitude": 26.7499997, + "longitude": -80.1299975 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Wilmington", + "metadata": { + "location": { + "city": "Wilmington", + "region": "CONUS", + "latitude": 39.7400018, + "longitude": -75.5299989 + } + }, + "type": "Roadm" + }, { "uid": "roadm Amsterdam", "metadata": { @@ -1068,6 +2112,54 @@ }, "type": "Roadm" }, + { + "uid": "roadm Berlin", + "metadata": { + "location": { + "city": "Berlin", + "region": "Europe", + "latitude": 52.520002, + "longitude": 13.379995 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Brussels", + "metadata": { + "location": { + "city": "Brussels", + "region": "Europe", + "latitude": 50.830002, + "longitude": 4.330002 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Bucharest", + "metadata": { + "location": { + "city": "Bucharest", + "region": "Europe", + "latitude": 44.44, + "longitude": 26.1 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Frankfurt", + "metadata": { + "location": { + "city": "Frankfurt", + "region": "Europe", + "latitude": 50.1199992, + "longitude": 8.68000104 + } + }, + "type": "Roadm" + }, { "uid": "roadm Istanbul", "metadata": { @@ -1092,6 +2184,18 @@ }, "type": "Roadm" }, + { + "uid": "roadm Madrid", + "metadata": { + "location": { + "city": "Madrid", + "region": "Europe", + "latitude": 40.419998, + "longitude": -3.7100002 + } + }, + "type": "Roadm" + }, { "uid": "roadm Paris", "metadata": { @@ -1140,6 +2244,42 @@ }, "type": "Roadm" }, + { + "uid": "roadm Zurich", + "metadata": { + "location": { + "city": "Zurich", + "region": "Europe", + "latitude": 47.3800015, + "longitude": 8.5399996 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Bangkok", + "metadata": { + "location": { + "city": "Bangkok", + "region": "Asia", + "latitude": 13.73, + "longitude": 100.5 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Beijing", + "metadata": { + "location": { + "city": "Beijing", + "region": "Asia", + "latitude": 39.92999979, + "longitude": 116.4000013 + } + }, + "type": "Roadm" + }, { "uid": "roadm Delhi", "metadata": { @@ -1188,6 +2328,42 @@ }, "type": "Roadm" }, + { + "uid": "roadm Seoul", + "metadata": { + "location": { + "city": "Seoul", + "region": "Asia", + "latitude": 37.56000108, + "longitude": 126.9899988 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Shanghai", + "metadata": { + "location": { + "city": "Shanghai", + "region": "Asia", + "latitude": 31.23, + "longitude": 121.47 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Singapore", + "metadata": { + "location": { + "city": "Singapore", + "region": "Asia", + "latitude": 1.299999907, + "longitude": 103.8499992 + } + }, + "type": "Roadm" + }, { "uid": "roadm Sydney", "metadata": { @@ -1225,7 +2401,7 @@ "type": "Roadm" }, { - "uid": "fiber (Abilene \u2192 Dallas)-", + "uid": "fiber (Abilene → Dallas)-", "metadata": { "location": { "latitude": 32.620000000000005, @@ -1243,7 +2419,7 @@ } }, { - "uid": "fiber (Abilene \u2192 El_Paso)-", + "uid": "fiber (Abilene → El_Paso)-", "metadata": { "location": { "latitude": 32.149905000000004, @@ -1261,7 +2437,7 @@ } }, { - "uid": "fiber (Albany \u2192 Boston)-", + "uid": "fiber (Albany → Boston)-", "metadata": { "location": { "latitude": 42.504999350000006, @@ -1279,7 +2455,7 @@ } }, { - "uid": "fiber (Albany \u2192 Syracuse)-", + "uid": "fiber (Albany → Syracuse)-", "metadata": { "location": { "latitude": 42.8549996, @@ -1297,7 +2473,7 @@ } }, { - "uid": "fiber (Albuquerque \u2192 Dallas)-", + "uid": "fiber (Albuquerque → Dallas)-", "metadata": { "location": { "latitude": 33.9549885, @@ -1315,7 +2491,7 @@ } }, { - "uid": "fiber (Albuquerque \u2192 Denver)-", + "uid": "fiber (Albuquerque → Denver)-", "metadata": { "location": { "latitude": 37.444989855, @@ -1333,7 +2509,7 @@ } }, { - "uid": "fiber (Albuquerque \u2192 El_Paso)-", + "uid": "fiber (Albuquerque → El_Paso)-", "metadata": { "location": { "latitude": 33.4848935, @@ -1351,7 +2527,7 @@ } }, { - "uid": "fiber (Albuquerque \u2192 Las_Vegas)-", + "uid": "fiber (Albuquerque → Las_Vegas)-", "metadata": { "location": { "latitude": 35.6649835, @@ -1369,7 +2545,7 @@ } }, { - "uid": "fiber (Amsterdam \u2192 Berlin)-", + "uid": "fiber (Amsterdam → Berlin)-", "metadata": { "location": { "latitude": 52.4450008, @@ -1387,7 +2563,7 @@ } }, { - "uid": "fiber (Amsterdam \u2192 Brussels)-", + "uid": "fiber (Amsterdam → Brussels)-", "metadata": { "location": { "latitude": 51.600000800000004, @@ -1405,7 +2581,7 @@ } }, { - "uid": "fiber (Amsterdam \u2192 Frankfurt)-", + "uid": "fiber (Amsterdam → Frankfurt)-", "metadata": { "location": { "latitude": 51.2449994, @@ -1423,7 +2599,7 @@ } }, { - "uid": "fiber (Amsterdam \u2192 New_York)-", + "uid": "fiber (Amsterdam → New_York)-", "metadata": { "location": { "latitude": 46.51999895, @@ -1441,7 +2617,7 @@ } }, { - "uid": "fiber (Atlanta \u2192 Birmingham)-", + "uid": "fiber (Atlanta → Birmingham)-", "metadata": { "location": { "latitude": 33.644998349999995, @@ -1459,7 +2635,7 @@ } }, { - "uid": "fiber (Atlanta \u2192 Charlotte)-", + "uid": "fiber (Atlanta → Charlotte)-", "metadata": { "location": { "latitude": 34.4799991, @@ -1477,7 +2653,7 @@ } }, { - "uid": "fiber (Atlanta \u2192 Jacksonville)-", + "uid": "fiber (Atlanta → Jacksonville)-", "metadata": { "location": { "latitude": 32.0450006, @@ -1495,7 +2671,7 @@ } }, { - "uid": "fiber (Austin \u2192 Houston)-", + "uid": "fiber (Austin → Houston)-", "metadata": { "location": { "latitude": 30.0399994, @@ -1513,7 +2689,7 @@ } }, { - "uid": "fiber (Austin \u2192 San_Antonio)-", + "uid": "fiber (Austin → San_Antonio)-", "metadata": { "location": { "latitude": 29.884997900000002, @@ -1531,7 +2707,7 @@ } }, { - "uid": "fiber (Baltimore \u2192 Philadelphia)-", + "uid": "fiber (Baltimore → Philadelphia)-", "metadata": { "location": { "latitude": 39.65499885, @@ -1549,7 +2725,7 @@ } }, { - "uid": "fiber (Baltimore \u2192 Pittsburgh)-", + "uid": "fiber (Baltimore → Pittsburgh)-", "metadata": { "location": { "latitude": 39.7999996, @@ -1567,7 +2743,7 @@ } }, { - "uid": "fiber (Baltimore \u2192 Washington_DC)-", + "uid": "fiber (Baltimore → Washington_DC)-", "metadata": { "location": { "latitude": 39.104999750000005, @@ -1585,7 +2761,7 @@ } }, { - "uid": "fiber (Bangkok \u2192 Delhi)-", + "uid": "fiber (Bangkok → Delhi)-", "metadata": { "location": { "latitude": 21.20000015, @@ -1603,7 +2779,7 @@ } }, { - "uid": "fiber (Bangkok \u2192 Hong_Kong)-", + "uid": "fiber (Bangkok → Hong_Kong)-", "metadata": { "location": { "latitude": 17.9985, @@ -1621,7 +2797,7 @@ } }, { - "uid": "fiber (Baton_Rouge \u2192 Houston)-", + "uid": "fiber (Baton_Rouge → Houston)-", "metadata": { "location": { "latitude": 30.1099998, @@ -1639,7 +2815,7 @@ } }, { - "uid": "fiber (Baton_Rouge \u2192 New_Orleans)-", + "uid": "fiber (Baton_Rouge → New_Orleans)-", "metadata": { "location": { "latitude": 30.259999800000003, @@ -1657,7 +2833,7 @@ } }, { - "uid": "fiber (Beijing \u2192 Seoul)-", + "uid": "fiber (Beijing → Seoul)-", "metadata": { "location": { "latitude": 38.745000434999994, @@ -1675,7 +2851,7 @@ } }, { - "uid": "fiber (Beijing \u2192 Shanghai)-", + "uid": "fiber (Beijing → Shanghai)-", "metadata": { "location": { "latitude": 35.579999895, @@ -1693,7 +2869,7 @@ } }, { - "uid": "fiber (Berlin \u2192 Warsaw)-", + "uid": "fiber (Berlin → Warsaw)-", "metadata": { "location": { "latitude": 52.390000349999994, @@ -1711,7 +2887,7 @@ } }, { - "uid": "fiber (Billings \u2192 Bismarck)-", + "uid": "fiber (Billings → Bismarck)-", "metadata": { "location": { "latitude": 46.30000129, @@ -1729,7 +2905,7 @@ } }, { - "uid": "fiber (Billings \u2192 Denver)-", + "uid": "fiber (Billings → Denver)-", "metadata": { "location": { "latitude": 42.780001874999996, @@ -1747,7 +2923,7 @@ } }, { - "uid": "fiber (Billings \u2192 Spokane)-", + "uid": "fiber (Billings → Spokane)-", "metadata": { "location": { "latitude": 46.729999545, @@ -1765,7 +2941,7 @@ } }, { - "uid": "fiber (Birmingham \u2192 Nashville)-", + "uid": "fiber (Birmingham → Nashville)-", "metadata": { "location": { "latitude": 34.84999845, @@ -1783,7 +2959,7 @@ } }, { - "uid": "fiber (Birmingham \u2192 New_Orleans)-", + "uid": "fiber (Birmingham → New_Orleans)-", "metadata": { "location": { "latitude": 31.79999925, @@ -1801,7 +2977,7 @@ } }, { - "uid": "fiber (Bismarck \u2192 Minneapolis)-", + "uid": "fiber (Bismarck → Minneapolis)-", "metadata": { "location": { "latitude": 45.88500017, @@ -1819,7 +2995,7 @@ } }, { - "uid": "fiber (Boston \u2192 Providence)-", + "uid": "fiber (Boston → Providence)-", "metadata": { "location": { "latitude": 42.08000025, @@ -1837,7 +3013,7 @@ } }, { - "uid": "fiber (Brussels \u2192 London)-", + "uid": "fiber (Brussels → London)-", "metadata": { "location": { "latitude": 51.17500125, @@ -1855,7 +3031,7 @@ } }, { - "uid": "fiber (Bucharest \u2192 Istanbul)-", + "uid": "fiber (Bucharest → Istanbul)-", "metadata": { "location": { "latitude": 42.769999999999996, @@ -1873,7 +3049,7 @@ } }, { - "uid": "fiber (Bucharest \u2192 Warsaw)-", + "uid": "fiber (Bucharest → Warsaw)-", "metadata": { "location": { "latitude": 48.34999935, @@ -1891,7 +3067,7 @@ } }, { - "uid": "fiber (Buffalo \u2192 Cleveland)-", + "uid": "fiber (Buffalo → Cleveland)-", "metadata": { "location": { "latitude": 42.184999250000004, @@ -1909,7 +3085,7 @@ } }, { - "uid": "fiber (Buffalo \u2192 Rochester)-", + "uid": "fiber (Buffalo → Rochester)-", "metadata": { "location": { "latitude": 43.029998899999995, @@ -1927,7 +3103,7 @@ } }, { - "uid": "fiber (Charleston \u2192 Jacksonville)-", + "uid": "fiber (Charleston → Jacksonville)-", "metadata": { "location": { "latitude": 31.560001900000003, @@ -1945,7 +3121,7 @@ } }, { - "uid": "fiber (Charleston \u2192 Raleigh)-", + "uid": "fiber (Charleston → Raleigh)-", "metadata": { "location": { "latitude": 34.30500015, @@ -1963,7 +3139,7 @@ } }, { - "uid": "fiber (Charlotte \u2192 Greensboro)-", + "uid": "fiber (Charlotte → Greensboro)-", "metadata": { "location": { "latitude": 35.6400012, @@ -1981,7 +3157,7 @@ } }, { - "uid": "fiber (Chicago \u2192 Detroit)-", + "uid": "fiber (Chicago → Detroit)-", "metadata": { "location": { "latitude": 42.109999450000004, @@ -1999,7 +3175,7 @@ } }, { - "uid": "fiber (Chicago \u2192 Milwaukee)-", + "uid": "fiber (Chicago → Milwaukee)-", "metadata": { "location": { "latitude": 42.44999915, @@ -2017,7 +3193,7 @@ } }, { - "uid": "fiber (Chicago \u2192 Springfield)-", + "uid": "fiber (Chicago → Springfield)-", "metadata": { "location": { "latitude": 40.6699985, @@ -2035,7 +3211,7 @@ } }, { - "uid": "fiber (Cincinnati \u2192 Columbus)-", + "uid": "fiber (Cincinnati → Columbus)-", "metadata": { "location": { "latitude": 39.56500054999999, @@ -2053,7 +3229,7 @@ } }, { - "uid": "fiber (Cincinnati \u2192 Louisville)-", + "uid": "fiber (Cincinnati → Louisville)-", "metadata": { "location": { "latitude": 38.68, @@ -2071,7 +3247,7 @@ } }, { - "uid": "fiber (Cincinnati \u2192 Washington_DC)-", + "uid": "fiber (Cincinnati → Washington_DC)-", "metadata": { "location": { "latitude": 39.024999699999995, @@ -2089,7 +3265,7 @@ } }, { - "uid": "fiber (Cleveland \u2192 Columbus)-", + "uid": "fiber (Cleveland → Columbus)-", "metadata": { "location": { "latitude": 40.7350006, @@ -2107,7 +3283,7 @@ } }, { - "uid": "fiber (Cleveland \u2192 Toledo)-", + "uid": "fiber (Cleveland → Toledo)-", "metadata": { "location": { "latitude": 41.5699981, @@ -2125,7 +3301,7 @@ } }, { - "uid": "fiber (Columbus \u2192 Pittsburgh)-", + "uid": "fiber (Columbus → Pittsburgh)-", "metadata": { "location": { "latitude": 40.14500099999999, @@ -2143,7 +3319,7 @@ } }, { - "uid": "fiber (Dallas \u2192 Houston)-", + "uid": "fiber (Dallas → Houston)-", "metadata": { "location": { "latitude": 31.28, @@ -2161,7 +3337,7 @@ } }, { - "uid": "fiber (Dallas \u2192 Little_Rock)-", + "uid": "fiber (Dallas → Little_Rock)-", "metadata": { "location": { "latitude": 33.754999999999995, @@ -2179,7 +3355,7 @@ } }, { - "uid": "fiber (Dallas \u2192 Oklahoma_City)-", + "uid": "fiber (Dallas → Oklahoma_City)-", "metadata": { "location": { "latitude": 34.13000075, @@ -2197,7 +3373,7 @@ } }, { - "uid": "fiber (Delhi \u2192 Istanbul)-", + "uid": "fiber (Delhi → Istanbul)-", "metadata": { "location": { "latitude": 34.88500015, @@ -2215,7 +3391,7 @@ } }, { - "uid": "fiber (Delhi \u2192 Mumbai)-", + "uid": "fiber (Delhi → Mumbai)-", "metadata": { "location": { "latitude": 23.8149995, @@ -2233,7 +3409,7 @@ } }, { - "uid": "fiber (Denver \u2192 Omaha)-", + "uid": "fiber (Denver → Omaha)-", "metadata": { "location": { "latitude": 40.515000555, @@ -2251,7 +3427,7 @@ } }, { - "uid": "fiber (Denver \u2192 Salt_Lake_City)-", + "uid": "fiber (Denver → Salt_Lake_City)-", "metadata": { "location": { "latitude": 40.27500067, @@ -2269,7 +3445,7 @@ } }, { - "uid": "fiber (Detroit \u2192 Toledo)-", + "uid": "fiber (Detroit → Toledo)-", "metadata": { "location": { "latitude": 42.01999945, @@ -2287,7 +3463,7 @@ } }, { - "uid": "fiber (El_Paso \u2192 San_Antonio)-", + "uid": "fiber (El_Paso → San_Antonio)-", "metadata": { "location": { "latitude": 30.654903500000003, @@ -2305,7 +3481,7 @@ } }, { - "uid": "fiber (El_Paso \u2192 Tucson)-", + "uid": "fiber (El_Paso → Tucson)-", "metadata": { "location": { "latitude": 32.024905000000004, @@ -2323,7 +3499,7 @@ } }, { - "uid": "fiber (Frankfurt \u2192 Vienna)-", + "uid": "fiber (Frankfurt → Vienna)-", "metadata": { "location": { "latitude": 49.1700008, @@ -2341,7 +3517,7 @@ } }, { - "uid": "fiber (Fresno \u2192 Las_Vegas)-", + "uid": "fiber (Fresno → Las_Vegas)-", "metadata": { "location": { "latitude": 36.494995349999996, @@ -2359,7 +3535,7 @@ } }, { - "uid": "fiber (Fresno \u2192 Los_Angeles)-", + "uid": "fiber (Fresno → Los_Angeles)-", "metadata": { "location": { "latitude": 35.44500085, @@ -2377,7 +3553,7 @@ } }, { - "uid": "fiber (Fresno \u2192 Oakland)-", + "uid": "fiber (Fresno → Oakland)-", "metadata": { "location": { "latitude": 37.275000705, @@ -2395,7 +3571,7 @@ } }, { - "uid": "fiber (Greensboro \u2192 Louisville)-", + "uid": "fiber (Greensboro → Louisville)-", "metadata": { "location": { "latitude": 37.15000165, @@ -2413,7 +3589,7 @@ } }, { - "uid": "fiber (Greensboro \u2192 Raleigh)-", + "uid": "fiber (Greensboro → Raleigh)-", "metadata": { "location": { "latitude": 35.95000095, @@ -2431,7 +3607,7 @@ } }, { - "uid": "fiber (Greensboro \u2192 Richmond)-", + "uid": "fiber (Greensboro → Richmond)-", "metadata": { "location": { "latitude": 36.8050005, @@ -2449,7 +3625,7 @@ } }, { - "uid": "fiber (Hartford \u2192 Long_Island)-", + "uid": "fiber (Hartford → Long_Island)-", "metadata": { "location": { "latitude": 41.18000015, @@ -2467,7 +3643,7 @@ } }, { - "uid": "fiber (Hartford \u2192 Providence)-", + "uid": "fiber (Hartford → Providence)-", "metadata": { "location": { "latitude": 41.795000200000004, @@ -2485,7 +3661,7 @@ } }, { - "uid": "fiber (Hong_Kong \u2192 Shanghai)-", + "uid": "fiber (Hong_Kong → Shanghai)-", "metadata": { "location": { "latitude": 26.7485, @@ -2503,7 +3679,7 @@ } }, { - "uid": "fiber (Hong_Kong \u2192 Sydney)-", + "uid": "fiber (Hong_Kong → Sydney)-", "metadata": { "location": { "latitude": -5.801499479999999, @@ -2521,7 +3697,7 @@ } }, { - "uid": "fiber (Hong_Kong \u2192 Taipei)-", + "uid": "fiber (Hong_Kong → Taipei)-", "metadata": { "location": { "latitude": 23.64350025, @@ -2539,7 +3715,7 @@ } }, { - "uid": "fiber (Honolulu \u2192 Los_Angeles)-", + "uid": "fiber (Honolulu → Los_Angeles)-", "metadata": { "location": { "latitude": 27.7150003, @@ -2557,7 +3733,7 @@ } }, { - "uid": "fiber (Honolulu \u2192 Sydney)-", + "uid": "fiber (Honolulu → Sydney)-", "metadata": { "location": { "latitude": -6.274999679999999, @@ -2575,7 +3751,7 @@ } }, { - "uid": "fiber (Honolulu \u2192 Taipei)-", + "uid": "fiber (Honolulu → Taipei)-", "metadata": { "location": { "latitude": 23.17000005, @@ -2593,7 +3769,7 @@ } }, { - "uid": "fiber (Istanbul \u2192 Rome)-", + "uid": "fiber (Istanbul → Rome)-", "metadata": { "location": { "latitude": 41.4949998, @@ -2611,7 +3787,7 @@ } }, { - "uid": "fiber (Jacksonville \u2192 Orlando)-", + "uid": "fiber (Jacksonville → Orlando)-", "metadata": { "location": { "latitude": 29.4150012, @@ -2629,7 +3805,7 @@ } }, { - "uid": "fiber (Kansas_City \u2192 Omaha)-", + "uid": "fiber (Kansas_City → Omaha)-", "metadata": { "location": { "latitude": 40.1899988, @@ -2647,7 +3823,7 @@ } }, { - "uid": "fiber (Kansas_City \u2192 St_Louis)-", + "uid": "fiber (Kansas_City → St_Louis)-", "metadata": { "location": { "latitude": 38.879999600000005, @@ -2665,7 +3841,7 @@ } }, { - "uid": "fiber (Kansas_City \u2192 Tulsa)-", + "uid": "fiber (Kansas_City → Tulsa)-", "metadata": { "location": { "latitude": 37.6249996, @@ -2683,7 +3859,7 @@ } }, { - "uid": "fiber (Las_Vegas \u2192 Phoenix)-", + "uid": "fiber (Las_Vegas → Phoenix)-", "metadata": { "location": { "latitude": 34.87499529, @@ -2701,7 +3877,7 @@ } }, { - "uid": "fiber (Las_Vegas \u2192 Salt_Lake_City)-", + "uid": "fiber (Las_Vegas → Salt_Lake_City)-", "metadata": { "location": { "latitude": 38.494994315, @@ -2719,7 +3895,7 @@ } }, { - "uid": "fiber (Little_Rock \u2192 Memphis)-", + "uid": "fiber (Little_Rock → Memphis)-", "metadata": { "location": { "latitude": 34.9150005, @@ -2737,7 +3913,7 @@ } }, { - "uid": "fiber (London \u2192 Paris)-", + "uid": "fiber (London → Paris)-", "metadata": { "location": { "latitude": 50.19000025, @@ -2755,7 +3931,7 @@ } }, { - "uid": "fiber (London \u2192 Washington_DC)-", + "uid": "fiber (London → Washington_DC)-", "metadata": { "location": { "latitude": 45.2150004, @@ -2773,7 +3949,7 @@ } }, { - "uid": "fiber (Long_Island \u2192 New_York)-", + "uid": "fiber (Long_Island → New_York)-", "metadata": { "location": { "latitude": 40.629999100000006, @@ -2791,7 +3967,7 @@ } }, { - "uid": "fiber (Los_Angeles \u2192 San_Diego)-", + "uid": "fiber (Los_Angeles → San_Diego)-", "metadata": { "location": { "latitude": 33.46000135, @@ -2809,7 +3985,7 @@ } }, { - "uid": "fiber (Los_Angeles \u2192 Santa_Barbara)-", + "uid": "fiber (Los_Angeles → Santa_Barbara)-", "metadata": { "location": { "latitude": 34.270000605, @@ -2827,7 +4003,7 @@ } }, { - "uid": "fiber (Louisville \u2192 Nashville)-", + "uid": "fiber (Louisville → Nashville)-", "metadata": { "location": { "latitude": 37.19499965, @@ -2845,7 +4021,7 @@ } }, { - "uid": "fiber (Louisville \u2192 St_Louis)-", + "uid": "fiber (Louisville → St_Louis)-", "metadata": { "location": { "latitude": 38.43000045, @@ -2863,7 +4039,7 @@ } }, { - "uid": "fiber (Madrid \u2192 Paris)-", + "uid": "fiber (Madrid → Paris)-", "metadata": { "location": { "latitude": 44.639999, @@ -2881,7 +4057,7 @@ } }, { - "uid": "fiber (Madrid \u2192 Zurich)-", + "uid": "fiber (Madrid → Zurich)-", "metadata": { "location": { "latitude": 43.89999975, @@ -2899,7 +4075,7 @@ } }, { - "uid": "fiber (Memphis \u2192 Nashville)-", + "uid": "fiber (Memphis → Nashville)-", "metadata": { "location": { "latitude": 35.6399997, @@ -2917,7 +4093,7 @@ } }, { - "uid": "fiber (Miami \u2192 Paris)-", + "uid": "fiber (Miami → Paris)-", "metadata": { "location": { "latitude": 37.320000300000004, @@ -2935,7 +4111,7 @@ } }, { - "uid": "fiber (Miami \u2192 Tampa)-", + "uid": "fiber (Miami → Tampa)-", "metadata": { "location": { "latitude": 26.8699997, @@ -2953,7 +4129,7 @@ } }, { - "uid": "fiber (Miami \u2192 West_Palm_Beach)-", + "uid": "fiber (Miami → West_Palm_Beach)-", "metadata": { "location": { "latitude": 26.26500015, @@ -2971,7 +4147,7 @@ } }, { - "uid": "fiber (Milwaukee \u2192 Minneapolis)-", + "uid": "fiber (Milwaukee → Minneapolis)-", "metadata": { "location": { "latitude": 44.01000005, @@ -2989,7 +4165,7 @@ } }, { - "uid": "fiber (Minneapolis \u2192 Omaha)-", + "uid": "fiber (Minneapolis → Omaha)-", "metadata": { "location": { "latitude": 43.1099986, @@ -3007,7 +4183,7 @@ } }, { - "uid": "fiber (Mumbai \u2192 Rome)-", + "uid": "fiber (Mumbai → Rome)-", "metadata": { "location": { "latitude": 30.42499915, @@ -3025,7 +4201,7 @@ } }, { - "uid": "fiber (Mumbai \u2192 Singapore)-", + "uid": "fiber (Mumbai → Singapore)-", "metadata": { "location": { "latitude": 10.1299993035, @@ -3043,7 +4219,7 @@ } }, { - "uid": "fiber (New_Orleans \u2192 Tallahassee)-", + "uid": "fiber (New_Orleans → Tallahassee)-", "metadata": { "location": { "latitude": 30.265, @@ -3061,7 +4237,7 @@ } }, { - "uid": "fiber (New_York \u2192 Newark)-", + "uid": "fiber (New_York → Newark)-", "metadata": { "location": { "latitude": 40.69499975, @@ -3079,7 +4255,7 @@ } }, { - "uid": "fiber (New_York \u2192 Scranton)-", + "uid": "fiber (New_York → Scranton)-", "metadata": { "location": { "latitude": 41.034999150000004, @@ -3097,7 +4273,7 @@ } }, { - "uid": "fiber (New_York \u2192 Wilmington)-", + "uid": "fiber (New_York → Wilmington)-", "metadata": { "location": { "latitude": 40.20500005, @@ -3115,7 +4291,7 @@ } }, { - "uid": "fiber (Newark \u2192 Philadelphia)-", + "uid": "fiber (Newark → Philadelphia)-", "metadata": { "location": { "latitude": 40.364999850000004, @@ -3133,7 +4309,7 @@ } }, { - "uid": "fiber (Norfolk \u2192 Raleigh)-", + "uid": "fiber (Norfolk → Raleigh)-", "metadata": { "location": { "latitude": 36.36999885, @@ -3151,7 +4327,7 @@ } }, { - "uid": "fiber (Norfolk \u2192 Wilmington)-", + "uid": "fiber (Norfolk → Wilmington)-", "metadata": { "location": { "latitude": 38.33, @@ -3169,7 +4345,7 @@ } }, { - "uid": "fiber (Oakland \u2192 Sacramento)-", + "uid": "fiber (Oakland → Sacramento)-", "metadata": { "location": { "latitude": 38.170000085, @@ -3187,7 +4363,7 @@ } }, { - "uid": "fiber (Oakland \u2192 Salt_Lake_City)-", + "uid": "fiber (Oakland → Salt_Lake_City)-", "metadata": { "location": { "latitude": 39.27499967, @@ -3205,7 +4381,7 @@ } }, { - "uid": "fiber (Oakland \u2192 San_Francisco)-", + "uid": "fiber (Oakland → San_Francisco)-", "metadata": { "location": { "latitude": 37.715000065, @@ -3223,7 +4399,7 @@ } }, { - "uid": "fiber (Oakland \u2192 Taipei)-", + "uid": "fiber (Oakland → Taipei)-", "metadata": { "location": { "latitude": 31.395000605, @@ -3241,7 +4417,7 @@ } }, { - "uid": "fiber (Oklahoma_City \u2192 Tulsa)-", + "uid": "fiber (Oklahoma_City → Tulsa)-", "metadata": { "location": { "latitude": 35.80000075, @@ -3259,7 +4435,7 @@ } }, { - "uid": "fiber (Orlando \u2192 West_Palm_Beach)-", + "uid": "fiber (Orlando → West_Palm_Beach)-", "metadata": { "location": { "latitude": 27.62499955, @@ -3277,7 +4453,7 @@ } }, { - "uid": "fiber (Philadelphia \u2192 Scranton)-", + "uid": "fiber (Philadelphia → Scranton)-", "metadata": { "location": { "latitude": 40.70499925, @@ -3295,7 +4471,7 @@ } }, { - "uid": "fiber (Phoenix \u2192 San_Diego)-", + "uid": "fiber (Phoenix → San_Diego)-", "metadata": { "location": { "latitude": 33.17500114, @@ -3313,7 +4489,7 @@ } }, { - "uid": "fiber (Phoenix \u2192 Tucson)-", + "uid": "fiber (Phoenix → Tucson)-", "metadata": { "location": { "latitude": 32.87000029, @@ -3331,7 +4507,7 @@ } }, { - "uid": "fiber (Pittsburgh \u2192 Scranton)-", + "uid": "fiber (Pittsburgh → Scranton)-", "metadata": { "location": { "latitude": 40.849999999999994, @@ -3349,7 +4525,7 @@ } }, { - "uid": "fiber (Portland \u2192 Sacramento)-", + "uid": "fiber (Portland → Sacramento)-", "metadata": { "location": { "latitude": 42.05500009, @@ -3367,7 +4543,7 @@ } }, { - "uid": "fiber (Portland \u2192 Salt_Lake_City)-", + "uid": "fiber (Portland → Salt_Lake_City)-", "metadata": { "location": { "latitude": 43.159999675, @@ -3385,7 +4561,7 @@ } }, { - "uid": "fiber (Portland \u2192 Seattle)-", + "uid": "fiber (Portland → Seattle)-", "metadata": { "location": { "latitude": 46.57999994, @@ -3403,7 +4579,7 @@ } }, { - "uid": "fiber (Portland \u2192 Tokyo)-", + "uid": "fiber (Portland → Tokyo)-", "metadata": { "location": { "latitude": 40.604999660000004, @@ -3421,7 +4597,7 @@ } }, { - "uid": "fiber (Richmond \u2192 Washington_DC)-", + "uid": "fiber (Richmond → Washington_DC)-", "metadata": { "location": { "latitude": 38.21999945, @@ -3439,7 +4615,7 @@ } }, { - "uid": "fiber (Rochester \u2192 Syracuse)-", + "uid": "fiber (Rochester → Syracuse)-", "metadata": { "location": { "latitude": 43.10499975, @@ -3457,7 +4633,7 @@ } }, { - "uid": "fiber (Rome \u2192 Vienna)-", + "uid": "fiber (Rome → Vienna)-", "metadata": { "location": { "latitude": 45.055001000000004, @@ -3475,7 +4651,7 @@ } }, { - "uid": "fiber (Rome \u2192 Zurich)-", + "uid": "fiber (Rome → Zurich)-", "metadata": { "location": { "latitude": 44.63500055, @@ -3493,7 +4669,7 @@ } }, { - "uid": "fiber (San_Francisco \u2192 San_Jose)-", + "uid": "fiber (San_Francisco → San_Jose)-", "metadata": { "location": { "latitude": 37.479999445000004, @@ -3511,7 +4687,7 @@ } }, { - "uid": "fiber (San_Jose \u2192 Santa_Barbara)-", + "uid": "fiber (San_Jose → Santa_Barbara)-", "metadata": { "location": { "latitude": 35.86499984, @@ -3529,7 +4705,7 @@ } }, { - "uid": "fiber (Scranton \u2192 Syracuse)-", + "uid": "fiber (Scranton → Syracuse)-", "metadata": { "location": { "latitude": 42.2200005, @@ -3547,7 +4723,7 @@ } }, { - "uid": "fiber (Seattle \u2192 Spokane)-", + "uid": "fiber (Seattle → Spokane)-", "metadata": { "location": { "latitude": 47.644998605, @@ -3565,7 +4741,7 @@ } }, { - "uid": "fiber (Seoul \u2192 Tokyo)-", + "uid": "fiber (Seoul → Tokyo)-", "metadata": { "location": { "latitude": 36.614999839999996, @@ -3583,7 +4759,7 @@ } }, { - "uid": "fiber (Singapore \u2192 Sydney)-", + "uid": "fiber (Singapore → Sydney)-", "metadata": { "location": { "latitude": -16.2849995265, @@ -3601,7 +4777,7 @@ } }, { - "uid": "fiber (Springfield \u2192 St_Louis)-", + "uid": "fiber (Springfield → St_Louis)-", "metadata": { "location": { "latitude": 39.07, @@ -3619,7 +4795,7 @@ } }, { - "uid": "fiber (Taipei \u2192 Tokyo)-", + "uid": "fiber (Taipei → Tokyo)-", "metadata": { "location": { "latitude": 30.344999549999997, @@ -3637,7 +4813,7 @@ } }, { - "uid": "fiber (Tallahassee \u2192 Tampa)-", + "uid": "fiber (Tallahassee → Tampa)-", "metadata": { "location": { "latitude": 29.2099994, @@ -3655,7 +4831,7 @@ } }, { - "uid": "fiber (Vienna \u2192 Warsaw)-", + "uid": "fiber (Vienna → Warsaw)-", "metadata": { "location": { "latitude": 50.24000055, @@ -3673,7 +4849,7 @@ } }, { - "uid": "fiber (Dallas \u2192 Abilene)-", + "uid": "fiber (Dallas → Abilene)-", "metadata": { "location": { "latitude": 32.620000000000005, @@ -3691,7 +4867,7 @@ } }, { - "uid": "fiber (El_Paso \u2192 Abilene)-", + "uid": "fiber (El_Paso → Abilene)-", "metadata": { "location": { "latitude": 32.149905000000004, @@ -3709,7 +4885,7 @@ } }, { - "uid": "fiber (Boston \u2192 Albany)-", + "uid": "fiber (Boston → Albany)-", "metadata": { "location": { "latitude": 42.504999350000006, @@ -3727,7 +4903,7 @@ } }, { - "uid": "fiber (Syracuse \u2192 Albany)-", + "uid": "fiber (Syracuse → Albany)-", "metadata": { "location": { "latitude": 42.8549996, @@ -3745,7 +4921,7 @@ } }, { - "uid": "fiber (Dallas \u2192 Albuquerque)-", + "uid": "fiber (Dallas → Albuquerque)-", "metadata": { "location": { "latitude": 33.9549885, @@ -3763,7 +4939,7 @@ } }, { - "uid": "fiber (Denver \u2192 Albuquerque)-", + "uid": "fiber (Denver → Albuquerque)-", "metadata": { "location": { "latitude": 37.444989855, @@ -3781,7 +4957,7 @@ } }, { - "uid": "fiber (El_Paso \u2192 Albuquerque)-", + "uid": "fiber (El_Paso → Albuquerque)-", "metadata": { "location": { "latitude": 33.4848935, @@ -3799,7 +4975,7 @@ } }, { - "uid": "fiber (Las_Vegas \u2192 Albuquerque)-", + "uid": "fiber (Las_Vegas → Albuquerque)-", "metadata": { "location": { "latitude": 35.6649835, @@ -3817,7 +4993,7 @@ } }, { - "uid": "fiber (Berlin \u2192 Amsterdam)-", + "uid": "fiber (Berlin → Amsterdam)-", "metadata": { "location": { "latitude": 52.4450008, @@ -3835,7 +5011,7 @@ } }, { - "uid": "fiber (Brussels \u2192 Amsterdam)-", + "uid": "fiber (Brussels → Amsterdam)-", "metadata": { "location": { "latitude": 51.600000800000004, @@ -3853,7 +5029,7 @@ } }, { - "uid": "fiber (Frankfurt \u2192 Amsterdam)-", + "uid": "fiber (Frankfurt → Amsterdam)-", "metadata": { "location": { "latitude": 51.2449994, @@ -3871,7 +5047,7 @@ } }, { - "uid": "fiber (New_York \u2192 Amsterdam)-", + "uid": "fiber (New_York → Amsterdam)-", "metadata": { "location": { "latitude": 46.51999895, @@ -3889,7 +5065,7 @@ } }, { - "uid": "fiber (Birmingham \u2192 Atlanta)-", + "uid": "fiber (Birmingham → Atlanta)-", "metadata": { "location": { "latitude": 33.644998349999995, @@ -3907,7 +5083,7 @@ } }, { - "uid": "fiber (Charlotte \u2192 Atlanta)-", + "uid": "fiber (Charlotte → Atlanta)-", "metadata": { "location": { "latitude": 34.4799991, @@ -3925,7 +5101,7 @@ } }, { - "uid": "fiber (Jacksonville \u2192 Atlanta)-", + "uid": "fiber (Jacksonville → Atlanta)-", "metadata": { "location": { "latitude": 32.0450006, @@ -3943,7 +5119,7 @@ } }, { - "uid": "fiber (Houston \u2192 Austin)-", + "uid": "fiber (Houston → Austin)-", "metadata": { "location": { "latitude": 30.0399994, @@ -3961,7 +5137,7 @@ } }, { - "uid": "fiber (San_Antonio \u2192 Austin)-", + "uid": "fiber (San_Antonio → Austin)-", "metadata": { "location": { "latitude": 29.884997900000002, @@ -3979,7 +5155,7 @@ } }, { - "uid": "fiber (Philadelphia \u2192 Baltimore)-", + "uid": "fiber (Philadelphia → Baltimore)-", "metadata": { "location": { "latitude": 39.65499885, @@ -3997,7 +5173,7 @@ } }, { - "uid": "fiber (Pittsburgh \u2192 Baltimore)-", + "uid": "fiber (Pittsburgh → Baltimore)-", "metadata": { "location": { "latitude": 39.7999996, @@ -4015,7 +5191,7 @@ } }, { - "uid": "fiber (Washington_DC \u2192 Baltimore)-", + "uid": "fiber (Washington_DC → Baltimore)-", "metadata": { "location": { "latitude": 39.104999750000005, @@ -4033,7 +5209,7 @@ } }, { - "uid": "fiber (Delhi \u2192 Bangkok)-", + "uid": "fiber (Delhi → Bangkok)-", "metadata": { "location": { "latitude": 21.20000015, @@ -4051,7 +5227,7 @@ } }, { - "uid": "fiber (Hong_Kong \u2192 Bangkok)-", + "uid": "fiber (Hong_Kong → Bangkok)-", "metadata": { "location": { "latitude": 17.9985, @@ -4069,7 +5245,7 @@ } }, { - "uid": "fiber (Houston \u2192 Baton_Rouge)-", + "uid": "fiber (Houston → Baton_Rouge)-", "metadata": { "location": { "latitude": 30.1099998, @@ -4087,7 +5263,7 @@ } }, { - "uid": "fiber (New_Orleans \u2192 Baton_Rouge)-", + "uid": "fiber (New_Orleans → Baton_Rouge)-", "metadata": { "location": { "latitude": 30.259999800000003, @@ -4105,7 +5281,7 @@ } }, { - "uid": "fiber (Seoul \u2192 Beijing)-", + "uid": "fiber (Seoul → Beijing)-", "metadata": { "location": { "latitude": 38.745000434999994, @@ -4123,7 +5299,7 @@ } }, { - "uid": "fiber (Shanghai \u2192 Beijing)-", + "uid": "fiber (Shanghai → Beijing)-", "metadata": { "location": { "latitude": 35.579999895, @@ -4141,7 +5317,7 @@ } }, { - "uid": "fiber (Warsaw \u2192 Berlin)-", + "uid": "fiber (Warsaw → Berlin)-", "metadata": { "location": { "latitude": 52.390000349999994, @@ -4159,7 +5335,7 @@ } }, { - "uid": "fiber (Bismarck \u2192 Billings)-", + "uid": "fiber (Bismarck → Billings)-", "metadata": { "location": { "latitude": 46.30000129, @@ -4177,7 +5353,7 @@ } }, { - "uid": "fiber (Denver \u2192 Billings)-", + "uid": "fiber (Denver → Billings)-", "metadata": { "location": { "latitude": 42.780001874999996, @@ -4195,7 +5371,7 @@ } }, { - "uid": "fiber (Spokane \u2192 Billings)-", + "uid": "fiber (Spokane → Billings)-", "metadata": { "location": { "latitude": 46.729999545, @@ -4213,7 +5389,7 @@ } }, { - "uid": "fiber (Nashville \u2192 Birmingham)-", + "uid": "fiber (Nashville → Birmingham)-", "metadata": { "location": { "latitude": 34.84999845, @@ -4231,7 +5407,7 @@ } }, { - "uid": "fiber (New_Orleans \u2192 Birmingham)-", + "uid": "fiber (New_Orleans → Birmingham)-", "metadata": { "location": { "latitude": 31.79999925, @@ -4249,7 +5425,7 @@ } }, { - "uid": "fiber (Minneapolis \u2192 Bismarck)-", + "uid": "fiber (Minneapolis → Bismarck)-", "metadata": { "location": { "latitude": 45.88500017, @@ -4267,7 +5443,7 @@ } }, { - "uid": "fiber (Providence \u2192 Boston)-", + "uid": "fiber (Providence → Boston)-", "metadata": { "location": { "latitude": 42.08000025, @@ -4285,7 +5461,7 @@ } }, { - "uid": "fiber (London \u2192 Brussels)-", + "uid": "fiber (London → Brussels)-", "metadata": { "location": { "latitude": 51.17500125, @@ -4303,7 +5479,7 @@ } }, { - "uid": "fiber (Istanbul \u2192 Bucharest)-", + "uid": "fiber (Istanbul → Bucharest)-", "metadata": { "location": { "latitude": 42.769999999999996, @@ -4321,7 +5497,7 @@ } }, { - "uid": "fiber (Warsaw \u2192 Bucharest)-", + "uid": "fiber (Warsaw → Bucharest)-", "metadata": { "location": { "latitude": 48.34999935, @@ -4339,7 +5515,7 @@ } }, { - "uid": "fiber (Cleveland \u2192 Buffalo)-", + "uid": "fiber (Cleveland → Buffalo)-", "metadata": { "location": { "latitude": 42.184999250000004, @@ -4357,7 +5533,7 @@ } }, { - "uid": "fiber (Rochester \u2192 Buffalo)-", + "uid": "fiber (Rochester → Buffalo)-", "metadata": { "location": { "latitude": 43.029998899999995, @@ -4375,7 +5551,7 @@ } }, { - "uid": "fiber (Jacksonville \u2192 Charleston)-", + "uid": "fiber (Jacksonville → Charleston)-", "metadata": { "location": { "latitude": 31.560001900000003, @@ -4393,7 +5569,7 @@ } }, { - "uid": "fiber (Raleigh \u2192 Charleston)-", + "uid": "fiber (Raleigh → Charleston)-", "metadata": { "location": { "latitude": 34.30500015, @@ -4411,7 +5587,7 @@ } }, { - "uid": "fiber (Greensboro \u2192 Charlotte)-", + "uid": "fiber (Greensboro → Charlotte)-", "metadata": { "location": { "latitude": 35.6400012, @@ -4429,7 +5605,7 @@ } }, { - "uid": "fiber (Detroit \u2192 Chicago)-", + "uid": "fiber (Detroit → Chicago)-", "metadata": { "location": { "latitude": 42.109999450000004, @@ -4447,7 +5623,7 @@ } }, { - "uid": "fiber (Milwaukee \u2192 Chicago)-", + "uid": "fiber (Milwaukee → Chicago)-", "metadata": { "location": { "latitude": 42.44999915, @@ -4465,7 +5641,7 @@ } }, { - "uid": "fiber (Springfield \u2192 Chicago)-", + "uid": "fiber (Springfield → Chicago)-", "metadata": { "location": { "latitude": 40.6699985, @@ -4483,7 +5659,7 @@ } }, { - "uid": "fiber (Columbus \u2192 Cincinnati)-", + "uid": "fiber (Columbus → Cincinnati)-", "metadata": { "location": { "latitude": 39.56500054999999, @@ -4501,7 +5677,7 @@ } }, { - "uid": "fiber (Louisville \u2192 Cincinnati)-", + "uid": "fiber (Louisville → Cincinnati)-", "metadata": { "location": { "latitude": 38.68, @@ -4519,7 +5695,7 @@ } }, { - "uid": "fiber (Washington_DC \u2192 Cincinnati)-", + "uid": "fiber (Washington_DC → Cincinnati)-", "metadata": { "location": { "latitude": 39.024999699999995, @@ -4537,7 +5713,7 @@ } }, { - "uid": "fiber (Columbus \u2192 Cleveland)-", + "uid": "fiber (Columbus → Cleveland)-", "metadata": { "location": { "latitude": 40.7350006, @@ -4555,7 +5731,7 @@ } }, { - "uid": "fiber (Toledo \u2192 Cleveland)-", + "uid": "fiber (Toledo → Cleveland)-", "metadata": { "location": { "latitude": 41.5699981, @@ -4573,7 +5749,7 @@ } }, { - "uid": "fiber (Pittsburgh \u2192 Columbus)-", + "uid": "fiber (Pittsburgh → Columbus)-", "metadata": { "location": { "latitude": 40.14500099999999, @@ -4591,7 +5767,7 @@ } }, { - "uid": "fiber (Houston \u2192 Dallas)-", + "uid": "fiber (Houston → Dallas)-", "metadata": { "location": { "latitude": 31.28, @@ -4609,7 +5785,7 @@ } }, { - "uid": "fiber (Little_Rock \u2192 Dallas)-", + "uid": "fiber (Little_Rock → Dallas)-", "metadata": { "location": { "latitude": 33.754999999999995, @@ -4627,7 +5803,7 @@ } }, { - "uid": "fiber (Oklahoma_City \u2192 Dallas)-", + "uid": "fiber (Oklahoma_City → Dallas)-", "metadata": { "location": { "latitude": 34.13000075, @@ -4645,7 +5821,7 @@ } }, { - "uid": "fiber (Istanbul \u2192 Delhi)-", + "uid": "fiber (Istanbul → Delhi)-", "metadata": { "location": { "latitude": 34.88500015, @@ -4663,7 +5839,7 @@ } }, { - "uid": "fiber (Mumbai \u2192 Delhi)-", + "uid": "fiber (Mumbai → Delhi)-", "metadata": { "location": { "latitude": 23.8149995, @@ -4681,7 +5857,7 @@ } }, { - "uid": "fiber (Omaha \u2192 Denver)-", + "uid": "fiber (Omaha → Denver)-", "metadata": { "location": { "latitude": 40.515000555, @@ -4699,7 +5875,7 @@ } }, { - "uid": "fiber (Salt_Lake_City \u2192 Denver)-", + "uid": "fiber (Salt_Lake_City → Denver)-", "metadata": { "location": { "latitude": 40.27500067, @@ -4717,7 +5893,7 @@ } }, { - "uid": "fiber (Toledo \u2192 Detroit)-", + "uid": "fiber (Toledo → Detroit)-", "metadata": { "location": { "latitude": 42.01999945, @@ -4735,7 +5911,7 @@ } }, { - "uid": "fiber (San_Antonio \u2192 El_Paso)-", + "uid": "fiber (San_Antonio → El_Paso)-", "metadata": { "location": { "latitude": 30.654903500000003, @@ -4753,7 +5929,7 @@ } }, { - "uid": "fiber (Tucson \u2192 El_Paso)-", + "uid": "fiber (Tucson → El_Paso)-", "metadata": { "location": { "latitude": 32.024905000000004, @@ -4771,7 +5947,7 @@ } }, { - "uid": "fiber (Vienna \u2192 Frankfurt)-", + "uid": "fiber (Vienna → Frankfurt)-", "metadata": { "location": { "latitude": 49.1700008, @@ -4789,7 +5965,7 @@ } }, { - "uid": "fiber (Las_Vegas \u2192 Fresno)-", + "uid": "fiber (Las_Vegas → Fresno)-", "metadata": { "location": { "latitude": 36.494995349999996, @@ -4807,7 +5983,7 @@ } }, { - "uid": "fiber (Los_Angeles \u2192 Fresno)-", + "uid": "fiber (Los_Angeles → Fresno)-", "metadata": { "location": { "latitude": 35.44500085, @@ -4825,7 +6001,7 @@ } }, { - "uid": "fiber (Oakland \u2192 Fresno)-", + "uid": "fiber (Oakland → Fresno)-", "metadata": { "location": { "latitude": 37.275000705, @@ -4843,7 +6019,7 @@ } }, { - "uid": "fiber (Louisville \u2192 Greensboro)-", + "uid": "fiber (Louisville → Greensboro)-", "metadata": { "location": { "latitude": 37.15000165, @@ -4861,7 +6037,7 @@ } }, { - "uid": "fiber (Raleigh \u2192 Greensboro)-", + "uid": "fiber (Raleigh → Greensboro)-", "metadata": { "location": { "latitude": 35.95000095, @@ -4879,7 +6055,7 @@ } }, { - "uid": "fiber (Richmond \u2192 Greensboro)-", + "uid": "fiber (Richmond → Greensboro)-", "metadata": { "location": { "latitude": 36.8050005, @@ -4897,7 +6073,7 @@ } }, { - "uid": "fiber (Long_Island \u2192 Hartford)-", + "uid": "fiber (Long_Island → Hartford)-", "metadata": { "location": { "latitude": 41.18000015, @@ -4915,7 +6091,7 @@ } }, { - "uid": "fiber (Providence \u2192 Hartford)-", + "uid": "fiber (Providence → Hartford)-", "metadata": { "location": { "latitude": 41.795000200000004, @@ -4933,7 +6109,7 @@ } }, { - "uid": "fiber (Shanghai \u2192 Hong_Kong)-", + "uid": "fiber (Shanghai → Hong_Kong)-", "metadata": { "location": { "latitude": 26.7485, @@ -4951,7 +6127,7 @@ } }, { - "uid": "fiber (Sydney \u2192 Hong_Kong)-", + "uid": "fiber (Sydney → Hong_Kong)-", "metadata": { "location": { "latitude": -5.801499479999999, @@ -4969,7 +6145,7 @@ } }, { - "uid": "fiber (Taipei \u2192 Hong_Kong)-", + "uid": "fiber (Taipei → Hong_Kong)-", "metadata": { "location": { "latitude": 23.64350025, @@ -4987,7 +6163,7 @@ } }, { - "uid": "fiber (Los_Angeles \u2192 Honolulu)-", + "uid": "fiber (Los_Angeles → Honolulu)-", "metadata": { "location": { "latitude": 27.7150003, @@ -5005,7 +6181,7 @@ } }, { - "uid": "fiber (Sydney \u2192 Honolulu)-", + "uid": "fiber (Sydney → Honolulu)-", "metadata": { "location": { "latitude": -6.274999679999999, @@ -5023,7 +6199,7 @@ } }, { - "uid": "fiber (Taipei \u2192 Honolulu)-", + "uid": "fiber (Taipei → Honolulu)-", "metadata": { "location": { "latitude": 23.17000005, @@ -5041,7 +6217,7 @@ } }, { - "uid": "fiber (Rome \u2192 Istanbul)-", + "uid": "fiber (Rome → Istanbul)-", "metadata": { "location": { "latitude": 41.4949998, @@ -5059,7 +6235,7 @@ } }, { - "uid": "fiber (Orlando \u2192 Jacksonville)-", + "uid": "fiber (Orlando → Jacksonville)-", "metadata": { "location": { "latitude": 29.4150012, @@ -5077,7 +6253,7 @@ } }, { - "uid": "fiber (Omaha \u2192 Kansas_City)-", + "uid": "fiber (Omaha → Kansas_City)-", "metadata": { "location": { "latitude": 40.1899988, @@ -5095,7 +6271,7 @@ } }, { - "uid": "fiber (St_Louis \u2192 Kansas_City)-", + "uid": "fiber (St_Louis → Kansas_City)-", "metadata": { "location": { "latitude": 38.879999600000005, @@ -5113,7 +6289,7 @@ } }, { - "uid": "fiber (Tulsa \u2192 Kansas_City)-", + "uid": "fiber (Tulsa → Kansas_City)-", "metadata": { "location": { "latitude": 37.6249996, @@ -5131,7 +6307,7 @@ } }, { - "uid": "fiber (Phoenix \u2192 Las_Vegas)-", + "uid": "fiber (Phoenix → Las_Vegas)-", "metadata": { "location": { "latitude": 34.87499529, @@ -5149,7 +6325,7 @@ } }, { - "uid": "fiber (Salt_Lake_City \u2192 Las_Vegas)-", + "uid": "fiber (Salt_Lake_City → Las_Vegas)-", "metadata": { "location": { "latitude": 38.494994315, @@ -5167,7 +6343,7 @@ } }, { - "uid": "fiber (Memphis \u2192 Little_Rock)-", + "uid": "fiber (Memphis → Little_Rock)-", "metadata": { "location": { "latitude": 34.9150005, @@ -5185,7 +6361,7 @@ } }, { - "uid": "fiber (Paris \u2192 London)-", + "uid": "fiber (Paris → London)-", "metadata": { "location": { "latitude": 50.19000025, @@ -5203,7 +6379,7 @@ } }, { - "uid": "fiber (Washington_DC \u2192 London)-", + "uid": "fiber (Washington_DC → London)-", "metadata": { "location": { "latitude": 45.2150004, @@ -5221,7 +6397,7 @@ } }, { - "uid": "fiber (New_York \u2192 Long_Island)-", + "uid": "fiber (New_York → Long_Island)-", "metadata": { "location": { "latitude": 40.629999100000006, @@ -5239,7 +6415,7 @@ } }, { - "uid": "fiber (San_Diego \u2192 Los_Angeles)-", + "uid": "fiber (San_Diego → Los_Angeles)-", "metadata": { "location": { "latitude": 33.46000135, @@ -5257,7 +6433,7 @@ } }, { - "uid": "fiber (Santa_Barbara \u2192 Los_Angeles)-", + "uid": "fiber (Santa_Barbara → Los_Angeles)-", "metadata": { "location": { "latitude": 34.270000605, @@ -5275,7 +6451,7 @@ } }, { - "uid": "fiber (Nashville \u2192 Louisville)-", + "uid": "fiber (Nashville → Louisville)-", "metadata": { "location": { "latitude": 37.19499965, @@ -5293,7 +6469,7 @@ } }, { - "uid": "fiber (St_Louis \u2192 Louisville)-", + "uid": "fiber (St_Louis → Louisville)-", "metadata": { "location": { "latitude": 38.43000045, @@ -5311,7 +6487,7 @@ } }, { - "uid": "fiber (Paris \u2192 Madrid)-", + "uid": "fiber (Paris → Madrid)-", "metadata": { "location": { "latitude": 44.639999, @@ -5329,7 +6505,7 @@ } }, { - "uid": "fiber (Zurich \u2192 Madrid)-", + "uid": "fiber (Zurich → Madrid)-", "metadata": { "location": { "latitude": 43.89999975, @@ -5347,7 +6523,7 @@ } }, { - "uid": "fiber (Nashville \u2192 Memphis)-", + "uid": "fiber (Nashville → Memphis)-", "metadata": { "location": { "latitude": 35.6399997, @@ -5365,7 +6541,7 @@ } }, { - "uid": "fiber (Paris \u2192 Miami)-", + "uid": "fiber (Paris → Miami)-", "metadata": { "location": { "latitude": 37.320000300000004, @@ -5383,7 +6559,7 @@ } }, { - "uid": "fiber (Tampa \u2192 Miami)-", + "uid": "fiber (Tampa → Miami)-", "metadata": { "location": { "latitude": 26.8699997, @@ -5401,7 +6577,7 @@ } }, { - "uid": "fiber (West_Palm_Beach \u2192 Miami)-", + "uid": "fiber (West_Palm_Beach → Miami)-", "metadata": { "location": { "latitude": 26.26500015, @@ -5419,7 +6595,7 @@ } }, { - "uid": "fiber (Minneapolis \u2192 Milwaukee)-", + "uid": "fiber (Minneapolis → Milwaukee)-", "metadata": { "location": { "latitude": 44.01000005, @@ -5437,7 +6613,7 @@ } }, { - "uid": "fiber (Omaha \u2192 Minneapolis)-", + "uid": "fiber (Omaha → Minneapolis)-", "metadata": { "location": { "latitude": 43.1099986, @@ -5455,7 +6631,7 @@ } }, { - "uid": "fiber (Rome \u2192 Mumbai)-", + "uid": "fiber (Rome → Mumbai)-", "metadata": { "location": { "latitude": 30.42499915, @@ -5473,7 +6649,7 @@ } }, { - "uid": "fiber (Singapore \u2192 Mumbai)-", + "uid": "fiber (Singapore → Mumbai)-", "metadata": { "location": { "latitude": 10.1299993035, @@ -5491,7 +6667,7 @@ } }, { - "uid": "fiber (Tallahassee \u2192 New_Orleans)-", + "uid": "fiber (Tallahassee → New_Orleans)-", "metadata": { "location": { "latitude": 30.265, @@ -5509,7 +6685,7 @@ } }, { - "uid": "fiber (Newark \u2192 New_York)-", + "uid": "fiber (Newark → New_York)-", "metadata": { "location": { "latitude": 40.69499975, @@ -5527,7 +6703,7 @@ } }, { - "uid": "fiber (Scranton \u2192 New_York)-", + "uid": "fiber (Scranton → New_York)-", "metadata": { "location": { "latitude": 41.034999150000004, @@ -5545,7 +6721,7 @@ } }, { - "uid": "fiber (Wilmington \u2192 New_York)-", + "uid": "fiber (Wilmington → New_York)-", "metadata": { "location": { "latitude": 40.20500005, @@ -5563,7 +6739,7 @@ } }, { - "uid": "fiber (Philadelphia \u2192 Newark)-", + "uid": "fiber (Philadelphia → Newark)-", "metadata": { "location": { "latitude": 40.364999850000004, @@ -5581,7 +6757,7 @@ } }, { - "uid": "fiber (Raleigh \u2192 Norfolk)-", + "uid": "fiber (Raleigh → Norfolk)-", "metadata": { "location": { "latitude": 36.36999885, @@ -5599,7 +6775,7 @@ } }, { - "uid": "fiber (Wilmington \u2192 Norfolk)-", + "uid": "fiber (Wilmington → Norfolk)-", "metadata": { "location": { "latitude": 38.33, @@ -5617,7 +6793,7 @@ } }, { - "uid": "fiber (Sacramento \u2192 Oakland)-", + "uid": "fiber (Sacramento → Oakland)-", "metadata": { "location": { "latitude": 38.170000085, @@ -5635,7 +6811,7 @@ } }, { - "uid": "fiber (Salt_Lake_City \u2192 Oakland)-", + "uid": "fiber (Salt_Lake_City → Oakland)-", "metadata": { "location": { "latitude": 39.27499967, @@ -5653,7 +6829,7 @@ } }, { - "uid": "fiber (San_Francisco \u2192 Oakland)-", + "uid": "fiber (San_Francisco → Oakland)-", "metadata": { "location": { "latitude": 37.715000065, @@ -5671,7 +6847,7 @@ } }, { - "uid": "fiber (Taipei \u2192 Oakland)-", + "uid": "fiber (Taipei → Oakland)-", "metadata": { "location": { "latitude": 31.395000605, @@ -5689,7 +6865,7 @@ } }, { - "uid": "fiber (Tulsa \u2192 Oklahoma_City)-", + "uid": "fiber (Tulsa → Oklahoma_City)-", "metadata": { "location": { "latitude": 35.80000075, @@ -5707,7 +6883,7 @@ } }, { - "uid": "fiber (West_Palm_Beach \u2192 Orlando)-", + "uid": "fiber (West_Palm_Beach → Orlando)-", "metadata": { "location": { "latitude": 27.62499955, @@ -5725,7 +6901,7 @@ } }, { - "uid": "fiber (Scranton \u2192 Philadelphia)-", + "uid": "fiber (Scranton → Philadelphia)-", "metadata": { "location": { "latitude": 40.70499925, @@ -5743,7 +6919,7 @@ } }, { - "uid": "fiber (San_Diego \u2192 Phoenix)-", + "uid": "fiber (San_Diego → Phoenix)-", "metadata": { "location": { "latitude": 33.17500114, @@ -5761,7 +6937,7 @@ } }, { - "uid": "fiber (Tucson \u2192 Phoenix)-", + "uid": "fiber (Tucson → Phoenix)-", "metadata": { "location": { "latitude": 32.87000029, @@ -5779,7 +6955,7 @@ } }, { - "uid": "fiber (Scranton \u2192 Pittsburgh)-", + "uid": "fiber (Scranton → Pittsburgh)-", "metadata": { "location": { "latitude": 40.849999999999994, @@ -5797,7 +6973,7 @@ } }, { - "uid": "fiber (Sacramento \u2192 Portland)-", + "uid": "fiber (Sacramento → Portland)-", "metadata": { "location": { "latitude": 42.05500009, @@ -5815,7 +6991,7 @@ } }, { - "uid": "fiber (Salt_Lake_City \u2192 Portland)-", + "uid": "fiber (Salt_Lake_City → Portland)-", "metadata": { "location": { "latitude": 43.159999675, @@ -5833,7 +7009,7 @@ } }, { - "uid": "fiber (Seattle \u2192 Portland)-", + "uid": "fiber (Seattle → Portland)-", "metadata": { "location": { "latitude": 46.57999994, @@ -5851,7 +7027,7 @@ } }, { - "uid": "fiber (Tokyo \u2192 Portland)-", + "uid": "fiber (Tokyo → Portland)-", "metadata": { "location": { "latitude": 40.604999660000004, @@ -5869,7 +7045,7 @@ } }, { - "uid": "fiber (Washington_DC \u2192 Richmond)-", + "uid": "fiber (Washington_DC → Richmond)-", "metadata": { "location": { "latitude": 38.21999945, @@ -5887,7 +7063,7 @@ } }, { - "uid": "fiber (Syracuse \u2192 Rochester)-", + "uid": "fiber (Syracuse → Rochester)-", "metadata": { "location": { "latitude": 43.10499975, @@ -5905,7 +7081,7 @@ } }, { - "uid": "fiber (Vienna \u2192 Rome)-", + "uid": "fiber (Vienna → Rome)-", "metadata": { "location": { "latitude": 45.055001000000004, @@ -5923,7 +7099,7 @@ } }, { - "uid": "fiber (Zurich \u2192 Rome)-", + "uid": "fiber (Zurich → Rome)-", "metadata": { "location": { "latitude": 44.63500055, @@ -5941,7 +7117,7 @@ } }, { - "uid": "fiber (San_Jose \u2192 San_Francisco)-", + "uid": "fiber (San_Jose → San_Francisco)-", "metadata": { "location": { "latitude": 37.479999445000004, @@ -5959,7 +7135,7 @@ } }, { - "uid": "fiber (Santa_Barbara \u2192 San_Jose)-", + "uid": "fiber (Santa_Barbara → San_Jose)-", "metadata": { "location": { "latitude": 35.86499984, @@ -5977,7 +7153,7 @@ } }, { - "uid": "fiber (Syracuse \u2192 Scranton)-", + "uid": "fiber (Syracuse → Scranton)-", "metadata": { "location": { "latitude": 42.2200005, @@ -5995,7 +7171,7 @@ } }, { - "uid": "fiber (Spokane \u2192 Seattle)-", + "uid": "fiber (Spokane → Seattle)-", "metadata": { "location": { "latitude": 47.644998605, @@ -6013,7 +7189,7 @@ } }, { - "uid": "fiber (Tokyo \u2192 Seoul)-", + "uid": "fiber (Tokyo → Seoul)-", "metadata": { "location": { "latitude": 36.614999839999996, @@ -6031,7 +7207,7 @@ } }, { - "uid": "fiber (Sydney \u2192 Singapore)-", + "uid": "fiber (Sydney → Singapore)-", "metadata": { "location": { "latitude": -16.2849995265, @@ -6049,7 +7225,7 @@ } }, { - "uid": "fiber (St_Louis \u2192 Springfield)-", + "uid": "fiber (St_Louis → Springfield)-", "metadata": { "location": { "latitude": 39.07, @@ -6067,7 +7243,7 @@ } }, { - "uid": "fiber (Tokyo \u2192 Taipei)-", + "uid": "fiber (Tokyo → Taipei)-", "metadata": { "location": { "latitude": 30.344999549999997, @@ -6085,7 +7261,7 @@ } }, { - "uid": "fiber (Tampa \u2192 Tallahassee)-", + "uid": "fiber (Tampa → Tallahassee)-", "metadata": { "location": { "latitude": 29.2099994, @@ -6103,7 +7279,7 @@ } }, { - "uid": "fiber (Warsaw \u2192 Vienna)-", + "uid": "fiber (Warsaw → Vienna)-", "metadata": { "location": { "latitude": 50.24000055, @@ -6123,1789 +7299,2197 @@ ], "connections": [ { - "from_node": "fiber (Dallas \u2192 Abilene)-", - "to_node": "fiber (Abilene \u2192 El_Paso)-" + "from_node": "roadm Abilene", + "to_node": "fiber (Abilene → Dallas)-" }, { - "from_node": "fiber (El_Paso \u2192 Abilene)-", - "to_node": "fiber (Abilene \u2192 Dallas)-" + "from_node": "fiber (Dallas → Abilene)-", + "to_node": "roadm Abilene" }, { - "from_node": "fiber (Boston \u2192 Albany)-", - "to_node": "fiber (Albany \u2192 Syracuse)-" + "from_node": "roadm Abilene", + "to_node": "fiber (Abilene → El_Paso)-" }, { - "from_node": "fiber (Syracuse \u2192 Albany)-", - "to_node": "fiber (Albany \u2192 Boston)-" + "from_node": "fiber (El_Paso → Abilene)-", + "to_node": "roadm Abilene" + }, + { + "from_node": "roadm Albany", + "to_node": "fiber (Albany → Boston)-" + }, + { + "from_node": "fiber (Boston → Albany)-", + "to_node": "roadm Albany" + }, + { + "from_node": "roadm Albany", + "to_node": "fiber (Albany → Syracuse)-" + }, + { + "from_node": "fiber (Syracuse → Albany)-", + "to_node": "roadm Albany" }, { "from_node": "roadm Albuquerque", - "to_node": "fiber (Albuquerque \u2192 Dallas)-" + "to_node": "fiber (Albuquerque → Dallas)-" }, { - "from_node": "fiber (Dallas \u2192 Albuquerque)-", + "from_node": "fiber (Dallas → Albuquerque)-", "to_node": "roadm Albuquerque" }, { "from_node": "roadm Albuquerque", - "to_node": "fiber (Albuquerque \u2192 Denver)-" + "to_node": "fiber (Albuquerque → Denver)-" }, { - "from_node": "fiber (Denver \u2192 Albuquerque)-", + "from_node": "fiber (Denver → Albuquerque)-", "to_node": "roadm Albuquerque" }, { "from_node": "roadm Albuquerque", - "to_node": "fiber (Albuquerque \u2192 El_Paso)-" + "to_node": "fiber (Albuquerque → El_Paso)-" }, { - "from_node": "fiber (El_Paso \u2192 Albuquerque)-", + "from_node": "fiber (El_Paso → Albuquerque)-", "to_node": "roadm Albuquerque" }, { "from_node": "roadm Albuquerque", - "to_node": "fiber (Albuquerque \u2192 Las_Vegas)-" + "to_node": "fiber (Albuquerque → Las_Vegas)-" }, { - "from_node": "fiber (Las_Vegas \u2192 Albuquerque)-", + "from_node": "fiber (Las_Vegas → Albuquerque)-", "to_node": "roadm Albuquerque" }, { "from_node": "roadm Atlanta", - "to_node": "fiber (Atlanta \u2192 Birmingham)-" + "to_node": "fiber (Atlanta → Birmingham)-" }, { - "from_node": "fiber (Birmingham \u2192 Atlanta)-", + "from_node": "fiber (Birmingham → Atlanta)-", "to_node": "roadm Atlanta" }, { "from_node": "roadm Atlanta", - "to_node": "fiber (Atlanta \u2192 Charlotte)-" + "to_node": "fiber (Atlanta → Charlotte)-" }, { - "from_node": "fiber (Charlotte \u2192 Atlanta)-", + "from_node": "fiber (Charlotte → Atlanta)-", "to_node": "roadm Atlanta" }, { "from_node": "roadm Atlanta", - "to_node": "fiber (Atlanta \u2192 Jacksonville)-" + "to_node": "fiber (Atlanta → Jacksonville)-" }, { - "from_node": "fiber (Jacksonville \u2192 Atlanta)-", + "from_node": "fiber (Jacksonville → Atlanta)-", "to_node": "roadm Atlanta" }, { - "from_node": "fiber (Houston \u2192 Austin)-", - "to_node": "fiber (Austin \u2192 San_Antonio)-" + "from_node": "roadm Austin", + "to_node": "fiber (Austin → Houston)-" }, { - "from_node": "fiber (San_Antonio \u2192 Austin)-", - "to_node": "fiber (Austin \u2192 Houston)-" + "from_node": "fiber (Houston → Austin)-", + "to_node": "roadm Austin" + }, + { + "from_node": "roadm Austin", + "to_node": "fiber (Austin → San_Antonio)-" + }, + { + "from_node": "fiber (San_Antonio → Austin)-", + "to_node": "roadm Austin" }, { "from_node": "roadm Baltimore", - "to_node": "fiber (Baltimore \u2192 Philadelphia)-" + "to_node": "fiber (Baltimore → Philadelphia)-" }, { - "from_node": "fiber (Philadelphia \u2192 Baltimore)-", + "from_node": "fiber (Philadelphia → Baltimore)-", "to_node": "roadm Baltimore" }, { "from_node": "roadm Baltimore", - "to_node": "fiber (Baltimore \u2192 Pittsburgh)-" + "to_node": "fiber (Baltimore → Pittsburgh)-" }, { - "from_node": "fiber (Pittsburgh \u2192 Baltimore)-", + "from_node": "fiber (Pittsburgh → Baltimore)-", "to_node": "roadm Baltimore" }, { "from_node": "roadm Baltimore", - "to_node": "fiber (Baltimore \u2192 Washington_DC)-" + "to_node": "fiber (Baltimore → Washington_DC)-" }, { - "from_node": "fiber (Washington_DC \u2192 Baltimore)-", + "from_node": "fiber (Washington_DC → Baltimore)-", "to_node": "roadm Baltimore" }, { - "from_node": "fiber (Houston \u2192 Baton_Rouge)-", - "to_node": "fiber (Baton_Rouge \u2192 New_Orleans)-" + "from_node": "roadm Baton_Rouge", + "to_node": "fiber (Baton_Rouge → Houston)-" }, { - "from_node": "fiber (New_Orleans \u2192 Baton_Rouge)-", - "to_node": "fiber (Baton_Rouge \u2192 Houston)-" + "from_node": "fiber (Houston → Baton_Rouge)-", + "to_node": "roadm Baton_Rouge" + }, + { + "from_node": "roadm Baton_Rouge", + "to_node": "fiber (Baton_Rouge → New_Orleans)-" + }, + { + "from_node": "fiber (New_Orleans → Baton_Rouge)-", + "to_node": "roadm Baton_Rouge" }, { "from_node": "roadm Billings", - "to_node": "fiber (Billings \u2192 Bismarck)-" + "to_node": "fiber (Billings → Bismarck)-" }, { - "from_node": "fiber (Bismarck \u2192 Billings)-", + "from_node": "fiber (Bismarck → Billings)-", "to_node": "roadm Billings" }, { "from_node": "roadm Billings", - "to_node": "fiber (Billings \u2192 Denver)-" + "to_node": "fiber (Billings → Denver)-" }, { - "from_node": "fiber (Denver \u2192 Billings)-", + "from_node": "fiber (Denver → Billings)-", "to_node": "roadm Billings" }, { "from_node": "roadm Billings", - "to_node": "fiber (Billings \u2192 Spokane)-" + "to_node": "fiber (Billings → Spokane)-" }, { - "from_node": "fiber (Spokane \u2192 Billings)-", + "from_node": "fiber (Spokane → Billings)-", "to_node": "roadm Billings" }, { "from_node": "roadm Birmingham", - "to_node": "fiber (Birmingham \u2192 Atlanta)-" + "to_node": "fiber (Birmingham → Atlanta)-" }, { - "from_node": "fiber (Atlanta \u2192 Birmingham)-", + "from_node": "fiber (Atlanta → Birmingham)-", "to_node": "roadm Birmingham" }, { "from_node": "roadm Birmingham", - "to_node": "fiber (Birmingham \u2192 Nashville)-" + "to_node": "fiber (Birmingham → Nashville)-" }, { - "from_node": "fiber (Nashville \u2192 Birmingham)-", + "from_node": "fiber (Nashville → Birmingham)-", "to_node": "roadm Birmingham" }, { "from_node": "roadm Birmingham", - "to_node": "fiber (Birmingham \u2192 New_Orleans)-" + "to_node": "fiber (Birmingham → New_Orleans)-" }, { - "from_node": "fiber (New_Orleans \u2192 Birmingham)-", + "from_node": "fiber (New_Orleans → Birmingham)-", "to_node": "roadm Birmingham" }, { - "from_node": "fiber (Billings \u2192 Bismarck)-", - "to_node": "fiber (Bismarck \u2192 Minneapolis)-" + "from_node": "roadm Bismarck", + "to_node": "fiber (Bismarck → Billings)-" }, { - "from_node": "fiber (Minneapolis \u2192 Bismarck)-", - "to_node": "fiber (Bismarck \u2192 Billings)-" + "from_node": "fiber (Billings → Bismarck)-", + "to_node": "roadm Bismarck" }, { - "from_node": "fiber (Albany \u2192 Boston)-", - "to_node": "fiber (Boston \u2192 Providence)-" + "from_node": "roadm Bismarck", + "to_node": "fiber (Bismarck → Minneapolis)-" }, { - "from_node": "fiber (Providence \u2192 Boston)-", - "to_node": "fiber (Boston \u2192 Albany)-" + "from_node": "fiber (Minneapolis → Bismarck)-", + "to_node": "roadm Bismarck" }, { - "from_node": "fiber (Cleveland \u2192 Buffalo)-", - "to_node": "fiber (Buffalo \u2192 Rochester)-" + "from_node": "roadm Boston", + "to_node": "fiber (Boston → Albany)-" }, { - "from_node": "fiber (Rochester \u2192 Buffalo)-", - "to_node": "fiber (Buffalo \u2192 Cleveland)-" + "from_node": "fiber (Albany → Boston)-", + "to_node": "roadm Boston" }, { - "from_node": "fiber (Jacksonville \u2192 Charleston)-", - "to_node": "fiber (Charleston \u2192 Raleigh)-" + "from_node": "roadm Boston", + "to_node": "fiber (Boston → Providence)-" }, { - "from_node": "fiber (Raleigh \u2192 Charleston)-", - "to_node": "fiber (Charleston \u2192 Jacksonville)-" + "from_node": "fiber (Providence → Boston)-", + "to_node": "roadm Boston" }, { - "from_node": "fiber (Atlanta \u2192 Charlotte)-", - "to_node": "fiber (Charlotte \u2192 Greensboro)-" + "from_node": "roadm Buffalo", + "to_node": "fiber (Buffalo → Cleveland)-" }, { - "from_node": "fiber (Greensboro \u2192 Charlotte)-", - "to_node": "fiber (Charlotte \u2192 Atlanta)-" + "from_node": "fiber (Cleveland → Buffalo)-", + "to_node": "roadm Buffalo" + }, + { + "from_node": "roadm Buffalo", + "to_node": "fiber (Buffalo → Rochester)-" + }, + { + "from_node": "fiber (Rochester → Buffalo)-", + "to_node": "roadm Buffalo" + }, + { + "from_node": "roadm Charleston", + "to_node": "fiber (Charleston → Jacksonville)-" + }, + { + "from_node": "fiber (Jacksonville → Charleston)-", + "to_node": "roadm Charleston" + }, + { + "from_node": "roadm Charleston", + "to_node": "fiber (Charleston → Raleigh)-" + }, + { + "from_node": "fiber (Raleigh → Charleston)-", + "to_node": "roadm Charleston" + }, + { + "from_node": "roadm Charlotte", + "to_node": "fiber (Charlotte → Atlanta)-" + }, + { + "from_node": "fiber (Atlanta → Charlotte)-", + "to_node": "roadm Charlotte" + }, + { + "from_node": "roadm Charlotte", + "to_node": "fiber (Charlotte → Greensboro)-" + }, + { + "from_node": "fiber (Greensboro → Charlotte)-", + "to_node": "roadm Charlotte" }, { "from_node": "roadm Chicago", - "to_node": "fiber (Chicago \u2192 Detroit)-" + "to_node": "fiber (Chicago → Detroit)-" }, { - "from_node": "fiber (Detroit \u2192 Chicago)-", + "from_node": "fiber (Detroit → Chicago)-", "to_node": "roadm Chicago" }, { "from_node": "roadm Chicago", - "to_node": "fiber (Chicago \u2192 Milwaukee)-" + "to_node": "fiber (Chicago → Milwaukee)-" }, { - "from_node": "fiber (Milwaukee \u2192 Chicago)-", + "from_node": "fiber (Milwaukee → Chicago)-", "to_node": "roadm Chicago" }, { "from_node": "roadm Chicago", - "to_node": "fiber (Chicago \u2192 Springfield)-" + "to_node": "fiber (Chicago → Springfield)-" }, { - "from_node": "fiber (Springfield \u2192 Chicago)-", + "from_node": "fiber (Springfield → Chicago)-", "to_node": "roadm Chicago" }, { "from_node": "roadm Cincinnati", - "to_node": "fiber (Cincinnati \u2192 Columbus)-" + "to_node": "fiber (Cincinnati → Columbus)-" }, { - "from_node": "fiber (Columbus \u2192 Cincinnati)-", + "from_node": "fiber (Columbus → Cincinnati)-", "to_node": "roadm Cincinnati" }, { "from_node": "roadm Cincinnati", - "to_node": "fiber (Cincinnati \u2192 Louisville)-" + "to_node": "fiber (Cincinnati → Louisville)-" }, { - "from_node": "fiber (Louisville \u2192 Cincinnati)-", + "from_node": "fiber (Louisville → Cincinnati)-", "to_node": "roadm Cincinnati" }, { "from_node": "roadm Cincinnati", - "to_node": "fiber (Cincinnati \u2192 Washington_DC)-" + "to_node": "fiber (Cincinnati → Washington_DC)-" }, { - "from_node": "fiber (Washington_DC \u2192 Cincinnati)-", + "from_node": "fiber (Washington_DC → Cincinnati)-", "to_node": "roadm Cincinnati" }, { "from_node": "roadm Cleveland", - "to_node": "fiber (Cleveland \u2192 Buffalo)-" + "to_node": "fiber (Cleveland → Buffalo)-" }, { - "from_node": "fiber (Buffalo \u2192 Cleveland)-", + "from_node": "fiber (Buffalo → Cleveland)-", "to_node": "roadm Cleveland" }, { "from_node": "roadm Cleveland", - "to_node": "fiber (Cleveland \u2192 Columbus)-" + "to_node": "fiber (Cleveland → Columbus)-" }, { - "from_node": "fiber (Columbus \u2192 Cleveland)-", + "from_node": "fiber (Columbus → Cleveland)-", "to_node": "roadm Cleveland" }, { "from_node": "roadm Cleveland", - "to_node": "fiber (Cleveland \u2192 Toledo)-" + "to_node": "fiber (Cleveland → Toledo)-" }, { - "from_node": "fiber (Toledo \u2192 Cleveland)-", + "from_node": "fiber (Toledo → Cleveland)-", "to_node": "roadm Cleveland" }, { "from_node": "roadm Columbus", - "to_node": "fiber (Columbus \u2192 Cincinnati)-" + "to_node": "fiber (Columbus → Cincinnati)-" }, { - "from_node": "fiber (Cincinnati \u2192 Columbus)-", + "from_node": "fiber (Cincinnati → Columbus)-", "to_node": "roadm Columbus" }, { "from_node": "roadm Columbus", - "to_node": "fiber (Columbus \u2192 Cleveland)-" + "to_node": "fiber (Columbus → Cleveland)-" }, { - "from_node": "fiber (Cleveland \u2192 Columbus)-", + "from_node": "fiber (Cleveland → Columbus)-", "to_node": "roadm Columbus" }, { "from_node": "roadm Columbus", - "to_node": "fiber (Columbus \u2192 Pittsburgh)-" + "to_node": "fiber (Columbus → Pittsburgh)-" }, { - "from_node": "fiber (Pittsburgh \u2192 Columbus)-", + "from_node": "fiber (Pittsburgh → Columbus)-", "to_node": "roadm Columbus" }, { "from_node": "roadm Dallas", - "to_node": "fiber (Dallas \u2192 Abilene)-" + "to_node": "fiber (Dallas → Abilene)-" }, { - "from_node": "fiber (Abilene \u2192 Dallas)-", + "from_node": "fiber (Abilene → Dallas)-", "to_node": "roadm Dallas" }, { "from_node": "roadm Dallas", - "to_node": "fiber (Dallas \u2192 Albuquerque)-" + "to_node": "fiber (Dallas → Albuquerque)-" }, { - "from_node": "fiber (Albuquerque \u2192 Dallas)-", + "from_node": "fiber (Albuquerque → Dallas)-", "to_node": "roadm Dallas" }, { "from_node": "roadm Dallas", - "to_node": "fiber (Dallas \u2192 Houston)-" + "to_node": "fiber (Dallas → Houston)-" }, { - "from_node": "fiber (Houston \u2192 Dallas)-", + "from_node": "fiber (Houston → Dallas)-", "to_node": "roadm Dallas" }, { "from_node": "roadm Dallas", - "to_node": "fiber (Dallas \u2192 Little_Rock)-" + "to_node": "fiber (Dallas → Little_Rock)-" }, { - "from_node": "fiber (Little_Rock \u2192 Dallas)-", + "from_node": "fiber (Little_Rock → Dallas)-", "to_node": "roadm Dallas" }, { "from_node": "roadm Dallas", - "to_node": "fiber (Dallas \u2192 Oklahoma_City)-" + "to_node": "fiber (Dallas → Oklahoma_City)-" }, { - "from_node": "fiber (Oklahoma_City \u2192 Dallas)-", + "from_node": "fiber (Oklahoma_City → Dallas)-", "to_node": "roadm Dallas" }, { "from_node": "roadm Denver", - "to_node": "fiber (Denver \u2192 Albuquerque)-" + "to_node": "fiber (Denver → Albuquerque)-" }, { - "from_node": "fiber (Albuquerque \u2192 Denver)-", + "from_node": "fiber (Albuquerque → Denver)-", "to_node": "roadm Denver" }, { "from_node": "roadm Denver", - "to_node": "fiber (Denver \u2192 Billings)-" + "to_node": "fiber (Denver → Billings)-" }, { - "from_node": "fiber (Billings \u2192 Denver)-", + "from_node": "fiber (Billings → Denver)-", "to_node": "roadm Denver" }, { "from_node": "roadm Denver", - "to_node": "fiber (Denver \u2192 Omaha)-" + "to_node": "fiber (Denver → Omaha)-" }, { - "from_node": "fiber (Omaha \u2192 Denver)-", + "from_node": "fiber (Omaha → Denver)-", "to_node": "roadm Denver" }, { "from_node": "roadm Denver", - "to_node": "fiber (Denver \u2192 Salt_Lake_City)-" + "to_node": "fiber (Denver → Salt_Lake_City)-" }, { - "from_node": "fiber (Salt_Lake_City \u2192 Denver)-", + "from_node": "fiber (Salt_Lake_City → Denver)-", "to_node": "roadm Denver" }, { - "from_node": "fiber (Chicago \u2192 Detroit)-", - "to_node": "fiber (Detroit \u2192 Toledo)-" + "from_node": "roadm Detroit", + "to_node": "fiber (Detroit → Chicago)-" }, { - "from_node": "fiber (Toledo \u2192 Detroit)-", - "to_node": "fiber (Detroit \u2192 Chicago)-" + "from_node": "fiber (Chicago → Detroit)-", + "to_node": "roadm Detroit" + }, + { + "from_node": "roadm Detroit", + "to_node": "fiber (Detroit → Toledo)-" + }, + { + "from_node": "fiber (Toledo → Detroit)-", + "to_node": "roadm Detroit" }, { "from_node": "roadm El_Paso", - "to_node": "fiber (El_Paso \u2192 Abilene)-" + "to_node": "fiber (El_Paso → Abilene)-" }, { - "from_node": "fiber (Abilene \u2192 El_Paso)-", + "from_node": "fiber (Abilene → El_Paso)-", "to_node": "roadm El_Paso" }, { "from_node": "roadm El_Paso", - "to_node": "fiber (El_Paso \u2192 Albuquerque)-" + "to_node": "fiber (El_Paso → Albuquerque)-" }, { - "from_node": "fiber (Albuquerque \u2192 El_Paso)-", + "from_node": "fiber (Albuquerque → El_Paso)-", "to_node": "roadm El_Paso" }, { "from_node": "roadm El_Paso", - "to_node": "fiber (El_Paso \u2192 San_Antonio)-" + "to_node": "fiber (El_Paso → San_Antonio)-" }, { - "from_node": "fiber (San_Antonio \u2192 El_Paso)-", + "from_node": "fiber (San_Antonio → El_Paso)-", "to_node": "roadm El_Paso" }, { "from_node": "roadm El_Paso", - "to_node": "fiber (El_Paso \u2192 Tucson)-" + "to_node": "fiber (El_Paso → Tucson)-" }, { - "from_node": "fiber (Tucson \u2192 El_Paso)-", + "from_node": "fiber (Tucson → El_Paso)-", "to_node": "roadm El_Paso" }, { "from_node": "roadm Fresno", - "to_node": "fiber (Fresno \u2192 Las_Vegas)-" + "to_node": "fiber (Fresno → Las_Vegas)-" }, { - "from_node": "fiber (Las_Vegas \u2192 Fresno)-", + "from_node": "fiber (Las_Vegas → Fresno)-", "to_node": "roadm Fresno" }, { "from_node": "roadm Fresno", - "to_node": "fiber (Fresno \u2192 Los_Angeles)-" + "to_node": "fiber (Fresno → Los_Angeles)-" }, { - "from_node": "fiber (Los_Angeles \u2192 Fresno)-", + "from_node": "fiber (Los_Angeles → Fresno)-", "to_node": "roadm Fresno" }, { "from_node": "roadm Fresno", - "to_node": "fiber (Fresno \u2192 Oakland)-" + "to_node": "fiber (Fresno → Oakland)-" }, { - "from_node": "fiber (Oakland \u2192 Fresno)-", + "from_node": "fiber (Oakland → Fresno)-", "to_node": "roadm Fresno" }, { "from_node": "roadm Greensboro", - "to_node": "fiber (Greensboro \u2192 Charlotte)-" + "to_node": "fiber (Greensboro → Charlotte)-" }, { - "from_node": "fiber (Charlotte \u2192 Greensboro)-", + "from_node": "fiber (Charlotte → Greensboro)-", "to_node": "roadm Greensboro" }, { "from_node": "roadm Greensboro", - "to_node": "fiber (Greensboro \u2192 Louisville)-" + "to_node": "fiber (Greensboro → Louisville)-" }, { - "from_node": "fiber (Louisville \u2192 Greensboro)-", + "from_node": "fiber (Louisville → Greensboro)-", "to_node": "roadm Greensboro" }, { "from_node": "roadm Greensboro", - "to_node": "fiber (Greensboro \u2192 Raleigh)-" + "to_node": "fiber (Greensboro → Raleigh)-" }, { - "from_node": "fiber (Raleigh \u2192 Greensboro)-", + "from_node": "fiber (Raleigh → Greensboro)-", "to_node": "roadm Greensboro" }, { "from_node": "roadm Greensboro", - "to_node": "fiber (Greensboro \u2192 Richmond)-" + "to_node": "fiber (Greensboro → Richmond)-" }, { - "from_node": "fiber (Richmond \u2192 Greensboro)-", + "from_node": "fiber (Richmond → Greensboro)-", "to_node": "roadm Greensboro" }, { - "from_node": "fiber (Long_Island \u2192 Hartford)-", - "to_node": "fiber (Hartford \u2192 Providence)-" + "from_node": "roadm Hartford", + "to_node": "fiber (Hartford → Long_Island)-" }, { - "from_node": "fiber (Providence \u2192 Hartford)-", - "to_node": "fiber (Hartford \u2192 Long_Island)-" + "from_node": "fiber (Long_Island → Hartford)-", + "to_node": "roadm Hartford" + }, + { + "from_node": "roadm Hartford", + "to_node": "fiber (Hartford → Providence)-" + }, + { + "from_node": "fiber (Providence → Hartford)-", + "to_node": "roadm Hartford" }, { "from_node": "roadm Houston", - "to_node": "fiber (Houston \u2192 Austin)-" + "to_node": "fiber (Houston → Austin)-" }, { - "from_node": "fiber (Austin \u2192 Houston)-", + "from_node": "fiber (Austin → Houston)-", "to_node": "roadm Houston" }, { "from_node": "roadm Houston", - "to_node": "fiber (Houston \u2192 Baton_Rouge)-" + "to_node": "fiber (Houston → Baton_Rouge)-" }, { - "from_node": "fiber (Baton_Rouge \u2192 Houston)-", + "from_node": "fiber (Baton_Rouge → Houston)-", "to_node": "roadm Houston" }, { "from_node": "roadm Houston", - "to_node": "fiber (Houston \u2192 Dallas)-" + "to_node": "fiber (Houston → Dallas)-" }, { - "from_node": "fiber (Dallas \u2192 Houston)-", + "from_node": "fiber (Dallas → Houston)-", "to_node": "roadm Houston" }, { "from_node": "roadm Jacksonville", - "to_node": "fiber (Jacksonville \u2192 Atlanta)-" + "to_node": "fiber (Jacksonville → Atlanta)-" }, { - "from_node": "fiber (Atlanta \u2192 Jacksonville)-", + "from_node": "fiber (Atlanta → Jacksonville)-", "to_node": "roadm Jacksonville" }, { "from_node": "roadm Jacksonville", - "to_node": "fiber (Jacksonville \u2192 Charleston)-" + "to_node": "fiber (Jacksonville → Charleston)-" }, { - "from_node": "fiber (Charleston \u2192 Jacksonville)-", + "from_node": "fiber (Charleston → Jacksonville)-", "to_node": "roadm Jacksonville" }, { "from_node": "roadm Jacksonville", - "to_node": "fiber (Jacksonville \u2192 Orlando)-" + "to_node": "fiber (Jacksonville → Orlando)-" }, { - "from_node": "fiber (Orlando \u2192 Jacksonville)-", + "from_node": "fiber (Orlando → Jacksonville)-", "to_node": "roadm Jacksonville" }, { "from_node": "roadm Kansas_City", - "to_node": "fiber (Kansas_City \u2192 Omaha)-" + "to_node": "fiber (Kansas_City → Omaha)-" }, { - "from_node": "fiber (Omaha \u2192 Kansas_City)-", + "from_node": "fiber (Omaha → Kansas_City)-", "to_node": "roadm Kansas_City" }, { "from_node": "roadm Kansas_City", - "to_node": "fiber (Kansas_City \u2192 St_Louis)-" + "to_node": "fiber (Kansas_City → St_Louis)-" }, { - "from_node": "fiber (St_Louis \u2192 Kansas_City)-", + "from_node": "fiber (St_Louis → Kansas_City)-", "to_node": "roadm Kansas_City" }, { "from_node": "roadm Kansas_City", - "to_node": "fiber (Kansas_City \u2192 Tulsa)-" + "to_node": "fiber (Kansas_City → Tulsa)-" }, { - "from_node": "fiber (Tulsa \u2192 Kansas_City)-", + "from_node": "fiber (Tulsa → Kansas_City)-", "to_node": "roadm Kansas_City" }, { "from_node": "roadm Las_Vegas", - "to_node": "fiber (Las_Vegas \u2192 Albuquerque)-" + "to_node": "fiber (Las_Vegas → Albuquerque)-" }, { - "from_node": "fiber (Albuquerque \u2192 Las_Vegas)-", + "from_node": "fiber (Albuquerque → Las_Vegas)-", "to_node": "roadm Las_Vegas" }, { "from_node": "roadm Las_Vegas", - "to_node": "fiber (Las_Vegas \u2192 Fresno)-" + "to_node": "fiber (Las_Vegas → Fresno)-" }, { - "from_node": "fiber (Fresno \u2192 Las_Vegas)-", + "from_node": "fiber (Fresno → Las_Vegas)-", "to_node": "roadm Las_Vegas" }, { "from_node": "roadm Las_Vegas", - "to_node": "fiber (Las_Vegas \u2192 Phoenix)-" + "to_node": "fiber (Las_Vegas → Phoenix)-" }, { - "from_node": "fiber (Phoenix \u2192 Las_Vegas)-", + "from_node": "fiber (Phoenix → Las_Vegas)-", "to_node": "roadm Las_Vegas" }, { "from_node": "roadm Las_Vegas", - "to_node": "fiber (Las_Vegas \u2192 Salt_Lake_City)-" + "to_node": "fiber (Las_Vegas → Salt_Lake_City)-" }, { - "from_node": "fiber (Salt_Lake_City \u2192 Las_Vegas)-", + "from_node": "fiber (Salt_Lake_City → Las_Vegas)-", "to_node": "roadm Las_Vegas" }, { - "from_node": "fiber (Dallas \u2192 Little_Rock)-", - "to_node": "fiber (Little_Rock \u2192 Memphis)-" + "from_node": "roadm Little_Rock", + "to_node": "fiber (Little_Rock → Dallas)-" }, { - "from_node": "fiber (Memphis \u2192 Little_Rock)-", - "to_node": "fiber (Little_Rock \u2192 Dallas)-" + "from_node": "fiber (Dallas → Little_Rock)-", + "to_node": "roadm Little_Rock" }, { - "from_node": "fiber (Hartford \u2192 Long_Island)-", - "to_node": "fiber (Long_Island \u2192 New_York)-" + "from_node": "roadm Little_Rock", + "to_node": "fiber (Little_Rock → Memphis)-" }, { - "from_node": "fiber (New_York \u2192 Long_Island)-", - "to_node": "fiber (Long_Island \u2192 Hartford)-" + "from_node": "fiber (Memphis → Little_Rock)-", + "to_node": "roadm Little_Rock" + }, + { + "from_node": "roadm Long_Island", + "to_node": "fiber (Long_Island → Hartford)-" + }, + { + "from_node": "fiber (Hartford → Long_Island)-", + "to_node": "roadm Long_Island" + }, + { + "from_node": "roadm Long_Island", + "to_node": "fiber (Long_Island → New_York)-" + }, + { + "from_node": "fiber (New_York → Long_Island)-", + "to_node": "roadm Long_Island" }, { "from_node": "roadm Los_Angeles", - "to_node": "fiber (Los_Angeles \u2192 Fresno)-" + "to_node": "fiber (Los_Angeles → Fresno)-" }, { - "from_node": "fiber (Fresno \u2192 Los_Angeles)-", + "from_node": "fiber (Fresno → Los_Angeles)-", "to_node": "roadm Los_Angeles" }, { "from_node": "roadm Los_Angeles", - "to_node": "fiber (Los_Angeles \u2192 Honolulu)-" + "to_node": "fiber (Los_Angeles → Honolulu)-" }, { - "from_node": "fiber (Honolulu \u2192 Los_Angeles)-", + "from_node": "fiber (Honolulu → Los_Angeles)-", "to_node": "roadm Los_Angeles" }, { "from_node": "roadm Los_Angeles", - "to_node": "fiber (Los_Angeles \u2192 San_Diego)-" + "to_node": "fiber (Los_Angeles → San_Diego)-" }, { - "from_node": "fiber (San_Diego \u2192 Los_Angeles)-", + "from_node": "fiber (San_Diego → Los_Angeles)-", "to_node": "roadm Los_Angeles" }, { "from_node": "roadm Los_Angeles", - "to_node": "fiber (Los_Angeles \u2192 Santa_Barbara)-" + "to_node": "fiber (Los_Angeles → Santa_Barbara)-" }, { - "from_node": "fiber (Santa_Barbara \u2192 Los_Angeles)-", + "from_node": "fiber (Santa_Barbara → Los_Angeles)-", "to_node": "roadm Los_Angeles" }, { "from_node": "roadm Louisville", - "to_node": "fiber (Louisville \u2192 Cincinnati)-" + "to_node": "fiber (Louisville → Cincinnati)-" }, { - "from_node": "fiber (Cincinnati \u2192 Louisville)-", + "from_node": "fiber (Cincinnati → Louisville)-", "to_node": "roadm Louisville" }, { "from_node": "roadm Louisville", - "to_node": "fiber (Louisville \u2192 Greensboro)-" + "to_node": "fiber (Louisville → Greensboro)-" }, { - "from_node": "fiber (Greensboro \u2192 Louisville)-", + "from_node": "fiber (Greensboro → Louisville)-", "to_node": "roadm Louisville" }, { "from_node": "roadm Louisville", - "to_node": "fiber (Louisville \u2192 Nashville)-" + "to_node": "fiber (Louisville → Nashville)-" }, { - "from_node": "fiber (Nashville \u2192 Louisville)-", + "from_node": "fiber (Nashville → Louisville)-", "to_node": "roadm Louisville" }, { "from_node": "roadm Louisville", - "to_node": "fiber (Louisville \u2192 St_Louis)-" + "to_node": "fiber (Louisville → St_Louis)-" }, { - "from_node": "fiber (St_Louis \u2192 Louisville)-", + "from_node": "fiber (St_Louis → Louisville)-", "to_node": "roadm Louisville" }, { - "from_node": "fiber (Little_Rock \u2192 Memphis)-", - "to_node": "fiber (Memphis \u2192 Nashville)-" + "from_node": "roadm Memphis", + "to_node": "fiber (Memphis → Little_Rock)-" }, { - "from_node": "fiber (Nashville \u2192 Memphis)-", - "to_node": "fiber (Memphis \u2192 Little_Rock)-" + "from_node": "fiber (Little_Rock → Memphis)-", + "to_node": "roadm Memphis" + }, + { + "from_node": "roadm Memphis", + "to_node": "fiber (Memphis → Nashville)-" + }, + { + "from_node": "fiber (Nashville → Memphis)-", + "to_node": "roadm Memphis" }, { "from_node": "roadm Miami", - "to_node": "fiber (Miami \u2192 Paris)-" + "to_node": "fiber (Miami → Paris)-" }, { - "from_node": "fiber (Paris \u2192 Miami)-", + "from_node": "fiber (Paris → Miami)-", "to_node": "roadm Miami" }, { "from_node": "roadm Miami", - "to_node": "fiber (Miami \u2192 Tampa)-" + "to_node": "fiber (Miami → Tampa)-" }, { - "from_node": "fiber (Tampa \u2192 Miami)-", + "from_node": "fiber (Tampa → Miami)-", "to_node": "roadm Miami" }, { "from_node": "roadm Miami", - "to_node": "fiber (Miami \u2192 West_Palm_Beach)-" + "to_node": "fiber (Miami → West_Palm_Beach)-" }, { - "from_node": "fiber (West_Palm_Beach \u2192 Miami)-", + "from_node": "fiber (West_Palm_Beach → Miami)-", "to_node": "roadm Miami" }, { - "from_node": "fiber (Chicago \u2192 Milwaukee)-", - "to_node": "fiber (Milwaukee \u2192 Minneapolis)-" + "from_node": "roadm Milwaukee", + "to_node": "fiber (Milwaukee → Chicago)-" }, { - "from_node": "fiber (Minneapolis \u2192 Milwaukee)-", - "to_node": "fiber (Milwaukee \u2192 Chicago)-" + "from_node": "fiber (Chicago → Milwaukee)-", + "to_node": "roadm Milwaukee" + }, + { + "from_node": "roadm Milwaukee", + "to_node": "fiber (Milwaukee → Minneapolis)-" + }, + { + "from_node": "fiber (Minneapolis → Milwaukee)-", + "to_node": "roadm Milwaukee" }, { "from_node": "roadm Minneapolis", - "to_node": "fiber (Minneapolis \u2192 Bismarck)-" + "to_node": "fiber (Minneapolis → Bismarck)-" }, { - "from_node": "fiber (Bismarck \u2192 Minneapolis)-", + "from_node": "fiber (Bismarck → Minneapolis)-", "to_node": "roadm Minneapolis" }, { "from_node": "roadm Minneapolis", - "to_node": "fiber (Minneapolis \u2192 Milwaukee)-" + "to_node": "fiber (Minneapolis → Milwaukee)-" }, { - "from_node": "fiber (Milwaukee \u2192 Minneapolis)-", + "from_node": "fiber (Milwaukee → Minneapolis)-", "to_node": "roadm Minneapolis" }, { "from_node": "roadm Minneapolis", - "to_node": "fiber (Minneapolis \u2192 Omaha)-" + "to_node": "fiber (Minneapolis → Omaha)-" }, { - "from_node": "fiber (Omaha \u2192 Minneapolis)-", + "from_node": "fiber (Omaha → Minneapolis)-", "to_node": "roadm Minneapolis" }, { "from_node": "roadm Nashville", - "to_node": "fiber (Nashville \u2192 Birmingham)-" + "to_node": "fiber (Nashville → Birmingham)-" }, { - "from_node": "fiber (Birmingham \u2192 Nashville)-", + "from_node": "fiber (Birmingham → Nashville)-", "to_node": "roadm Nashville" }, { "from_node": "roadm Nashville", - "to_node": "fiber (Nashville \u2192 Louisville)-" + "to_node": "fiber (Nashville → Louisville)-" }, { - "from_node": "fiber (Louisville \u2192 Nashville)-", + "from_node": "fiber (Louisville → Nashville)-", "to_node": "roadm Nashville" }, { "from_node": "roadm Nashville", - "to_node": "fiber (Nashville \u2192 Memphis)-" + "to_node": "fiber (Nashville → Memphis)-" }, { - "from_node": "fiber (Memphis \u2192 Nashville)-", + "from_node": "fiber (Memphis → Nashville)-", "to_node": "roadm Nashville" }, { "from_node": "roadm New_Orleans", - "to_node": "fiber (New_Orleans \u2192 Baton_Rouge)-" + "to_node": "fiber (New_Orleans → Baton_Rouge)-" }, { - "from_node": "fiber (Baton_Rouge \u2192 New_Orleans)-", + "from_node": "fiber (Baton_Rouge → New_Orleans)-", "to_node": "roadm New_Orleans" }, { "from_node": "roadm New_Orleans", - "to_node": "fiber (New_Orleans \u2192 Birmingham)-" + "to_node": "fiber (New_Orleans → Birmingham)-" }, { - "from_node": "fiber (Birmingham \u2192 New_Orleans)-", + "from_node": "fiber (Birmingham → New_Orleans)-", "to_node": "roadm New_Orleans" }, { "from_node": "roadm New_Orleans", - "to_node": "fiber (New_Orleans \u2192 Tallahassee)-" + "to_node": "fiber (New_Orleans → Tallahassee)-" }, { - "from_node": "fiber (Tallahassee \u2192 New_Orleans)-", + "from_node": "fiber (Tallahassee → New_Orleans)-", "to_node": "roadm New_Orleans" }, { "from_node": "roadm New_York", - "to_node": "fiber (New_York \u2192 Amsterdam)-" + "to_node": "fiber (New_York → Amsterdam)-" }, { - "from_node": "fiber (Amsterdam \u2192 New_York)-", + "from_node": "fiber (Amsterdam → New_York)-", "to_node": "roadm New_York" }, { "from_node": "roadm New_York", - "to_node": "fiber (New_York \u2192 Long_Island)-" + "to_node": "fiber (New_York → Long_Island)-" }, { - "from_node": "fiber (Long_Island \u2192 New_York)-", + "from_node": "fiber (Long_Island → New_York)-", "to_node": "roadm New_York" }, { "from_node": "roadm New_York", - "to_node": "fiber (New_York \u2192 Newark)-" + "to_node": "fiber (New_York → Newark)-" }, { - "from_node": "fiber (Newark \u2192 New_York)-", + "from_node": "fiber (Newark → New_York)-", "to_node": "roadm New_York" }, { "from_node": "roadm New_York", - "to_node": "fiber (New_York \u2192 Scranton)-" + "to_node": "fiber (New_York → Scranton)-" }, { - "from_node": "fiber (Scranton \u2192 New_York)-", + "from_node": "fiber (Scranton → New_York)-", "to_node": "roadm New_York" }, { "from_node": "roadm New_York", - "to_node": "fiber (New_York \u2192 Wilmington)-" + "to_node": "fiber (New_York → Wilmington)-" }, { - "from_node": "fiber (Wilmington \u2192 New_York)-", + "from_node": "fiber (Wilmington → New_York)-", "to_node": "roadm New_York" }, { - "from_node": "fiber (New_York \u2192 Newark)-", - "to_node": "fiber (Newark \u2192 Philadelphia)-" + "from_node": "roadm Newark", + "to_node": "fiber (Newark → New_York)-" }, { - "from_node": "fiber (Philadelphia \u2192 Newark)-", - "to_node": "fiber (Newark \u2192 New_York)-" + "from_node": "fiber (New_York → Newark)-", + "to_node": "roadm Newark" }, { - "from_node": "fiber (Raleigh \u2192 Norfolk)-", - "to_node": "fiber (Norfolk \u2192 Wilmington)-" + "from_node": "roadm Newark", + "to_node": "fiber (Newark → Philadelphia)-" }, { - "from_node": "fiber (Wilmington \u2192 Norfolk)-", - "to_node": "fiber (Norfolk \u2192 Raleigh)-" + "from_node": "fiber (Philadelphia → Newark)-", + "to_node": "roadm Newark" + }, + { + "from_node": "roadm Norfolk", + "to_node": "fiber (Norfolk → Raleigh)-" + }, + { + "from_node": "fiber (Raleigh → Norfolk)-", + "to_node": "roadm Norfolk" + }, + { + "from_node": "roadm Norfolk", + "to_node": "fiber (Norfolk → Wilmington)-" + }, + { + "from_node": "fiber (Wilmington → Norfolk)-", + "to_node": "roadm Norfolk" }, { "from_node": "roadm Oakland", - "to_node": "fiber (Oakland \u2192 Fresno)-" + "to_node": "fiber (Oakland → Fresno)-" }, { - "from_node": "fiber (Fresno \u2192 Oakland)-", + "from_node": "fiber (Fresno → Oakland)-", "to_node": "roadm Oakland" }, { "from_node": "roadm Oakland", - "to_node": "fiber (Oakland \u2192 Sacramento)-" + "to_node": "fiber (Oakland → Sacramento)-" }, { - "from_node": "fiber (Sacramento \u2192 Oakland)-", + "from_node": "fiber (Sacramento → Oakland)-", "to_node": "roadm Oakland" }, { "from_node": "roadm Oakland", - "to_node": "fiber (Oakland \u2192 Salt_Lake_City)-" + "to_node": "fiber (Oakland → Salt_Lake_City)-" }, { - "from_node": "fiber (Salt_Lake_City \u2192 Oakland)-", + "from_node": "fiber (Salt_Lake_City → Oakland)-", "to_node": "roadm Oakland" }, { "from_node": "roadm Oakland", - "to_node": "fiber (Oakland \u2192 San_Francisco)-" + "to_node": "fiber (Oakland → San_Francisco)-" }, { - "from_node": "fiber (San_Francisco \u2192 Oakland)-", + "from_node": "fiber (San_Francisco → Oakland)-", "to_node": "roadm Oakland" }, { "from_node": "roadm Oakland", - "to_node": "fiber (Oakland \u2192 Taipei)-" + "to_node": "fiber (Oakland → Taipei)-" }, { - "from_node": "fiber (Taipei \u2192 Oakland)-", + "from_node": "fiber (Taipei → Oakland)-", "to_node": "roadm Oakland" }, { - "from_node": "fiber (Dallas \u2192 Oklahoma_City)-", - "to_node": "fiber (Oklahoma_City \u2192 Tulsa)-" + "from_node": "roadm Oklahoma_City", + "to_node": "fiber (Oklahoma_City → Dallas)-" }, { - "from_node": "fiber (Tulsa \u2192 Oklahoma_City)-", - "to_node": "fiber (Oklahoma_City \u2192 Dallas)-" + "from_node": "fiber (Dallas → Oklahoma_City)-", + "to_node": "roadm Oklahoma_City" + }, + { + "from_node": "roadm Oklahoma_City", + "to_node": "fiber (Oklahoma_City → Tulsa)-" + }, + { + "from_node": "fiber (Tulsa → Oklahoma_City)-", + "to_node": "roadm Oklahoma_City" }, { "from_node": "roadm Omaha", - "to_node": "fiber (Omaha \u2192 Denver)-" + "to_node": "fiber (Omaha → Denver)-" }, { - "from_node": "fiber (Denver \u2192 Omaha)-", + "from_node": "fiber (Denver → Omaha)-", "to_node": "roadm Omaha" }, { "from_node": "roadm Omaha", - "to_node": "fiber (Omaha \u2192 Kansas_City)-" + "to_node": "fiber (Omaha → Kansas_City)-" }, { - "from_node": "fiber (Kansas_City \u2192 Omaha)-", + "from_node": "fiber (Kansas_City → Omaha)-", "to_node": "roadm Omaha" }, { "from_node": "roadm Omaha", - "to_node": "fiber (Omaha \u2192 Minneapolis)-" + "to_node": "fiber (Omaha → Minneapolis)-" }, { - "from_node": "fiber (Minneapolis \u2192 Omaha)-", + "from_node": "fiber (Minneapolis → Omaha)-", "to_node": "roadm Omaha" }, { - "from_node": "fiber (Jacksonville \u2192 Orlando)-", - "to_node": "fiber (Orlando \u2192 West_Palm_Beach)-" + "from_node": "roadm Orlando", + "to_node": "fiber (Orlando → Jacksonville)-" }, { - "from_node": "fiber (West_Palm_Beach \u2192 Orlando)-", - "to_node": "fiber (Orlando \u2192 Jacksonville)-" + "from_node": "fiber (Jacksonville → Orlando)-", + "to_node": "roadm Orlando" + }, + { + "from_node": "roadm Orlando", + "to_node": "fiber (Orlando → West_Palm_Beach)-" + }, + { + "from_node": "fiber (West_Palm_Beach → Orlando)-", + "to_node": "roadm Orlando" }, { "from_node": "roadm Philadelphia", - "to_node": "fiber (Philadelphia \u2192 Baltimore)-" + "to_node": "fiber (Philadelphia → Baltimore)-" }, { - "from_node": "fiber (Baltimore \u2192 Philadelphia)-", + "from_node": "fiber (Baltimore → Philadelphia)-", "to_node": "roadm Philadelphia" }, { "from_node": "roadm Philadelphia", - "to_node": "fiber (Philadelphia \u2192 Newark)-" + "to_node": "fiber (Philadelphia → Newark)-" }, { - "from_node": "fiber (Newark \u2192 Philadelphia)-", + "from_node": "fiber (Newark → Philadelphia)-", "to_node": "roadm Philadelphia" }, { "from_node": "roadm Philadelphia", - "to_node": "fiber (Philadelphia \u2192 Scranton)-" + "to_node": "fiber (Philadelphia → Scranton)-" }, { - "from_node": "fiber (Scranton \u2192 Philadelphia)-", + "from_node": "fiber (Scranton → Philadelphia)-", "to_node": "roadm Philadelphia" }, { "from_node": "roadm Phoenix", - "to_node": "fiber (Phoenix \u2192 Las_Vegas)-" + "to_node": "fiber (Phoenix → Las_Vegas)-" }, { - "from_node": "fiber (Las_Vegas \u2192 Phoenix)-", + "from_node": "fiber (Las_Vegas → Phoenix)-", "to_node": "roadm Phoenix" }, { "from_node": "roadm Phoenix", - "to_node": "fiber (Phoenix \u2192 San_Diego)-" + "to_node": "fiber (Phoenix → San_Diego)-" }, { - "from_node": "fiber (San_Diego \u2192 Phoenix)-", + "from_node": "fiber (San_Diego → Phoenix)-", "to_node": "roadm Phoenix" }, { "from_node": "roadm Phoenix", - "to_node": "fiber (Phoenix \u2192 Tucson)-" + "to_node": "fiber (Phoenix → Tucson)-" }, { - "from_node": "fiber (Tucson \u2192 Phoenix)-", + "from_node": "fiber (Tucson → Phoenix)-", "to_node": "roadm Phoenix" }, { "from_node": "roadm Pittsburgh", - "to_node": "fiber (Pittsburgh \u2192 Baltimore)-" + "to_node": "fiber (Pittsburgh → Baltimore)-" }, { - "from_node": "fiber (Baltimore \u2192 Pittsburgh)-", + "from_node": "fiber (Baltimore → Pittsburgh)-", "to_node": "roadm Pittsburgh" }, { "from_node": "roadm Pittsburgh", - "to_node": "fiber (Pittsburgh \u2192 Columbus)-" + "to_node": "fiber (Pittsburgh → Columbus)-" }, { - "from_node": "fiber (Columbus \u2192 Pittsburgh)-", + "from_node": "fiber (Columbus → Pittsburgh)-", "to_node": "roadm Pittsburgh" }, { "from_node": "roadm Pittsburgh", - "to_node": "fiber (Pittsburgh \u2192 Scranton)-" + "to_node": "fiber (Pittsburgh → Scranton)-" }, { - "from_node": "fiber (Scranton \u2192 Pittsburgh)-", + "from_node": "fiber (Scranton → Pittsburgh)-", "to_node": "roadm Pittsburgh" }, { "from_node": "roadm Portland", - "to_node": "fiber (Portland \u2192 Sacramento)-" + "to_node": "fiber (Portland → Sacramento)-" }, { - "from_node": "fiber (Sacramento \u2192 Portland)-", + "from_node": "fiber (Sacramento → Portland)-", "to_node": "roadm Portland" }, { "from_node": "roadm Portland", - "to_node": "fiber (Portland \u2192 Salt_Lake_City)-" + "to_node": "fiber (Portland → Salt_Lake_City)-" }, { - "from_node": "fiber (Salt_Lake_City \u2192 Portland)-", + "from_node": "fiber (Salt_Lake_City → Portland)-", "to_node": "roadm Portland" }, { "from_node": "roadm Portland", - "to_node": "fiber (Portland \u2192 Seattle)-" + "to_node": "fiber (Portland → Seattle)-" }, { - "from_node": "fiber (Seattle \u2192 Portland)-", + "from_node": "fiber (Seattle → Portland)-", "to_node": "roadm Portland" }, { "from_node": "roadm Portland", - "to_node": "fiber (Portland \u2192 Tokyo)-" + "to_node": "fiber (Portland → Tokyo)-" }, { - "from_node": "fiber (Tokyo \u2192 Portland)-", + "from_node": "fiber (Tokyo → Portland)-", "to_node": "roadm Portland" }, { - "from_node": "fiber (Boston \u2192 Providence)-", - "to_node": "fiber (Providence \u2192 Hartford)-" + "from_node": "roadm Providence", + "to_node": "fiber (Providence → Boston)-" }, { - "from_node": "fiber (Hartford \u2192 Providence)-", - "to_node": "fiber (Providence \u2192 Boston)-" + "from_node": "fiber (Boston → Providence)-", + "to_node": "roadm Providence" + }, + { + "from_node": "roadm Providence", + "to_node": "fiber (Providence → Hartford)-" + }, + { + "from_node": "fiber (Hartford → Providence)-", + "to_node": "roadm Providence" }, { "from_node": "roadm Raleigh", - "to_node": "fiber (Raleigh \u2192 Charleston)-" + "to_node": "fiber (Raleigh → Charleston)-" }, { - "from_node": "fiber (Charleston \u2192 Raleigh)-", + "from_node": "fiber (Charleston → Raleigh)-", "to_node": "roadm Raleigh" }, { "from_node": "roadm Raleigh", - "to_node": "fiber (Raleigh \u2192 Greensboro)-" + "to_node": "fiber (Raleigh → Greensboro)-" }, { - "from_node": "fiber (Greensboro \u2192 Raleigh)-", + "from_node": "fiber (Greensboro → Raleigh)-", "to_node": "roadm Raleigh" }, { "from_node": "roadm Raleigh", - "to_node": "fiber (Raleigh \u2192 Norfolk)-" + "to_node": "fiber (Raleigh → Norfolk)-" }, { - "from_node": "fiber (Norfolk \u2192 Raleigh)-", + "from_node": "fiber (Norfolk → Raleigh)-", "to_node": "roadm Raleigh" }, { - "from_node": "fiber (Greensboro \u2192 Richmond)-", - "to_node": "fiber (Richmond \u2192 Washington_DC)-" + "from_node": "roadm Richmond", + "to_node": "fiber (Richmond → Greensboro)-" }, { - "from_node": "fiber (Washington_DC \u2192 Richmond)-", - "to_node": "fiber (Richmond \u2192 Greensboro)-" + "from_node": "fiber (Greensboro → Richmond)-", + "to_node": "roadm Richmond" }, { - "from_node": "fiber (Buffalo \u2192 Rochester)-", - "to_node": "fiber (Rochester \u2192 Syracuse)-" + "from_node": "roadm Richmond", + "to_node": "fiber (Richmond → Washington_DC)-" }, { - "from_node": "fiber (Syracuse \u2192 Rochester)-", - "to_node": "fiber (Rochester \u2192 Buffalo)-" + "from_node": "fiber (Washington_DC → Richmond)-", + "to_node": "roadm Richmond" }, { - "from_node": "fiber (Oakland \u2192 Sacramento)-", - "to_node": "fiber (Sacramento \u2192 Portland)-" + "from_node": "roadm Rochester", + "to_node": "fiber (Rochester → Buffalo)-" }, { - "from_node": "fiber (Portland \u2192 Sacramento)-", - "to_node": "fiber (Sacramento \u2192 Oakland)-" + "from_node": "fiber (Buffalo → Rochester)-", + "to_node": "roadm Rochester" + }, + { + "from_node": "roadm Rochester", + "to_node": "fiber (Rochester → Syracuse)-" + }, + { + "from_node": "fiber (Syracuse → Rochester)-", + "to_node": "roadm Rochester" + }, + { + "from_node": "roadm Sacramento", + "to_node": "fiber (Sacramento → Oakland)-" + }, + { + "from_node": "fiber (Oakland → Sacramento)-", + "to_node": "roadm Sacramento" + }, + { + "from_node": "roadm Sacramento", + "to_node": "fiber (Sacramento → Portland)-" + }, + { + "from_node": "fiber (Portland → Sacramento)-", + "to_node": "roadm Sacramento" }, { "from_node": "roadm Salt_Lake_City", - "to_node": "fiber (Salt_Lake_City \u2192 Denver)-" + "to_node": "fiber (Salt_Lake_City → Denver)-" }, { - "from_node": "fiber (Denver \u2192 Salt_Lake_City)-", + "from_node": "fiber (Denver → Salt_Lake_City)-", "to_node": "roadm Salt_Lake_City" }, { "from_node": "roadm Salt_Lake_City", - "to_node": "fiber (Salt_Lake_City \u2192 Las_Vegas)-" + "to_node": "fiber (Salt_Lake_City → Las_Vegas)-" }, { - "from_node": "fiber (Las_Vegas \u2192 Salt_Lake_City)-", + "from_node": "fiber (Las_Vegas → Salt_Lake_City)-", "to_node": "roadm Salt_Lake_City" }, { "from_node": "roadm Salt_Lake_City", - "to_node": "fiber (Salt_Lake_City \u2192 Oakland)-" + "to_node": "fiber (Salt_Lake_City → Oakland)-" }, { - "from_node": "fiber (Oakland \u2192 Salt_Lake_City)-", + "from_node": "fiber (Oakland → Salt_Lake_City)-", "to_node": "roadm Salt_Lake_City" }, { "from_node": "roadm Salt_Lake_City", - "to_node": "fiber (Salt_Lake_City \u2192 Portland)-" + "to_node": "fiber (Salt_Lake_City → Portland)-" }, { - "from_node": "fiber (Portland \u2192 Salt_Lake_City)-", + "from_node": "fiber (Portland → Salt_Lake_City)-", "to_node": "roadm Salt_Lake_City" }, { - "from_node": "fiber (Austin \u2192 San_Antonio)-", - "to_node": "fiber (San_Antonio \u2192 El_Paso)-" + "from_node": "roadm San_Antonio", + "to_node": "fiber (San_Antonio → Austin)-" }, { - "from_node": "fiber (El_Paso \u2192 San_Antonio)-", - "to_node": "fiber (San_Antonio \u2192 Austin)-" + "from_node": "fiber (Austin → San_Antonio)-", + "to_node": "roadm San_Antonio" }, { - "from_node": "fiber (Los_Angeles \u2192 San_Diego)-", - "to_node": "fiber (San_Diego \u2192 Phoenix)-" + "from_node": "roadm San_Antonio", + "to_node": "fiber (San_Antonio → El_Paso)-" }, { - "from_node": "fiber (Phoenix \u2192 San_Diego)-", - "to_node": "fiber (San_Diego \u2192 Los_Angeles)-" + "from_node": "fiber (El_Paso → San_Antonio)-", + "to_node": "roadm San_Antonio" }, { - "from_node": "fiber (Oakland \u2192 San_Francisco)-", - "to_node": "fiber (San_Francisco \u2192 San_Jose)-" + "from_node": "roadm San_Diego", + "to_node": "fiber (San_Diego → Los_Angeles)-" }, { - "from_node": "fiber (San_Jose \u2192 San_Francisco)-", - "to_node": "fiber (San_Francisco \u2192 Oakland)-" + "from_node": "fiber (Los_Angeles → San_Diego)-", + "to_node": "roadm San_Diego" }, { - "from_node": "fiber (San_Francisco \u2192 San_Jose)-", - "to_node": "fiber (San_Jose \u2192 Santa_Barbara)-" + "from_node": "roadm San_Diego", + "to_node": "fiber (San_Diego → Phoenix)-" }, { - "from_node": "fiber (Santa_Barbara \u2192 San_Jose)-", - "to_node": "fiber (San_Jose \u2192 San_Francisco)-" + "from_node": "fiber (Phoenix → San_Diego)-", + "to_node": "roadm San_Diego" }, { - "from_node": "fiber (Los_Angeles \u2192 Santa_Barbara)-", - "to_node": "fiber (Santa_Barbara \u2192 San_Jose)-" + "from_node": "roadm San_Francisco", + "to_node": "fiber (San_Francisco → Oakland)-" }, { - "from_node": "fiber (San_Jose \u2192 Santa_Barbara)-", - "to_node": "fiber (Santa_Barbara \u2192 Los_Angeles)-" + "from_node": "fiber (Oakland → San_Francisco)-", + "to_node": "roadm San_Francisco" + }, + { + "from_node": "roadm San_Francisco", + "to_node": "fiber (San_Francisco → San_Jose)-" + }, + { + "from_node": "fiber (San_Jose → San_Francisco)-", + "to_node": "roadm San_Francisco" + }, + { + "from_node": "roadm San_Jose", + "to_node": "fiber (San_Jose → San_Francisco)-" + }, + { + "from_node": "fiber (San_Francisco → San_Jose)-", + "to_node": "roadm San_Jose" + }, + { + "from_node": "roadm San_Jose", + "to_node": "fiber (San_Jose → Santa_Barbara)-" + }, + { + "from_node": "fiber (Santa_Barbara → San_Jose)-", + "to_node": "roadm San_Jose" + }, + { + "from_node": "roadm Santa_Barbara", + "to_node": "fiber (Santa_Barbara → Los_Angeles)-" + }, + { + "from_node": "fiber (Los_Angeles → Santa_Barbara)-", + "to_node": "roadm Santa_Barbara" + }, + { + "from_node": "roadm Santa_Barbara", + "to_node": "fiber (Santa_Barbara → San_Jose)-" + }, + { + "from_node": "fiber (San_Jose → Santa_Barbara)-", + "to_node": "roadm Santa_Barbara" }, { "from_node": "roadm Scranton", - "to_node": "fiber (Scranton \u2192 New_York)-" + "to_node": "fiber (Scranton → New_York)-" }, { - "from_node": "fiber (New_York \u2192 Scranton)-", + "from_node": "fiber (New_York → Scranton)-", "to_node": "roadm Scranton" }, { "from_node": "roadm Scranton", - "to_node": "fiber (Scranton \u2192 Philadelphia)-" + "to_node": "fiber (Scranton → Philadelphia)-" }, { - "from_node": "fiber (Philadelphia \u2192 Scranton)-", + "from_node": "fiber (Philadelphia → Scranton)-", "to_node": "roadm Scranton" }, { "from_node": "roadm Scranton", - "to_node": "fiber (Scranton \u2192 Pittsburgh)-" + "to_node": "fiber (Scranton → Pittsburgh)-" }, { - "from_node": "fiber (Pittsburgh \u2192 Scranton)-", + "from_node": "fiber (Pittsburgh → Scranton)-", "to_node": "roadm Scranton" }, { "from_node": "roadm Scranton", - "to_node": "fiber (Scranton \u2192 Syracuse)-" + "to_node": "fiber (Scranton → Syracuse)-" }, { - "from_node": "fiber (Syracuse \u2192 Scranton)-", + "from_node": "fiber (Syracuse → Scranton)-", "to_node": "roadm Scranton" }, { - "from_node": "fiber (Portland \u2192 Seattle)-", - "to_node": "fiber (Seattle \u2192 Spokane)-" + "from_node": "roadm Seattle", + "to_node": "fiber (Seattle → Portland)-" }, { - "from_node": "fiber (Spokane \u2192 Seattle)-", - "to_node": "fiber (Seattle \u2192 Portland)-" + "from_node": "fiber (Portland → Seattle)-", + "to_node": "roadm Seattle" }, { - "from_node": "fiber (Billings \u2192 Spokane)-", - "to_node": "fiber (Spokane \u2192 Seattle)-" + "from_node": "roadm Seattle", + "to_node": "fiber (Seattle → Spokane)-" }, { - "from_node": "fiber (Seattle \u2192 Spokane)-", - "to_node": "fiber (Spokane \u2192 Billings)-" + "from_node": "fiber (Spokane → Seattle)-", + "to_node": "roadm Seattle" }, { - "from_node": "fiber (Chicago \u2192 Springfield)-", - "to_node": "fiber (Springfield \u2192 St_Louis)-" + "from_node": "roadm Spokane", + "to_node": "fiber (Spokane → Billings)-" }, { - "from_node": "fiber (St_Louis \u2192 Springfield)-", - "to_node": "fiber (Springfield \u2192 Chicago)-" + "from_node": "fiber (Billings → Spokane)-", + "to_node": "roadm Spokane" + }, + { + "from_node": "roadm Spokane", + "to_node": "fiber (Spokane → Seattle)-" + }, + { + "from_node": "fiber (Seattle → Spokane)-", + "to_node": "roadm Spokane" + }, + { + "from_node": "roadm Springfield", + "to_node": "fiber (Springfield → Chicago)-" + }, + { + "from_node": "fiber (Chicago → Springfield)-", + "to_node": "roadm Springfield" + }, + { + "from_node": "roadm Springfield", + "to_node": "fiber (Springfield → St_Louis)-" + }, + { + "from_node": "fiber (St_Louis → Springfield)-", + "to_node": "roadm Springfield" }, { "from_node": "roadm St_Louis", - "to_node": "fiber (St_Louis \u2192 Kansas_City)-" + "to_node": "fiber (St_Louis → Kansas_City)-" }, { - "from_node": "fiber (Kansas_City \u2192 St_Louis)-", + "from_node": "fiber (Kansas_City → St_Louis)-", "to_node": "roadm St_Louis" }, { "from_node": "roadm St_Louis", - "to_node": "fiber (St_Louis \u2192 Louisville)-" + "to_node": "fiber (St_Louis → Louisville)-" }, { - "from_node": "fiber (Louisville \u2192 St_Louis)-", + "from_node": "fiber (Louisville → St_Louis)-", "to_node": "roadm St_Louis" }, { "from_node": "roadm St_Louis", - "to_node": "fiber (St_Louis \u2192 Springfield)-" + "to_node": "fiber (St_Louis → Springfield)-" }, { - "from_node": "fiber (Springfield \u2192 St_Louis)-", + "from_node": "fiber (Springfield → St_Louis)-", "to_node": "roadm St_Louis" }, { "from_node": "roadm Syracuse", - "to_node": "fiber (Syracuse \u2192 Albany)-" + "to_node": "fiber (Syracuse → Albany)-" }, { - "from_node": "fiber (Albany \u2192 Syracuse)-", + "from_node": "fiber (Albany → Syracuse)-", "to_node": "roadm Syracuse" }, { "from_node": "roadm Syracuse", - "to_node": "fiber (Syracuse \u2192 Rochester)-" + "to_node": "fiber (Syracuse → Rochester)-" }, { - "from_node": "fiber (Rochester \u2192 Syracuse)-", + "from_node": "fiber (Rochester → Syracuse)-", "to_node": "roadm Syracuse" }, { "from_node": "roadm Syracuse", - "to_node": "fiber (Syracuse \u2192 Scranton)-" + "to_node": "fiber (Syracuse → Scranton)-" }, { - "from_node": "fiber (Scranton \u2192 Syracuse)-", + "from_node": "fiber (Scranton → Syracuse)-", "to_node": "roadm Syracuse" }, { - "from_node": "fiber (New_Orleans \u2192 Tallahassee)-", - "to_node": "fiber (Tallahassee \u2192 Tampa)-" + "from_node": "roadm Tallahassee", + "to_node": "fiber (Tallahassee → New_Orleans)-" }, { - "from_node": "fiber (Tampa \u2192 Tallahassee)-", - "to_node": "fiber (Tallahassee \u2192 New_Orleans)-" + "from_node": "fiber (New_Orleans → Tallahassee)-", + "to_node": "roadm Tallahassee" }, { - "from_node": "fiber (Miami \u2192 Tampa)-", - "to_node": "fiber (Tampa \u2192 Tallahassee)-" + "from_node": "roadm Tallahassee", + "to_node": "fiber (Tallahassee → Tampa)-" }, { - "from_node": "fiber (Tallahassee \u2192 Tampa)-", - "to_node": "fiber (Tampa \u2192 Miami)-" + "from_node": "fiber (Tampa → Tallahassee)-", + "to_node": "roadm Tallahassee" }, { - "from_node": "fiber (Cleveland \u2192 Toledo)-", - "to_node": "fiber (Toledo \u2192 Detroit)-" + "from_node": "roadm Tampa", + "to_node": "fiber (Tampa → Miami)-" }, { - "from_node": "fiber (Detroit \u2192 Toledo)-", - "to_node": "fiber (Toledo \u2192 Cleveland)-" + "from_node": "fiber (Miami → Tampa)-", + "to_node": "roadm Tampa" }, { - "from_node": "fiber (El_Paso \u2192 Tucson)-", - "to_node": "fiber (Tucson \u2192 Phoenix)-" + "from_node": "roadm Tampa", + "to_node": "fiber (Tampa → Tallahassee)-" }, { - "from_node": "fiber (Phoenix \u2192 Tucson)-", - "to_node": "fiber (Tucson \u2192 El_Paso)-" + "from_node": "fiber (Tallahassee → Tampa)-", + "to_node": "roadm Tampa" }, { - "from_node": "fiber (Kansas_City \u2192 Tulsa)-", - "to_node": "fiber (Tulsa \u2192 Oklahoma_City)-" + "from_node": "roadm Toledo", + "to_node": "fiber (Toledo → Cleveland)-" }, { - "from_node": "fiber (Oklahoma_City \u2192 Tulsa)-", - "to_node": "fiber (Tulsa \u2192 Kansas_City)-" + "from_node": "fiber (Cleveland → Toledo)-", + "to_node": "roadm Toledo" + }, + { + "from_node": "roadm Toledo", + "to_node": "fiber (Toledo → Detroit)-" + }, + { + "from_node": "fiber (Detroit → Toledo)-", + "to_node": "roadm Toledo" + }, + { + "from_node": "roadm Tucson", + "to_node": "fiber (Tucson → El_Paso)-" + }, + { + "from_node": "fiber (El_Paso → Tucson)-", + "to_node": "roadm Tucson" + }, + { + "from_node": "roadm Tucson", + "to_node": "fiber (Tucson → Phoenix)-" + }, + { + "from_node": "fiber (Phoenix → Tucson)-", + "to_node": "roadm Tucson" + }, + { + "from_node": "roadm Tulsa", + "to_node": "fiber (Tulsa → Kansas_City)-" + }, + { + "from_node": "fiber (Kansas_City → Tulsa)-", + "to_node": "roadm Tulsa" + }, + { + "from_node": "roadm Tulsa", + "to_node": "fiber (Tulsa → Oklahoma_City)-" + }, + { + "from_node": "fiber (Oklahoma_City → Tulsa)-", + "to_node": "roadm Tulsa" }, { "from_node": "roadm Washington_DC", - "to_node": "fiber (Washington_DC \u2192 Baltimore)-" + "to_node": "fiber (Washington_DC → Baltimore)-" }, { - "from_node": "fiber (Baltimore \u2192 Washington_DC)-", + "from_node": "fiber (Baltimore → Washington_DC)-", "to_node": "roadm Washington_DC" }, { "from_node": "roadm Washington_DC", - "to_node": "fiber (Washington_DC \u2192 Cincinnati)-" + "to_node": "fiber (Washington_DC → Cincinnati)-" }, { - "from_node": "fiber (Cincinnati \u2192 Washington_DC)-", + "from_node": "fiber (Cincinnati → Washington_DC)-", "to_node": "roadm Washington_DC" }, { "from_node": "roadm Washington_DC", - "to_node": "fiber (Washington_DC \u2192 London)-" + "to_node": "fiber (Washington_DC → London)-" }, { - "from_node": "fiber (London \u2192 Washington_DC)-", + "from_node": "fiber (London → Washington_DC)-", "to_node": "roadm Washington_DC" }, { "from_node": "roadm Washington_DC", - "to_node": "fiber (Washington_DC \u2192 Richmond)-" + "to_node": "fiber (Washington_DC → Richmond)-" }, { - "from_node": "fiber (Richmond \u2192 Washington_DC)-", + "from_node": "fiber (Richmond → Washington_DC)-", "to_node": "roadm Washington_DC" }, { - "from_node": "fiber (Miami \u2192 West_Palm_Beach)-", - "to_node": "fiber (West_Palm_Beach \u2192 Orlando)-" + "from_node": "roadm West_Palm_Beach", + "to_node": "fiber (West_Palm_Beach → Miami)-" }, { - "from_node": "fiber (Orlando \u2192 West_Palm_Beach)-", - "to_node": "fiber (West_Palm_Beach \u2192 Miami)-" + "from_node": "fiber (Miami → West_Palm_Beach)-", + "to_node": "roadm West_Palm_Beach" }, { - "from_node": "fiber (New_York \u2192 Wilmington)-", - "to_node": "fiber (Wilmington \u2192 Norfolk)-" + "from_node": "roadm West_Palm_Beach", + "to_node": "fiber (West_Palm_Beach → Orlando)-" }, { - "from_node": "fiber (Norfolk \u2192 Wilmington)-", - "to_node": "fiber (Wilmington \u2192 New_York)-" + "from_node": "fiber (Orlando → West_Palm_Beach)-", + "to_node": "roadm West_Palm_Beach" + }, + { + "from_node": "roadm Wilmington", + "to_node": "fiber (Wilmington → New_York)-" + }, + { + "from_node": "fiber (New_York → Wilmington)-", + "to_node": "roadm Wilmington" + }, + { + "from_node": "roadm Wilmington", + "to_node": "fiber (Wilmington → Norfolk)-" + }, + { + "from_node": "fiber (Norfolk → Wilmington)-", + "to_node": "roadm Wilmington" }, { "from_node": "roadm Amsterdam", - "to_node": "fiber (Amsterdam \u2192 Berlin)-" + "to_node": "fiber (Amsterdam → Berlin)-" }, { - "from_node": "fiber (Berlin \u2192 Amsterdam)-", + "from_node": "fiber (Berlin → Amsterdam)-", "to_node": "roadm Amsterdam" }, { "from_node": "roadm Amsterdam", - "to_node": "fiber (Amsterdam \u2192 Brussels)-" + "to_node": "fiber (Amsterdam → Brussels)-" }, { - "from_node": "fiber (Brussels \u2192 Amsterdam)-", + "from_node": "fiber (Brussels → Amsterdam)-", "to_node": "roadm Amsterdam" }, { "from_node": "roadm Amsterdam", - "to_node": "fiber (Amsterdam \u2192 Frankfurt)-" + "to_node": "fiber (Amsterdam → Frankfurt)-" }, { - "from_node": "fiber (Frankfurt \u2192 Amsterdam)-", + "from_node": "fiber (Frankfurt → Amsterdam)-", "to_node": "roadm Amsterdam" }, { "from_node": "roadm Amsterdam", - "to_node": "fiber (Amsterdam \u2192 New_York)-" + "to_node": "fiber (Amsterdam → New_York)-" }, { - "from_node": "fiber (New_York \u2192 Amsterdam)-", + "from_node": "fiber (New_York → Amsterdam)-", "to_node": "roadm Amsterdam" }, { - "from_node": "fiber (Amsterdam \u2192 Berlin)-", - "to_node": "fiber (Berlin \u2192 Warsaw)-" + "from_node": "roadm Berlin", + "to_node": "fiber (Berlin → Amsterdam)-" }, { - "from_node": "fiber (Warsaw \u2192 Berlin)-", - "to_node": "fiber (Berlin \u2192 Amsterdam)-" + "from_node": "fiber (Amsterdam → Berlin)-", + "to_node": "roadm Berlin" }, { - "from_node": "fiber (Amsterdam \u2192 Brussels)-", - "to_node": "fiber (Brussels \u2192 London)-" + "from_node": "roadm Berlin", + "to_node": "fiber (Berlin → Warsaw)-" }, { - "from_node": "fiber (London \u2192 Brussels)-", - "to_node": "fiber (Brussels \u2192 Amsterdam)-" + "from_node": "fiber (Warsaw → Berlin)-", + "to_node": "roadm Berlin" }, { - "from_node": "fiber (Istanbul \u2192 Bucharest)-", - "to_node": "fiber (Bucharest \u2192 Warsaw)-" + "from_node": "roadm Brussels", + "to_node": "fiber (Brussels → Amsterdam)-" }, { - "from_node": "fiber (Warsaw \u2192 Bucharest)-", - "to_node": "fiber (Bucharest \u2192 Istanbul)-" + "from_node": "fiber (Amsterdam → Brussels)-", + "to_node": "roadm Brussels" }, { - "from_node": "fiber (Amsterdam \u2192 Frankfurt)-", - "to_node": "fiber (Frankfurt \u2192 Vienna)-" + "from_node": "roadm Brussels", + "to_node": "fiber (Brussels → London)-" }, { - "from_node": "fiber (Vienna \u2192 Frankfurt)-", - "to_node": "fiber (Frankfurt \u2192 Amsterdam)-" + "from_node": "fiber (London → Brussels)-", + "to_node": "roadm Brussels" + }, + { + "from_node": "roadm Bucharest", + "to_node": "fiber (Bucharest → Istanbul)-" + }, + { + "from_node": "fiber (Istanbul → Bucharest)-", + "to_node": "roadm Bucharest" + }, + { + "from_node": "roadm Bucharest", + "to_node": "fiber (Bucharest → Warsaw)-" + }, + { + "from_node": "fiber (Warsaw → Bucharest)-", + "to_node": "roadm Bucharest" + }, + { + "from_node": "roadm Frankfurt", + "to_node": "fiber (Frankfurt → Amsterdam)-" + }, + { + "from_node": "fiber (Amsterdam → Frankfurt)-", + "to_node": "roadm Frankfurt" + }, + { + "from_node": "roadm Frankfurt", + "to_node": "fiber (Frankfurt → Vienna)-" + }, + { + "from_node": "fiber (Vienna → Frankfurt)-", + "to_node": "roadm Frankfurt" }, { "from_node": "roadm Istanbul", - "to_node": "fiber (Istanbul \u2192 Bucharest)-" + "to_node": "fiber (Istanbul → Bucharest)-" }, { - "from_node": "fiber (Bucharest \u2192 Istanbul)-", + "from_node": "fiber (Bucharest → Istanbul)-", "to_node": "roadm Istanbul" }, { "from_node": "roadm Istanbul", - "to_node": "fiber (Istanbul \u2192 Delhi)-" + "to_node": "fiber (Istanbul → Delhi)-" }, { - "from_node": "fiber (Delhi \u2192 Istanbul)-", + "from_node": "fiber (Delhi → Istanbul)-", "to_node": "roadm Istanbul" }, { "from_node": "roadm Istanbul", - "to_node": "fiber (Istanbul \u2192 Rome)-" + "to_node": "fiber (Istanbul → Rome)-" }, { - "from_node": "fiber (Rome \u2192 Istanbul)-", + "from_node": "fiber (Rome → Istanbul)-", "to_node": "roadm Istanbul" }, { "from_node": "roadm London", - "to_node": "fiber (London \u2192 Brussels)-" + "to_node": "fiber (London → Brussels)-" }, { - "from_node": "fiber (Brussels \u2192 London)-", + "from_node": "fiber (Brussels → London)-", "to_node": "roadm London" }, { "from_node": "roadm London", - "to_node": "fiber (London \u2192 Paris)-" + "to_node": "fiber (London → Paris)-" }, { - "from_node": "fiber (Paris \u2192 London)-", + "from_node": "fiber (Paris → London)-", "to_node": "roadm London" }, { "from_node": "roadm London", - "to_node": "fiber (London \u2192 Washington_DC)-" + "to_node": "fiber (London → Washington_DC)-" }, { - "from_node": "fiber (Washington_DC \u2192 London)-", + "from_node": "fiber (Washington_DC → London)-", "to_node": "roadm London" }, { - "from_node": "fiber (Paris \u2192 Madrid)-", - "to_node": "fiber (Madrid \u2192 Zurich)-" + "from_node": "roadm Madrid", + "to_node": "fiber (Madrid → Paris)-" }, { - "from_node": "fiber (Zurich \u2192 Madrid)-", - "to_node": "fiber (Madrid \u2192 Paris)-" + "from_node": "fiber (Paris → Madrid)-", + "to_node": "roadm Madrid" + }, + { + "from_node": "roadm Madrid", + "to_node": "fiber (Madrid → Zurich)-" + }, + { + "from_node": "fiber (Zurich → Madrid)-", + "to_node": "roadm Madrid" }, { "from_node": "roadm Paris", - "to_node": "fiber (Paris \u2192 London)-" + "to_node": "fiber (Paris → London)-" }, { - "from_node": "fiber (London \u2192 Paris)-", + "from_node": "fiber (London → Paris)-", "to_node": "roadm Paris" }, { "from_node": "roadm Paris", - "to_node": "fiber (Paris \u2192 Madrid)-" + "to_node": "fiber (Paris → Madrid)-" }, { - "from_node": "fiber (Madrid \u2192 Paris)-", + "from_node": "fiber (Madrid → Paris)-", "to_node": "roadm Paris" }, { "from_node": "roadm Paris", - "to_node": "fiber (Paris \u2192 Miami)-" + "to_node": "fiber (Paris → Miami)-" }, { - "from_node": "fiber (Miami \u2192 Paris)-", + "from_node": "fiber (Miami → Paris)-", "to_node": "roadm Paris" }, { "from_node": "roadm Rome", - "to_node": "fiber (Rome \u2192 Istanbul)-" + "to_node": "fiber (Rome → Istanbul)-" }, { - "from_node": "fiber (Istanbul \u2192 Rome)-", + "from_node": "fiber (Istanbul → Rome)-", "to_node": "roadm Rome" }, { "from_node": "roadm Rome", - "to_node": "fiber (Rome \u2192 Mumbai)-" + "to_node": "fiber (Rome → Mumbai)-" }, { - "from_node": "fiber (Mumbai \u2192 Rome)-", + "from_node": "fiber (Mumbai → Rome)-", "to_node": "roadm Rome" }, { "from_node": "roadm Rome", - "to_node": "fiber (Rome \u2192 Vienna)-" + "to_node": "fiber (Rome → Vienna)-" }, { - "from_node": "fiber (Vienna \u2192 Rome)-", + "from_node": "fiber (Vienna → Rome)-", "to_node": "roadm Rome" }, { "from_node": "roadm Rome", - "to_node": "fiber (Rome \u2192 Zurich)-" + "to_node": "fiber (Rome → Zurich)-" }, { - "from_node": "fiber (Zurich \u2192 Rome)-", + "from_node": "fiber (Zurich → Rome)-", "to_node": "roadm Rome" }, { "from_node": "roadm Vienna", - "to_node": "fiber (Vienna \u2192 Frankfurt)-" + "to_node": "fiber (Vienna → Frankfurt)-" }, { - "from_node": "fiber (Frankfurt \u2192 Vienna)-", + "from_node": "fiber (Frankfurt → Vienna)-", "to_node": "roadm Vienna" }, { "from_node": "roadm Vienna", - "to_node": "fiber (Vienna \u2192 Rome)-" + "to_node": "fiber (Vienna → Rome)-" }, { - "from_node": "fiber (Rome \u2192 Vienna)-", + "from_node": "fiber (Rome → Vienna)-", "to_node": "roadm Vienna" }, { "from_node": "roadm Vienna", - "to_node": "fiber (Vienna \u2192 Warsaw)-" + "to_node": "fiber (Vienna → Warsaw)-" }, { - "from_node": "fiber (Warsaw \u2192 Vienna)-", + "from_node": "fiber (Warsaw → Vienna)-", "to_node": "roadm Vienna" }, { "from_node": "roadm Warsaw", - "to_node": "fiber (Warsaw \u2192 Berlin)-" + "to_node": "fiber (Warsaw → Berlin)-" }, { - "from_node": "fiber (Berlin \u2192 Warsaw)-", + "from_node": "fiber (Berlin → Warsaw)-", "to_node": "roadm Warsaw" }, { "from_node": "roadm Warsaw", - "to_node": "fiber (Warsaw \u2192 Bucharest)-" + "to_node": "fiber (Warsaw → Bucharest)-" }, { - "from_node": "fiber (Bucharest \u2192 Warsaw)-", + "from_node": "fiber (Bucharest → Warsaw)-", "to_node": "roadm Warsaw" }, { "from_node": "roadm Warsaw", - "to_node": "fiber (Warsaw \u2192 Vienna)-" + "to_node": "fiber (Warsaw → Vienna)-" }, { - "from_node": "fiber (Vienna \u2192 Warsaw)-", + "from_node": "fiber (Vienna → Warsaw)-", "to_node": "roadm Warsaw" }, { - "from_node": "fiber (Madrid \u2192 Zurich)-", - "to_node": "fiber (Zurich \u2192 Rome)-" + "from_node": "roadm Zurich", + "to_node": "fiber (Zurich → Madrid)-" }, { - "from_node": "fiber (Rome \u2192 Zurich)-", - "to_node": "fiber (Zurich \u2192 Madrid)-" + "from_node": "fiber (Madrid → Zurich)-", + "to_node": "roadm Zurich" }, { - "from_node": "fiber (Delhi \u2192 Bangkok)-", - "to_node": "fiber (Bangkok \u2192 Hong_Kong)-" + "from_node": "roadm Zurich", + "to_node": "fiber (Zurich → Rome)-" }, { - "from_node": "fiber (Hong_Kong \u2192 Bangkok)-", - "to_node": "fiber (Bangkok \u2192 Delhi)-" + "from_node": "fiber (Rome → Zurich)-", + "to_node": "roadm Zurich" }, { - "from_node": "fiber (Seoul \u2192 Beijing)-", - "to_node": "fiber (Beijing \u2192 Shanghai)-" + "from_node": "roadm Bangkok", + "to_node": "fiber (Bangkok → Delhi)-" }, { - "from_node": "fiber (Shanghai \u2192 Beijing)-", - "to_node": "fiber (Beijing \u2192 Seoul)-" + "from_node": "fiber (Delhi → Bangkok)-", + "to_node": "roadm Bangkok" + }, + { + "from_node": "roadm Bangkok", + "to_node": "fiber (Bangkok → Hong_Kong)-" + }, + { + "from_node": "fiber (Hong_Kong → Bangkok)-", + "to_node": "roadm Bangkok" + }, + { + "from_node": "roadm Beijing", + "to_node": "fiber (Beijing → Seoul)-" + }, + { + "from_node": "fiber (Seoul → Beijing)-", + "to_node": "roadm Beijing" + }, + { + "from_node": "roadm Beijing", + "to_node": "fiber (Beijing → Shanghai)-" + }, + { + "from_node": "fiber (Shanghai → Beijing)-", + "to_node": "roadm Beijing" }, { "from_node": "roadm Delhi", - "to_node": "fiber (Delhi \u2192 Bangkok)-" + "to_node": "fiber (Delhi → Bangkok)-" }, { - "from_node": "fiber (Bangkok \u2192 Delhi)-", + "from_node": "fiber (Bangkok → Delhi)-", "to_node": "roadm Delhi" }, { "from_node": "roadm Delhi", - "to_node": "fiber (Delhi \u2192 Istanbul)-" + "to_node": "fiber (Delhi → Istanbul)-" }, { - "from_node": "fiber (Istanbul \u2192 Delhi)-", + "from_node": "fiber (Istanbul → Delhi)-", "to_node": "roadm Delhi" }, { "from_node": "roadm Delhi", - "to_node": "fiber (Delhi \u2192 Mumbai)-" + "to_node": "fiber (Delhi → Mumbai)-" }, { - "from_node": "fiber (Mumbai \u2192 Delhi)-", + "from_node": "fiber (Mumbai → Delhi)-", "to_node": "roadm Delhi" }, { "from_node": "roadm Hong_Kong", - "to_node": "fiber (Hong_Kong \u2192 Bangkok)-" + "to_node": "fiber (Hong_Kong → Bangkok)-" }, { - "from_node": "fiber (Bangkok \u2192 Hong_Kong)-", + "from_node": "fiber (Bangkok → Hong_Kong)-", "to_node": "roadm Hong_Kong" }, { "from_node": "roadm Hong_Kong", - "to_node": "fiber (Hong_Kong \u2192 Shanghai)-" + "to_node": "fiber (Hong_Kong → Shanghai)-" }, { - "from_node": "fiber (Shanghai \u2192 Hong_Kong)-", + "from_node": "fiber (Shanghai → Hong_Kong)-", "to_node": "roadm Hong_Kong" }, { "from_node": "roadm Hong_Kong", - "to_node": "fiber (Hong_Kong \u2192 Sydney)-" + "to_node": "fiber (Hong_Kong → Sydney)-" }, { - "from_node": "fiber (Sydney \u2192 Hong_Kong)-", + "from_node": "fiber (Sydney → Hong_Kong)-", "to_node": "roadm Hong_Kong" }, { "from_node": "roadm Hong_Kong", - "to_node": "fiber (Hong_Kong \u2192 Taipei)-" + "to_node": "fiber (Hong_Kong → Taipei)-" }, { - "from_node": "fiber (Taipei \u2192 Hong_Kong)-", + "from_node": "fiber (Taipei → Hong_Kong)-", "to_node": "roadm Hong_Kong" }, { "from_node": "roadm Honolulu", - "to_node": "fiber (Honolulu \u2192 Los_Angeles)-" + "to_node": "fiber (Honolulu → Los_Angeles)-" }, { - "from_node": "fiber (Los_Angeles \u2192 Honolulu)-", + "from_node": "fiber (Los_Angeles → Honolulu)-", "to_node": "roadm Honolulu" }, { "from_node": "roadm Honolulu", - "to_node": "fiber (Honolulu \u2192 Sydney)-" + "to_node": "fiber (Honolulu → Sydney)-" }, { - "from_node": "fiber (Sydney \u2192 Honolulu)-", + "from_node": "fiber (Sydney → Honolulu)-", "to_node": "roadm Honolulu" }, { "from_node": "roadm Honolulu", - "to_node": "fiber (Honolulu \u2192 Taipei)-" + "to_node": "fiber (Honolulu → Taipei)-" }, { - "from_node": "fiber (Taipei \u2192 Honolulu)-", + "from_node": "fiber (Taipei → Honolulu)-", "to_node": "roadm Honolulu" }, { "from_node": "roadm Mumbai", - "to_node": "fiber (Mumbai \u2192 Delhi)-" + "to_node": "fiber (Mumbai → Delhi)-" }, { - "from_node": "fiber (Delhi \u2192 Mumbai)-", + "from_node": "fiber (Delhi → Mumbai)-", "to_node": "roadm Mumbai" }, { "from_node": "roadm Mumbai", - "to_node": "fiber (Mumbai \u2192 Rome)-" + "to_node": "fiber (Mumbai → Rome)-" }, { - "from_node": "fiber (Rome \u2192 Mumbai)-", + "from_node": "fiber (Rome → Mumbai)-", "to_node": "roadm Mumbai" }, { "from_node": "roadm Mumbai", - "to_node": "fiber (Mumbai \u2192 Singapore)-" + "to_node": "fiber (Mumbai → Singapore)-" }, { - "from_node": "fiber (Singapore \u2192 Mumbai)-", + "from_node": "fiber (Singapore → Mumbai)-", "to_node": "roadm Mumbai" }, { - "from_node": "fiber (Beijing \u2192 Seoul)-", - "to_node": "fiber (Seoul \u2192 Tokyo)-" + "from_node": "roadm Seoul", + "to_node": "fiber (Seoul → Beijing)-" }, { - "from_node": "fiber (Tokyo \u2192 Seoul)-", - "to_node": "fiber (Seoul \u2192 Beijing)-" + "from_node": "fiber (Beijing → Seoul)-", + "to_node": "roadm Seoul" }, { - "from_node": "fiber (Beijing \u2192 Shanghai)-", - "to_node": "fiber (Shanghai \u2192 Hong_Kong)-" + "from_node": "roadm Seoul", + "to_node": "fiber (Seoul → Tokyo)-" }, { - "from_node": "fiber (Hong_Kong \u2192 Shanghai)-", - "to_node": "fiber (Shanghai \u2192 Beijing)-" + "from_node": "fiber (Tokyo → Seoul)-", + "to_node": "roadm Seoul" }, { - "from_node": "fiber (Mumbai \u2192 Singapore)-", - "to_node": "fiber (Singapore \u2192 Sydney)-" + "from_node": "roadm Shanghai", + "to_node": "fiber (Shanghai → Beijing)-" }, { - "from_node": "fiber (Sydney \u2192 Singapore)-", - "to_node": "fiber (Singapore \u2192 Mumbai)-" + "from_node": "fiber (Beijing → Shanghai)-", + "to_node": "roadm Shanghai" + }, + { + "from_node": "roadm Shanghai", + "to_node": "fiber (Shanghai → Hong_Kong)-" + }, + { + "from_node": "fiber (Hong_Kong → Shanghai)-", + "to_node": "roadm Shanghai" + }, + { + "from_node": "roadm Singapore", + "to_node": "fiber (Singapore → Mumbai)-" + }, + { + "from_node": "fiber (Mumbai → Singapore)-", + "to_node": "roadm Singapore" + }, + { + "from_node": "roadm Singapore", + "to_node": "fiber (Singapore → Sydney)-" + }, + { + "from_node": "fiber (Sydney → Singapore)-", + "to_node": "roadm Singapore" }, { "from_node": "roadm Sydney", - "to_node": "fiber (Sydney \u2192 Hong_Kong)-" + "to_node": "fiber (Sydney → Hong_Kong)-" }, { - "from_node": "fiber (Hong_Kong \u2192 Sydney)-", + "from_node": "fiber (Hong_Kong → Sydney)-", "to_node": "roadm Sydney" }, { "from_node": "roadm Sydney", - "to_node": "fiber (Sydney \u2192 Honolulu)-" + "to_node": "fiber (Sydney → Honolulu)-" }, { - "from_node": "fiber (Honolulu \u2192 Sydney)-", + "from_node": "fiber (Honolulu → Sydney)-", "to_node": "roadm Sydney" }, { "from_node": "roadm Sydney", - "to_node": "fiber (Sydney \u2192 Singapore)-" + "to_node": "fiber (Sydney → Singapore)-" }, { - "from_node": "fiber (Singapore \u2192 Sydney)-", + "from_node": "fiber (Singapore → Sydney)-", "to_node": "roadm Sydney" }, { "from_node": "roadm Taipei", - "to_node": "fiber (Taipei \u2192 Hong_Kong)-" + "to_node": "fiber (Taipei → Hong_Kong)-" }, { - "from_node": "fiber (Hong_Kong \u2192 Taipei)-", + "from_node": "fiber (Hong_Kong → Taipei)-", "to_node": "roadm Taipei" }, { "from_node": "roadm Taipei", - "to_node": "fiber (Taipei \u2192 Honolulu)-" + "to_node": "fiber (Taipei → Honolulu)-" }, { - "from_node": "fiber (Honolulu \u2192 Taipei)-", + "from_node": "fiber (Honolulu → Taipei)-", "to_node": "roadm Taipei" }, { "from_node": "roadm Taipei", - "to_node": "fiber (Taipei \u2192 Oakland)-" + "to_node": "fiber (Taipei → Oakland)-" }, { - "from_node": "fiber (Oakland \u2192 Taipei)-", + "from_node": "fiber (Oakland → Taipei)-", "to_node": "roadm Taipei" }, { "from_node": "roadm Taipei", - "to_node": "fiber (Taipei \u2192 Tokyo)-" + "to_node": "fiber (Taipei → Tokyo)-" }, { - "from_node": "fiber (Tokyo \u2192 Taipei)-", + "from_node": "fiber (Tokyo → Taipei)-", "to_node": "roadm Taipei" }, { "from_node": "roadm Tokyo", - "to_node": "fiber (Tokyo \u2192 Portland)-" + "to_node": "fiber (Tokyo → Portland)-" }, { - "from_node": "fiber (Portland \u2192 Tokyo)-", + "from_node": "fiber (Portland → Tokyo)-", "to_node": "roadm Tokyo" }, { "from_node": "roadm Tokyo", - "to_node": "fiber (Tokyo \u2192 Seoul)-" + "to_node": "fiber (Tokyo → Seoul)-" }, { - "from_node": "fiber (Seoul \u2192 Tokyo)-", + "from_node": "fiber (Seoul → Tokyo)-", "to_node": "roadm Tokyo" }, { "from_node": "roadm Tokyo", - "to_node": "fiber (Tokyo \u2192 Taipei)-" + "to_node": "fiber (Tokyo → Taipei)-" }, { - "from_node": "fiber (Taipei \u2192 Tokyo)-", + "from_node": "fiber (Taipei → Tokyo)-", "to_node": "roadm Tokyo" }, + { + "from_node": "trx Abilene", + "to_node": "roadm Abilene" + }, + { + "from_node": "roadm Abilene", + "to_node": "trx Abilene" + }, + { + "from_node": "trx Albany", + "to_node": "roadm Albany" + }, + { + "from_node": "roadm Albany", + "to_node": "trx Albany" + }, { "from_node": "trx Albuquerque", "to_node": "roadm Albuquerque" @@ -7922,6 +9506,14 @@ "from_node": "roadm Atlanta", "to_node": "trx Atlanta" }, + { + "from_node": "trx Austin", + "to_node": "roadm Austin" + }, + { + "from_node": "roadm Austin", + "to_node": "trx Austin" + }, { "from_node": "trx Baltimore", "to_node": "roadm Baltimore" @@ -7930,6 +9522,14 @@ "from_node": "roadm Baltimore", "to_node": "trx Baltimore" }, + { + "from_node": "trx Baton_Rouge", + "to_node": "roadm Baton_Rouge" + }, + { + "from_node": "roadm Baton_Rouge", + "to_node": "trx Baton_Rouge" + }, { "from_node": "trx Billings", "to_node": "roadm Billings" @@ -7946,6 +9546,46 @@ "from_node": "roadm Birmingham", "to_node": "trx Birmingham" }, + { + "from_node": "trx Bismarck", + "to_node": "roadm Bismarck" + }, + { + "from_node": "roadm Bismarck", + "to_node": "trx Bismarck" + }, + { + "from_node": "trx Boston", + "to_node": "roadm Boston" + }, + { + "from_node": "roadm Boston", + "to_node": "trx Boston" + }, + { + "from_node": "trx Buffalo", + "to_node": "roadm Buffalo" + }, + { + "from_node": "roadm Buffalo", + "to_node": "trx Buffalo" + }, + { + "from_node": "trx Charleston", + "to_node": "roadm Charleston" + }, + { + "from_node": "roadm Charleston", + "to_node": "trx Charleston" + }, + { + "from_node": "trx Charlotte", + "to_node": "roadm Charlotte" + }, + { + "from_node": "roadm Charlotte", + "to_node": "trx Charlotte" + }, { "from_node": "trx Chicago", "to_node": "roadm Chicago" @@ -7994,6 +9634,14 @@ "from_node": "roadm Denver", "to_node": "trx Denver" }, + { + "from_node": "trx Detroit", + "to_node": "roadm Detroit" + }, + { + "from_node": "roadm Detroit", + "to_node": "trx Detroit" + }, { "from_node": "trx El_Paso", "to_node": "roadm El_Paso" @@ -8018,6 +9666,14 @@ "from_node": "roadm Greensboro", "to_node": "trx Greensboro" }, + { + "from_node": "trx Hartford", + "to_node": "roadm Hartford" + }, + { + "from_node": "roadm Hartford", + "to_node": "trx Hartford" + }, { "from_node": "trx Houston", "to_node": "roadm Houston" @@ -8050,6 +9706,22 @@ "from_node": "roadm Las_Vegas", "to_node": "trx Las_Vegas" }, + { + "from_node": "trx Little_Rock", + "to_node": "roadm Little_Rock" + }, + { + "from_node": "roadm Little_Rock", + "to_node": "trx Little_Rock" + }, + { + "from_node": "trx Long_Island", + "to_node": "roadm Long_Island" + }, + { + "from_node": "roadm Long_Island", + "to_node": "trx Long_Island" + }, { "from_node": "trx Los_Angeles", "to_node": "roadm Los_Angeles" @@ -8066,6 +9738,14 @@ "from_node": "roadm Louisville", "to_node": "trx Louisville" }, + { + "from_node": "trx Memphis", + "to_node": "roadm Memphis" + }, + { + "from_node": "roadm Memphis", + "to_node": "trx Memphis" + }, { "from_node": "trx Miami", "to_node": "roadm Miami" @@ -8074,6 +9754,14 @@ "from_node": "roadm Miami", "to_node": "trx Miami" }, + { + "from_node": "trx Milwaukee", + "to_node": "roadm Milwaukee" + }, + { + "from_node": "roadm Milwaukee", + "to_node": "trx Milwaukee" + }, { "from_node": "trx Minneapolis", "to_node": "roadm Minneapolis" @@ -8106,6 +9794,22 @@ "from_node": "roadm New_York", "to_node": "trx New_York" }, + { + "from_node": "trx Newark", + "to_node": "roadm Newark" + }, + { + "from_node": "roadm Newark", + "to_node": "trx Newark" + }, + { + "from_node": "trx Norfolk", + "to_node": "roadm Norfolk" + }, + { + "from_node": "roadm Norfolk", + "to_node": "trx Norfolk" + }, { "from_node": "trx Oakland", "to_node": "roadm Oakland" @@ -8114,6 +9818,14 @@ "from_node": "roadm Oakland", "to_node": "trx Oakland" }, + { + "from_node": "trx Oklahoma_City", + "to_node": "roadm Oklahoma_City" + }, + { + "from_node": "roadm Oklahoma_City", + "to_node": "trx Oklahoma_City" + }, { "from_node": "trx Omaha", "to_node": "roadm Omaha" @@ -8122,6 +9834,14 @@ "from_node": "roadm Omaha", "to_node": "trx Omaha" }, + { + "from_node": "trx Orlando", + "to_node": "roadm Orlando" + }, + { + "from_node": "roadm Orlando", + "to_node": "trx Orlando" + }, { "from_node": "trx Philadelphia", "to_node": "roadm Philadelphia" @@ -8154,6 +9874,14 @@ "from_node": "roadm Portland", "to_node": "trx Portland" }, + { + "from_node": "trx Providence", + "to_node": "roadm Providence" + }, + { + "from_node": "roadm Providence", + "to_node": "trx Providence" + }, { "from_node": "trx Raleigh", "to_node": "roadm Raleigh" @@ -8162,6 +9890,30 @@ "from_node": "roadm Raleigh", "to_node": "trx Raleigh" }, + { + "from_node": "trx Richmond", + "to_node": "roadm Richmond" + }, + { + "from_node": "roadm Richmond", + "to_node": "trx Richmond" + }, + { + "from_node": "trx Rochester", + "to_node": "roadm Rochester" + }, + { + "from_node": "roadm Rochester", + "to_node": "trx Rochester" + }, + { + "from_node": "trx Sacramento", + "to_node": "roadm Sacramento" + }, + { + "from_node": "roadm Sacramento", + "to_node": "trx Sacramento" + }, { "from_node": "trx Salt_Lake_City", "to_node": "roadm Salt_Lake_City" @@ -8170,6 +9922,46 @@ "from_node": "roadm Salt_Lake_City", "to_node": "trx Salt_Lake_City" }, + { + "from_node": "trx San_Antonio", + "to_node": "roadm San_Antonio" + }, + { + "from_node": "roadm San_Antonio", + "to_node": "trx San_Antonio" + }, + { + "from_node": "trx San_Diego", + "to_node": "roadm San_Diego" + }, + { + "from_node": "roadm San_Diego", + "to_node": "trx San_Diego" + }, + { + "from_node": "trx San_Francisco", + "to_node": "roadm San_Francisco" + }, + { + "from_node": "roadm San_Francisco", + "to_node": "trx San_Francisco" + }, + { + "from_node": "trx San_Jose", + "to_node": "roadm San_Jose" + }, + { + "from_node": "roadm San_Jose", + "to_node": "trx San_Jose" + }, + { + "from_node": "trx Santa_Barbara", + "to_node": "roadm Santa_Barbara" + }, + { + "from_node": "roadm Santa_Barbara", + "to_node": "trx Santa_Barbara" + }, { "from_node": "trx Scranton", "to_node": "roadm Scranton" @@ -8178,6 +9970,30 @@ "from_node": "roadm Scranton", "to_node": "trx Scranton" }, + { + "from_node": "trx Seattle", + "to_node": "roadm Seattle" + }, + { + "from_node": "roadm Seattle", + "to_node": "trx Seattle" + }, + { + "from_node": "trx Spokane", + "to_node": "roadm Spokane" + }, + { + "from_node": "roadm Spokane", + "to_node": "trx Spokane" + }, + { + "from_node": "trx Springfield", + "to_node": "roadm Springfield" + }, + { + "from_node": "roadm Springfield", + "to_node": "trx Springfield" + }, { "from_node": "trx St_Louis", "to_node": "roadm St_Louis" @@ -8194,6 +10010,46 @@ "from_node": "roadm Syracuse", "to_node": "trx Syracuse" }, + { + "from_node": "trx Tallahassee", + "to_node": "roadm Tallahassee" + }, + { + "from_node": "roadm Tallahassee", + "to_node": "trx Tallahassee" + }, + { + "from_node": "trx Tampa", + "to_node": "roadm Tampa" + }, + { + "from_node": "roadm Tampa", + "to_node": "trx Tampa" + }, + { + "from_node": "trx Toledo", + "to_node": "roadm Toledo" + }, + { + "from_node": "roadm Toledo", + "to_node": "trx Toledo" + }, + { + "from_node": "trx Tucson", + "to_node": "roadm Tucson" + }, + { + "from_node": "roadm Tucson", + "to_node": "trx Tucson" + }, + { + "from_node": "trx Tulsa", + "to_node": "roadm Tulsa" + }, + { + "from_node": "roadm Tulsa", + "to_node": "trx Tulsa" + }, { "from_node": "trx Washington_DC", "to_node": "roadm Washington_DC" @@ -8202,6 +10058,22 @@ "from_node": "roadm Washington_DC", "to_node": "trx Washington_DC" }, + { + "from_node": "trx West_Palm_Beach", + "to_node": "roadm West_Palm_Beach" + }, + { + "from_node": "roadm West_Palm_Beach", + "to_node": "trx West_Palm_Beach" + }, + { + "from_node": "trx Wilmington", + "to_node": "roadm Wilmington" + }, + { + "from_node": "roadm Wilmington", + "to_node": "trx Wilmington" + }, { "from_node": "trx Amsterdam", "to_node": "roadm Amsterdam" @@ -8210,6 +10082,38 @@ "from_node": "roadm Amsterdam", "to_node": "trx Amsterdam" }, + { + "from_node": "trx Berlin", + "to_node": "roadm Berlin" + }, + { + "from_node": "roadm Berlin", + "to_node": "trx Berlin" + }, + { + "from_node": "trx Brussels", + "to_node": "roadm Brussels" + }, + { + "from_node": "roadm Brussels", + "to_node": "trx Brussels" + }, + { + "from_node": "trx Bucharest", + "to_node": "roadm Bucharest" + }, + { + "from_node": "roadm Bucharest", + "to_node": "trx Bucharest" + }, + { + "from_node": "trx Frankfurt", + "to_node": "roadm Frankfurt" + }, + { + "from_node": "roadm Frankfurt", + "to_node": "trx Frankfurt" + }, { "from_node": "trx Istanbul", "to_node": "roadm Istanbul" @@ -8226,6 +10130,14 @@ "from_node": "roadm London", "to_node": "trx London" }, + { + "from_node": "trx Madrid", + "to_node": "roadm Madrid" + }, + { + "from_node": "roadm Madrid", + "to_node": "trx Madrid" + }, { "from_node": "trx Paris", "to_node": "roadm Paris" @@ -8258,6 +10170,30 @@ "from_node": "roadm Warsaw", "to_node": "trx Warsaw" }, + { + "from_node": "trx Zurich", + "to_node": "roadm Zurich" + }, + { + "from_node": "roadm Zurich", + "to_node": "trx Zurich" + }, + { + "from_node": "trx Bangkok", + "to_node": "roadm Bangkok" + }, + { + "from_node": "roadm Bangkok", + "to_node": "trx Bangkok" + }, + { + "from_node": "trx Beijing", + "to_node": "roadm Beijing" + }, + { + "from_node": "roadm Beijing", + "to_node": "trx Beijing" + }, { "from_node": "trx Delhi", "to_node": "roadm Delhi" @@ -8290,6 +10226,30 @@ "from_node": "roadm Mumbai", "to_node": "trx Mumbai" }, + { + "from_node": "trx Seoul", + "to_node": "roadm Seoul" + }, + { + "from_node": "roadm Seoul", + "to_node": "trx Seoul" + }, + { + "from_node": "trx Shanghai", + "to_node": "roadm Shanghai" + }, + { + "from_node": "roadm Shanghai", + "to_node": "trx Shanghai" + }, + { + "from_node": "trx Singapore", + "to_node": "roadm Singapore" + }, + { + "from_node": "roadm Singapore", + "to_node": "trx Singapore" + }, { "from_node": "trx Sydney", "to_node": "roadm Sydney" diff --git a/examples/CORONET_Global_Topology.xls b/examples/CORONET_Global_Topology.xls index 952d008b..6dea7f16 100644 Binary files a/examples/CORONET_Global_Topology.xls and b/examples/CORONET_Global_Topology.xls differ diff --git a/examples/convert_service_sheet.py b/examples/convert_service_sheet.py deleted file mode 100644 index 4fbe8881..00000000 --- a/examples/convert_service_sheet.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -""" -convert_service_sheet.py -======================== - -XLS parser that can be called to create a JSON request file in accordance with -Yang model for requesting path computation. - -See: draft-ietf-teas-yang-path-computation-01.txt -""" - -from argparse import ArgumentParser -from logging import getLogger, basicConfig, CRITICAL, DEBUG, INFO -from json import dumps - -from gnpy.core.service_sheet import Request, Element, Request_element -from gnpy.core.service_sheet import parse_row, parse_excel, convert_service_sheet - -logger = getLogger(__name__) - -if __name__ == '__main__': - args = parser.parse_args() - basicConfig(level={2: DEBUG, 1: INFO, 0: CRITICAL}.get(args.verbose, CRITICAL)) - logger.info(f'Converting Service sheet {args.workbook!r} into gnpy JSON format') - if args.output is None: - data = convert_service_sheet(args.workbook,'eqpt_config.json') - print(dumps(data, indent=2)) - else: - data = convert_service_sheet(args.workbook,'eqpt_config.json',args.output) diff --git a/examples/create_eqpt_sheet.py b/examples/create_eqpt_sheet.py index f1e247f7..b0f7b4ca 100644 --- a/examples/create_eqpt_sheet.py +++ b/examples/create_eqpt_sheet.py @@ -70,7 +70,7 @@ def read_excel(input_filename): def create_eqt_template(links,nodes, links_by_src , links_by_dest, input_filename): output_filename = f'{input_filename[:-4]}_eqpt_sheet.txt' - with open(output_filename,'w') as my_file : + with open(output_filename, 'w', encoding='utf-8') as my_file: # print header similar to excel my_file.write('OPTIONAL\n\n\n\ \t\tNode a egress amp (from a to z)\t\t\t\t\tNode a ingress amp (from z to a) \ diff --git a/examples/eqpt_config.json b/examples/eqpt_config.json index dc255f34..57abcc17 100644 --- a/examples/eqpt_config.json +++ b/examples/eqpt_config.json @@ -19,6 +19,24 @@ "allowed_for_design": false }, { + "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 + }, + { + "type_variety": "standard", + "type_def": "openroadm", + "gain_flatmax": 27, + "gain_min": 12, + "p_max": 22, + "nf_coef": [-5.952e-4,-6.250e-2,-1.071,28.99], + "allowed_for_design": false + }, + { "type_variety": "std_medium_gain", "type_def": "variable_gain", "gain_flatmax": 26, @@ -48,22 +66,22 @@ "p_max": 21, "nf0": 5.5, "allowed_for_design": false - }, - { - "type_variety": "test", - "type_def": "variable_gain", - "gain_flatmax": 25, - "gain_min": 15, - "p_max": 21, - "nf_min": 7, - "nf_max": 11, - "allowed_for_design": false - } + } ], "Fiber":[{ "type_variety": "SSMF", "dispersion": 1.67e-05, "gamma": 0.00127 + }, + { + "type_variety": "NZDF", + "dispersion": 0.5e-05, + "gamma": 0.00146 + }, + { + "type_variety": "LOF", + "dispersion": 2.2e-05, + "gamma": 0.000843 } ], "Spans":[{ @@ -80,7 +98,8 @@ ], "Roadms":[{ "gain_mode_default_loss": 20, - "power_mode_pref": -20 + "power_mode_pout_target": -20, + "add_drop_osnr": 38 }], "SI":[{ "f_min": 191.3e12, @@ -90,8 +109,8 @@ "power_dbm": 0, "power_range_db": [0,0,0.5], "roll_off": 0.15, - "OSNR": 11, - "bit_rate":100e9 + "tx_osnr": 40, + "sys_margins": 0 }], "Transceiver":[ { @@ -107,28 +126,20 @@ "baud_rate": 32e9, "OSNR": 11, "bit_rate": 100e9, - "roll_off": 0.15 + "roll_off": 0.15, + "tx_osnr": 40, + "min_spacing": 37.5e9, + "cost":1 }, { "format": "mode 2", "baud_rate": 66e9, "OSNR": 15, "bit_rate": 200e9, - "roll_off": 0.15 - }, - { - "format": "PS_SP64_1", - "baud_rate": 32e9, - "OSNR": 11, - "bit_rate": 100e9, - "roll_off": 0.15 - }, - { - "format": "mode_2", - "baud_rate": 66e9, - "OSNR": 15, - "bit_rate": 200e9, - "roll_off": 0.15 + "roll_off": 0.15, + "tx_osnr": 40, + "min_spacing": 75e9, + "cost":1 } ] }, @@ -140,44 +151,45 @@ }, "mode":[ { - "format": "16QAM", - "baud_rate": 32e9, - "OSNR": 19, - "bit_rate": 200e9, - "roll_off": 0.15 - }, - { - "format": "QPSK", + "format": "mode 1", "baud_rate": 32e9, "OSNR": 12, "bit_rate": 100e9, - "roll_off": 0.15 - } - - ] - }, - { - "type_variety": "Voyager_16QAM", - "frequency":{ - "min": 191.35e12, - "max": 196.1e12 - }, - "mode":[ - { - "format": "16QAM", - "baud_rate": 32e9, - "OSNR": 19, - "bit_rate": 200e9, - "roll_off": 0.15 + "roll_off": 0.15, + "tx_osnr": 40, + "min_spacing": 37.5e9, + "cost":1 }, { - "format": "QPSK", - "baud_rate": 32e9, - "OSNR": 12, - "bit_rate": 100e9, - "roll_off": 0.15 + "format": "mode 3", + "baud_rate": 44e9, + "OSNR": 18, + "bit_rate": 300e9, + "roll_off": 0.15, + "tx_osnr": 40, + "min_spacing": 62.5e9, + "cost":1 + }, + { + "format": "mode 2", + "baud_rate": 66e9, + "OSNR": 21, + "bit_rate": 400e9, + "roll_off": 0.15, + "tx_osnr": 40, + "min_spacing": 75e9, + "cost":1 + }, + { + "format": "mode 4", + "baud_rate": 66e9, + "OSNR": 16, + "bit_rate": 200e9, + "roll_off": 0.15, + "tx_osnr": 40, + "min_spacing": 75e9, + "cost":1 } - ] } ] diff --git a/examples/meshTopologyExampleV2.json b/examples/meshTopologyExampleV2.json index 7fd4df15..5556574c 100644 --- a/examples/meshTopologyExampleV2.json +++ b/examples/meshTopologyExampleV2.json @@ -121,7 +121,7 @@ "type": "Roadm" }, { - "uid": "ingress fused spans in Corlay", + "uid": "west fused spans in Corlay", "metadata": { "location": { "city": "Corlay", @@ -133,7 +133,7 @@ "type": "Fused" }, { - "uid": "ingress fused spans in Loudeac", + "uid": "west fused spans in Loudeac", "metadata": { "location": { "city": "Loudeac", @@ -145,7 +145,7 @@ "type": "Fused" }, { - "uid": "ingress fused spans in Morlaix", + "uid": "west fused spans in Morlaix", "metadata": { "location": { "city": "Morlaix", @@ -157,7 +157,7 @@ "type": "Fused" }, { - "uid": "egress fused spans in Corlay", + "uid": "east fused spans in Corlay", "metadata": { "location": { "city": "Corlay", @@ -169,7 +169,7 @@ "type": "Fused" }, { - "uid": "egress fused spans in Loudeac", + "uid": "east fused spans in Loudeac", "metadata": { "location": { "city": "Loudeac", @@ -181,7 +181,7 @@ "type": "Fused" }, { - "uid": "egress fused spans in Morlaix", + "uid": "east fused spans in Morlaix", "metadata": { "location": { "city": "Morlaix", @@ -193,7 +193,7 @@ "type": "Fused" }, { - "uid": "fiber (Lannion_CAS \u2192 Corlay)-F061", + "uid": "fiber (Lannion_CAS → Corlay)-F061", "metadata": { "location": { "latitude": 2.0, @@ -211,7 +211,7 @@ } }, { - "uid": "fiber (Corlay \u2192 Loudeac)-F010", + "uid": "fiber (Corlay → Loudeac)-F010", "metadata": { "location": { "latitude": 2.0, @@ -229,7 +229,7 @@ } }, { - "uid": "fiber (Loudeac \u2192 Lorient_KMA)-F054", + "uid": "fiber (Loudeac → Lorient_KMA)-F054", "metadata": { "location": { "latitude": 2.0, @@ -247,7 +247,7 @@ } }, { - "uid": "fiber (Lorient_KMA \u2192 Vannes_KBE)-F055", + "uid": "fiber (Lorient_KMA → Vannes_KBE)-F055", "metadata": { "location": { "latitude": 2.0, @@ -265,7 +265,7 @@ } }, { - "uid": "fiber (Lannion_CAS \u2192 Stbrieuc)-F056", + "uid": "fiber (Lannion_CAS → Stbrieuc)-F056", "metadata": { "location": { "latitude": 1.5, @@ -283,7 +283,7 @@ } }, { - "uid": "fiber (Stbrieuc \u2192 Rennes_STA)-F057", + "uid": "fiber (Stbrieuc → Rennes_STA)-F057", "metadata": { "location": { "latitude": 0.5, @@ -301,7 +301,7 @@ } }, { - "uid": "fiber (Lannion_CAS \u2192 Morlaix)-F059", + "uid": "fiber (Lannion_CAS → Morlaix)-F059", "metadata": { "location": { "latitude": 2.5, @@ -319,7 +319,7 @@ } }, { - "uid": "fiber (Morlaix \u2192 Brest_KLA)-F060", + "uid": "fiber (Morlaix → Brest_KLA)-F060", "metadata": { "location": { "latitude": 3.5, @@ -337,7 +337,79 @@ } }, { - "uid": "fiber (Corlay \u2192 Lannion_CAS)-F061", + "uid": "fiber (Brest_KLA → Quimper)-", + "metadata": { + "location": { + "latitude": 2.5, + "longitude": 0.5 + } + }, + "type": "Fiber", + "type_variety": "SSMF", + "params": { + "length": 75.0, + "length_units": "km", + "loss_coef": 0.2, + "con_in": null, + "con_out": null + } + }, + { + "uid": "fiber (Quimper → Lorient_KMA)-", + "metadata": { + "location": { + "latitude": 1.5, + "longitude": 2.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 (Ploermel → Vannes_KBE)-", + "metadata": { + "location": { + "latitude": 1.5, + "longitude": 3.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 (Ploermel → Rennes_STA)-", + "metadata": { + "location": { + "latitude": 0.5, + "longitude": 1.0 + } + }, + "type": "Fiber", + "type_variety": "SSMF", + "params": { + "length": 55.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, @@ -355,7 +427,7 @@ } }, { - "uid": "fiber (Loudeac \u2192 Corlay)-F010", + "uid": "fiber (Loudeac → Corlay)-F010", "metadata": { "location": { "latitude": 2.0, @@ -373,7 +445,7 @@ } }, { - "uid": "fiber (Lorient_KMA \u2192 Loudeac)-F054", + "uid": "fiber (Lorient_KMA → Loudeac)-F054", "metadata": { "location": { "latitude": 2.0, @@ -391,7 +463,7 @@ } }, { - "uid": "fiber (Vannes_KBE \u2192 Lorient_KMA)-F055", + "uid": "fiber (Vannes_KBE → Lorient_KMA)-F055", "metadata": { "location": { "latitude": 2.0, @@ -409,7 +481,7 @@ } }, { - "uid": "fiber (Stbrieuc \u2192 Lannion_CAS)-F056", + "uid": "fiber (Stbrieuc → Lannion_CAS)-F056", "metadata": { "location": { "latitude": 1.5, @@ -427,7 +499,7 @@ } }, { - "uid": "fiber (Rennes_STA \u2192 Stbrieuc)-F057", + "uid": "fiber (Rennes_STA → Stbrieuc)-F057", "metadata": { "location": { "latitude": 0.5, @@ -445,7 +517,7 @@ } }, { - "uid": "fiber (Morlaix \u2192 Lannion_CAS)-F059", + "uid": "fiber (Morlaix → Lannion_CAS)-F059", "metadata": { "location": { "latitude": 2.5, @@ -463,7 +535,7 @@ } }, { - "uid": "fiber (Brest_KLA \u2192 Morlaix)-F060", + "uid": "fiber (Brest_KLA → Morlaix)-F060", "metadata": { "location": { "latitude": 3.5, @@ -479,129 +551,249 @@ "con_in": null, "con_out": null } + }, + { + "uid": "fiber (Quimper → Brest_KLA)-", + "metadata": { + "location": { + "latitude": 2.5, + "longitude": 0.5 + } + }, + "type": "Fiber", + "type_variety": "SSMF", + "params": { + "length": 75.0, + "length_units": "km", + "loss_coef": 0.2, + "con_in": null, + "con_out": null + } + }, + { + "uid": "fiber (Lorient_KMA → Quimper)-", + "metadata": { + "location": { + "latitude": 1.5, + "longitude": 2.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 (Vannes_KBE → Ploermel)-", + "metadata": { + "location": { + "latitude": 1.5, + "longitude": 3.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 (Rennes_STA → Ploermel)-", + "metadata": { + "location": { + "latitude": 0.5, + "longitude": 1.0 + } + }, + "type": "Fiber", + "type_variety": "SSMF", + "params": { + "length": 55.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 \u2192 Corlay)-F061" + "to_node": "fiber (Lannion_CAS → Corlay)-F061" }, { - "from_node": "fiber (Corlay \u2192 Lannion_CAS)-F061", + "from_node": "fiber (Corlay → Lannion_CAS)-F061", "to_node": "roadm Lannion_CAS" }, { "from_node": "roadm Lannion_CAS", - "to_node": "fiber (Lannion_CAS \u2192 Stbrieuc)-F056" + "to_node": "fiber (Lannion_CAS → Stbrieuc)-F056" }, { - "from_node": "fiber (Stbrieuc \u2192 Lannion_CAS)-F056", + "from_node": "fiber (Stbrieuc → Lannion_CAS)-F056", "to_node": "roadm Lannion_CAS" }, { "from_node": "roadm Lannion_CAS", - "to_node": "fiber (Lannion_CAS \u2192 Morlaix)-F059" + "to_node": "fiber (Lannion_CAS → Morlaix)-F059" }, { - "from_node": "fiber (Morlaix \u2192 Lannion_CAS)-F059", + "from_node": "fiber (Morlaix → Lannion_CAS)-F059", "to_node": "roadm Lannion_CAS" }, { - "from_node": "fiber (Lannion_CAS \u2192 Corlay)-F061", - "to_node": "ingress fused spans in Corlay" + "from_node": "fiber (Lannion_CAS → Corlay)-F061", + "to_node": "west fused spans in Corlay" }, { - "from_node": "ingress fused spans in Corlay", - "to_node": "fiber (Corlay \u2192 Loudeac)-F010" + "from_node": "west fused spans in Corlay", + "to_node": "fiber (Corlay → Loudeac)-F010" }, { - "from_node": "fiber (Loudeac \u2192 Corlay)-F010", - "to_node": "egress fused spans in Corlay" + "from_node": "fiber (Loudeac → Corlay)-F010", + "to_node": "east fused spans in Corlay" }, { - "from_node": "egress fused spans in Corlay", - "to_node": "fiber (Corlay \u2192 Lannion_CAS)-F061" + "from_node": "east fused spans in Corlay", + "to_node": "fiber (Corlay → Lannion_CAS)-F061" }, { - "from_node": "fiber (Corlay \u2192 Loudeac)-F010", - "to_node": "ingress fused spans in Loudeac" + "from_node": "fiber (Corlay → Loudeac)-F010", + "to_node": "west fused spans in Loudeac" }, { - "from_node": "ingress fused spans in Loudeac", - "to_node": "fiber (Loudeac \u2192 Lorient_KMA)-F054" + "from_node": "west fused spans in Loudeac", + "to_node": "fiber (Loudeac → Lorient_KMA)-F054" }, { - "from_node": "fiber (Lorient_KMA \u2192 Loudeac)-F054", - "to_node": "egress fused spans in Loudeac" + "from_node": "fiber (Lorient_KMA → Loudeac)-F054", + "to_node": "east fused spans in Loudeac" }, { - "from_node": "egress fused spans in Loudeac", - "to_node": "fiber (Loudeac \u2192 Corlay)-F010" + "from_node": "east fused spans in Loudeac", + "to_node": "fiber (Loudeac → Corlay)-F010" }, { "from_node": "roadm Lorient_KMA", - "to_node": "fiber (Lorient_KMA \u2192 Loudeac)-F054" + "to_node": "fiber (Lorient_KMA → Loudeac)-F054" }, { - "from_node": "fiber (Loudeac \u2192 Lorient_KMA)-F054", + "from_node": "fiber (Loudeac → Lorient_KMA)-F054", "to_node": "roadm Lorient_KMA" }, { "from_node": "roadm Lorient_KMA", - "to_node": "fiber (Lorient_KMA \u2192 Vannes_KBE)-F055" + "to_node": "fiber (Lorient_KMA → Vannes_KBE)-F055" }, { - "from_node": "fiber (Vannes_KBE \u2192 Lorient_KMA)-F055", + "from_node": "fiber (Vannes_KBE → Lorient_KMA)-F055", + "to_node": "roadm Lorient_KMA" + }, + { + "from_node": "roadm Lorient_KMA", + "to_node": "fiber (Lorient_KMA → Quimper)-" + }, + { + "from_node": "fiber (Quimper → Lorient_KMA)-", "to_node": "roadm Lorient_KMA" }, { "from_node": "roadm Vannes_KBE", - "to_node": "fiber (Vannes_KBE \u2192 Lorient_KMA)-F055" + "to_node": "fiber (Vannes_KBE → Lorient_KMA)-F055" }, { - "from_node": "fiber (Lorient_KMA \u2192 Vannes_KBE)-F055", + "from_node": "fiber (Lorient_KMA → Vannes_KBE)-F055", "to_node": "roadm Vannes_KBE" }, { - "from_node": "fiber (Lannion_CAS \u2192 Stbrieuc)-F056", - "to_node": "fiber (Stbrieuc \u2192 Rennes_STA)-F057" + "from_node": "roadm Vannes_KBE", + "to_node": "fiber (Vannes_KBE → Ploermel)-" }, { - "from_node": "fiber (Rennes_STA \u2192 Stbrieuc)-F057", - "to_node": "fiber (Stbrieuc \u2192 Lannion_CAS)-F056" + "from_node": "fiber (Ploermel → Vannes_KBE)-", + "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 \u2192 Stbrieuc)-F057" + "to_node": "fiber (Rennes_STA → Stbrieuc)-F057" }, { - "from_node": "fiber (Stbrieuc \u2192 Rennes_STA)-F057", + "from_node": "fiber (Stbrieuc → Rennes_STA)-F057", "to_node": "roadm Rennes_STA" }, { - "from_node": "fiber (Lannion_CAS \u2192 Morlaix)-F059", - "to_node": "ingress fused spans in Morlaix" + "from_node": "roadm Rennes_STA", + "to_node": "fiber (Rennes_STA → Ploermel)-" }, { - "from_node": "ingress fused spans in Morlaix", - "to_node": "fiber (Morlaix \u2192 Brest_KLA)-F060" + "from_node": "fiber (Ploermel → Rennes_STA)-", + "to_node": "roadm Rennes_STA" }, { - "from_node": "fiber (Brest_KLA \u2192 Morlaix)-F060", - "to_node": "egress fused spans in Morlaix" + "from_node": "fiber (Lannion_CAS → Morlaix)-F059", + "to_node": "west fused spans in Morlaix" }, { - "from_node": "egress fused spans in Morlaix", - "to_node": "fiber (Morlaix \u2192 Lannion_CAS)-F059" + "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 \u2192 Morlaix)-F060" + "to_node": "fiber (Brest_KLA → Morlaix)-F060" }, { - "from_node": "fiber (Morlaix \u2192 Brest_KLA)-F060", + "from_node": "fiber (Morlaix → Brest_KLA)-F060", "to_node": "roadm Brest_KLA" }, + { + "from_node": "roadm Brest_KLA", + "to_node": "fiber (Brest_KLA → Quimper)-" + }, + { + "from_node": "fiber (Quimper → Brest_KLA)-", + "to_node": "roadm Brest_KLA" + }, + { + "from_node": "fiber (Brest_KLA → Quimper)-", + "to_node": "fiber (Quimper → Lorient_KMA)-" + }, + { + "from_node": "fiber (Lorient_KMA → Quimper)-", + "to_node": "fiber (Quimper → Brest_KLA)-" + }, + { + "from_node": "fiber (Vannes_KBE → Ploermel)-", + "to_node": "fiber (Ploermel → Rennes_STA)-" + }, + { + "from_node": "fiber (Rennes_STA → Ploermel)-", + "to_node": "fiber (Ploermel → Vannes_KBE)-" + }, { "from_node": "trx Lannion_CAS", "to_node": "roadm Lannion_CAS" diff --git a/examples/meshTopologyExampleV2.xls b/examples/meshTopologyExampleV2.xls index a47e87a5..c64302bd 100644 Binary files a/examples/meshTopologyExampleV2.xls and b/examples/meshTopologyExampleV2.xls differ diff --git a/examples/meshTopologyExampleV2_services.json b/examples/meshTopologyExampleV2_services.json index 64cda69c..cdce3cc0 100644 --- a/examples/meshTopologyExampleV2_services.json +++ b/examples/meshTopologyExampleV2_services.json @@ -1,7 +1,7 @@ { "path-request": [ { - "request-id": 0, + "request-id": "0", "source": "Lorient_KMA", "destination": "Vannes_KBE", "src-tp-id": "trx Lorient_KMA", @@ -9,8 +9,8 @@ "path-constraints": { "te-bandwidth": { "technology": "flexi-grid", - "trx_type": "Voyager_16QAM", - "trx_mode": "16QAM", + "trx_type": "Voyager", + "trx_mode": null, "effective-freq-slot": [ { "n": "null", @@ -19,7 +19,8 @@ ], "spacing": 50000000000.0, "max-nb-of-channel": 80, - "output-power": 0.0012589254117941673 + "output-power": 0.0012589254117941673, + "path_bandwidth": 100000000000.0 } }, "optimizations": { @@ -27,7 +28,7 @@ } }, { - "request-id": 1, + "request-id": "1", "source": "Brest_KLA", "destination": "Vannes_KBE", "src-tp-id": "trx Brest_KLA", @@ -35,8 +36,8 @@ "path-constraints": { "te-bandwidth": { "technology": "flexi-grid", - "trx_type": "Voyager_16QAM", - "trx_mode": "16QAM", + "trx_type": "Voyager", + "trx_mode": "mode 1", "effective-freq-slot": [ { "n": "null", @@ -44,8 +45,9 @@ } ], "spacing": 50000000000.0, - "max-nb-of-channel": 80, - "output-power": 0.0012589254117941673 + "max-nb-of-channel": null, + "output-power": 0.0012589254117941673, + "path_bandwidth": 200000000000.0 } }, "optimizations": { @@ -53,7 +55,7 @@ { "index": 0, "unnumbered-hop": { - "node-id": "Lannion_CAS", + "node-id": "roadm Brest_KLA", "link-tp-id": "link-tp-id is not used", "hop-type": "loose", "direction": "direction is not used" @@ -68,7 +70,37 @@ { "index": 1, "unnumbered-hop": { - "node-id": "Lorient_KMA", + "node-id": "roadm Lannion_CAS", + "link-tp-id": "link-tp-id is not used", + "hop-type": "loose", + "direction": "direction is not used" + }, + "label-hop": { + "te-label": { + "generic": "generic is not used", + "direction": "direction is not used" + } + } + }, + { + "index": 2, + "unnumbered-hop": { + "node-id": "roadm Lorient_KMA", + "link-tp-id": "link-tp-id is not used", + "hop-type": "loose", + "direction": "direction is not used" + }, + "label-hop": { + "te-label": { + "generic": "generic is not used", + "direction": "direction is not used" + } + } + }, + { + "index": 3, + "unnumbered-hop": { + "node-id": "roadm Vannes_KBE", "link-tp-id": "link-tp-id is not used", "hop-type": "loose", "direction": "direction is not used" @@ -84,7 +116,7 @@ } }, { - "request-id": 3, + "request-id": "3", "source": "Lannion_CAS", "destination": "Rennes_STA", "src-tp-id": "trx Lannion_CAS", @@ -93,7 +125,7 @@ "te-bandwidth": { "technology": "flexi-grid", "trx_type": "vendorA_trx-type1", - "trx_mode": "PS_SP64_1", + "trx_mode": "mode 1", "effective-freq-slot": [ { "n": "null", @@ -101,8 +133,9 @@ } ], "spacing": 50000000000.0, - "max-nb-of-channel": 80, - "output-power": 0.0012589254117941673 + "max-nb-of-channel": null, + "output-power": null, + "path_bandwidth": 60000000000.0 } }, "optimizations": { @@ -110,7 +143,7 @@ } }, { - "request-id": 4, + "request-id": "4", "source": "Rennes_STA", "destination": "Lannion_CAS", "src-tp-id": "trx Rennes_STA", @@ -119,7 +152,7 @@ "te-bandwidth": { "technology": "flexi-grid", "trx_type": "vendorA_trx-type1", - "trx_mode": "PS_SP64_1", + "trx_mode": null, "effective-freq-slot": [ { "n": "null", @@ -127,8 +160,117 @@ } ], "spacing": 75000000000.0, - "max-nb-of-channel": 64, - "output-power": 0.0019952623149688794 + "max-nb-of-channel": null, + "output-power": 0.0019952623149688794, + "path_bandwidth": 150000000000.0 + } + }, + "optimizations": { + "explicit-route-include-objects": [] + } + }, + { + "request-id": "5", + "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": "mode 2", + "effective-freq-slot": [ + { + "n": "null", + "m": "null" + } + ], + "spacing": 75000000000.0, + "max-nb-of-channel": 63, + "output-power": 0.0019952623149688794, + "path_bandwidth": 20000000000.0 + } + }, + "optimizations": { + "explicit-route-include-objects": [] + } + }, + { + "request-id": "6", + "source": "Lannion_CAS", + "destination": "Lorient_KMA", + "src-tp-id": "trx Lannion_CAS", + "dst-tp-id": "trx Lorient_KMA", + "path-constraints": { + "te-bandwidth": { + "technology": "flexi-grid", + "trx_type": "Voyager", + "trx_mode": "mode 1", + "effective-freq-slot": [ + { + "n": "null", + "m": "null" + } + ], + "spacing": 50000000000.0, + "max-nb-of-channel": 76, + "output-power": 0.001, + "path_bandwidth": 300000000000.0 + } + }, + "optimizations": { + "explicit-route-include-objects": [] + } + }, + { + "request-id": "7", + "source": "Lannion_CAS", + "destination": "Lorient_KMA", + "src-tp-id": "trx Lannion_CAS", + "dst-tp-id": "trx Lorient_KMA", + "path-constraints": { + "te-bandwidth": { + "technology": "flexi-grid", + "trx_type": "Voyager", + "trx_mode": "mode 1", + "effective-freq-slot": [ + { + "n": "null", + "m": "null" + } + ], + "spacing": 50000000000.0, + "max-nb-of-channel": 76, + "output-power": 0.001, + "path_bandwidth": 400000000000.0 + } + }, + "optimizations": { + "explicit-route-include-objects": [] + } + }, + { + "request-id": "7b", + "source": "Lannion_CAS", + "destination": "Lorient_KMA", + "src-tp-id": "trx Lannion_CAS", + "dst-tp-id": "trx Lorient_KMA", + "path-constraints": { + "te-bandwidth": { + "technology": "flexi-grid", + "trx_type": "Voyager", + "trx_mode": "mode 1", + "effective-freq-slot": [ + { + "n": "null", + "m": "null" + } + ], + "spacing": 75000000000.0, + "max-nb-of-channel": 50, + "output-power": 0.001, + "path_bandwidth": 400000000000.0 } }, "optimizations": { @@ -136,30 +278,30 @@ } } ], - "synchronisation": [ + "synchronization": [ { - "synchonization-id": 0, + "synchronization-id": "3", "svec": { "relaxable": "False", "link-diverse": "True", "node-diverse": "True", "request-id-number": [ - 0, - 0 + "3", + "1" ] } }, { - "synchonization-id": 3, + "synchronization-id": "4", "svec": { "relaxable": "False", "link-diverse": "True", "node-diverse": "True", "request-id-number": [ - 3, - 4 + "4", + "5" ] } } ] -} +} \ No newline at end of file diff --git a/examples/meshTopologyToy.xls b/examples/meshTopologyToy.xls index 05ae7d6a..be744cc5 100644 Binary files a/examples/meshTopologyToy.xls and b/examples/meshTopologyToy.xls differ diff --git a/examples/meshTopologyToy2.xls b/examples/meshTopologyToy2.xls new file mode 100644 index 00000000..428e2ee1 Binary files /dev/null and b/examples/meshTopologyToy2.xls differ diff --git a/examples/path_requests_run.py b/examples/path_requests_run.py index c72e3c2e..fd13dd7e 100755 --- a/examples/path_requests_run.py +++ b/examples/path_requests_run.py @@ -19,16 +19,21 @@ from collections import namedtuple from logging import getLogger, basicConfig, CRITICAL, DEBUG, INFO from json import dumps, loads from networkx import (draw_networkx_nodes, draw_networkx_edges, - draw_networkx_labels, dijkstra_path, NetworkXNoPath) + draw_networkx_labels) from numpy import mean -from examples.convert_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.network import load_network, build_network, set_roadm_loss -from gnpy.core.equipment import load_equipment, trx_mode_params -from gnpy.core.elements import Transceiver, Roadm, Edfa, Fused +from gnpy.core.network import load_network, build_network, set_roadm_loss, save_network +from gnpy.core.equipment import load_equipment, trx_mode_params, automatic_nch, automatic_spacing +from gnpy.core.elements import Transceiver, Roadm, Edfa, Fused, Fiber from gnpy.core.utils import db2lin, lin2db -from gnpy.core.request import Path_request, Result_element, compute_constrained_path, propagate, jsontocsv +from gnpy.core.request import (Path_request, Result_element, compute_constrained_path, + propagate, jsontocsv, Disjunction, compute_path_dsjctn, requests_aggregation, + propagate_and_optimize_mode) from copy import copy, deepcopy +from textwrap import dedent +from math import ceil +import time #EQPT_LIBRARY_FILENAME = Path(__file__).parent / 'eqpt_config.json' @@ -38,15 +43,15 @@ parser = ArgumentParser(description = 'A function that computes performances for parser.add_argument('network_filename', nargs='?', type = Path, default= Path(__file__).parent / 'meshTopologyExampleV2.xls') parser.add_argument('service_filename', nargs='?', type = Path, default= Path(__file__).parent / 'meshTopologyExampleV2.xls') parser.add_argument('eqpt_filename', nargs='?', type = Path, default=Path(__file__).parent / 'eqpt_config.json') -parser.add_argument('-v', '--verbose', action='count') -parser.add_argument('-o', '--output', default=None) +parser.add_argument('-v', '--verbose', action='count', default=0, help='increases verbosity for each occurence') +parser.add_argument('-o', '--output', type = Path) def requests_from_json(json_data,equipment): requests_list = [] for req in json_data['path-request']: - #print(f'{req}') + # init all params from request params = {} params['request_id'] = req['request-id'] params['source'] = req['src-tp-id'] @@ -59,27 +64,89 @@ def requests_from_json(json_data,equipment): params['loose_list'] = [n['unnumbered-hop']['hop-type'] for n in nd_list] params['spacing'] = req['path-constraints']['te-bandwidth']['spacing'] + # recover trx physical param (baudrate, ...) from type and mode + # in trx_mode_params optical power is read from equipment['SI']['default'] and + # nb_channel is computed based on min max frequency and spacing trx_params = trx_mode_params(equipment,params['trx_type'],params['trx_mode'],True) params.update(trx_params) - params['power'] = req['path-constraints']['te-bandwidth']['output-power'] - params['nb_channel'] = req['path-constraints']['te-bandwidth']['max-nb-of-channel'] + # print(trx_params['min_spacing']) + # optical power might be set differently in the request. if it is indicated then the + # params['power'] is updated + if req['path-constraints']['te-bandwidth']['output-power']: + params['power'] = req['path-constraints']['te-bandwidth']['output-power'] + # same process for nb-channel + f_min = params['f_min'] + f_max_from_si = params['f_max'] + if req['path-constraints']['te-bandwidth']['max-nb-of-channel'] is not None : + nch = req['path-constraints']['te-bandwidth']['max-nb-of-channel'] + params['nb_channel'] = nch + spacing = params['spacing'] + params['f_max'] = f_min + nch*spacing + else : + params['nb_channel'] = automatic_nch(f_min,f_max_from_si,params['spacing']) + + consistency_check(params, f_max_from_si) + + try : + params['path_bandwidth'] = req['path-constraints']['te-bandwidth']['path_bandwidth'] + except KeyError: + pass requests_list.append(Path_request(**params)) - return requests_list +def consistency_check(params, f_max_from_si): + f_min = params['f_min'] + f_max = params['f_max'] + max_recommanded_nb_channels = automatic_nch(f_min,f_max, + params['spacing']) + if params['baud_rate'] is not None: + #implicitely means that a mode is defined with min_spacing + if params['min_spacing']>params['spacing'] : + msg = f'Request {params["request_id"]} has spacing below transponder {params["trx_type"]}'+\ + f' {params["trx_mode"]} min spacing value {params["min_spacing"]*1e-9}GHz.\n'+\ + 'Computation stopped' + print(msg) + logger.critical(msg) + exit() + if f_max>f_max_from_si: + msg = dedent(f''' + Requested channel number {params["nb_channel"]}, baud rate {params["baud_rate"]} GHz and requested spacing {params["spacing"]*1e-9}GHz + is not consistent with frequency range {f_min*1e-12} THz, {f_max*1e-12} THz, min recommanded spacing {params["min_spacing"]*1e-9}GHz. + max recommanded nb of channels is {max_recommanded_nb_channels} + Computation stopped.''') + logger.critical(msg) + exit() + + +def disjunctions_from_json(json_data): + disjunctions_list = [] + + for snc in json_data['synchronization']: + params = {} + params['disjunction_id'] = snc['synchronization-id'] + params['relaxable'] = snc['svec']['relaxable'] + params['link_diverse'] = snc['svec']['link-diverse'] + params['node_diverse'] = snc['svec']['node-diverse'] + params['disjunctions_req'] = snc['svec']['request-id-number'] + disjunctions_list.append(Disjunction(**params)) + return disjunctions_list + def load_requests(filename,eqpt_filename): if filename.suffix.lower() == '.xls': logger.info('Automatically converting requests from XLS to JSON') json_data = convert_service_sheet(filename,eqpt_filename) else: - with open(filename) as f: + with open(filename, encoding='utf-8') as f: json_data = loads(f.read()) return json_data def compute_path(network, equipment, pathreqlist): + # This function is obsolete and not relevant with respect to network building: suggest either to correct + # or to suppress it + path_res_list = [] for pathreq in pathreqlist: @@ -97,8 +164,7 @@ def compute_path(network, equipment, pathreqlist): print(f'with path constraint: {[pathreq.source]+pathreq.nodes_list}') #adding first node to be clearer on the output total_path = compute_constrained_path(network, pathreq) print(f'Computed path (roadms):{[e.uid for e in total_path if isinstance(e, Roadm)]}\n') - # for debug - # print(f'{pathreq.baud_rate} {pathreq.power} {pathreq.spacing} {pathreq.nb_channel}') + if total_path : total_path = propagate(total_path,pathreq,equipment, show=False) else: @@ -114,6 +180,117 @@ def compute_path(network, equipment, pathreqlist): path_res_list.append(deepcopy(total_path)) return path_res_list +def compute_path_with_disjunction(network, equipment, pathreqlist, pathlist): + + # use a list but a dictionnary might be helpful to find path bathsed on request_id + # TODO change all these req, dsjct, res lists into dict ! + path_res_list = [] + + for i,pathreq in enumerate(pathreqlist): + + # use the power specified in requests but might be different from the one specified for design + # the power is an optional parameter for requests definition + # if optional, use the one defines in eqt_config.json + p_db = lin2db(pathreq.power*1e3) + p_total_db = p_db + lin2db(pathreq.nb_channel) + print(f'request {pathreq.request_id}') + print(f'Computing path from {pathreq.source} to {pathreq.destination}') + print(f'with path constraint: {[pathreq.source]+pathreq.nodes_list}') #adding first node to be clearer on the output + + total_path = pathlist[i] + print(f'Computed path (roadms):{[e.uid for e in total_path if isinstance(e, Roadm)]}\n') + # for debug + # print(f'{pathreq.baud_rate} {pathreq.power} {pathreq.spacing} {pathreq.nb_channel}') + if total_path : + if pathreq.baud_rate is not None: + total_path = propagate(total_path,pathreq,equipment, show=False) + temp_snr01nm = round(mean(total_path[-1].snr+lin2db(pathreq.baud_rate/(12.5e9))),2) + if temp_snr01nm < pathreq.OSNR : + msg = f'\tWarning! Request {pathreq.request_id} computed path from {pathreq.source} to {pathreq.destination} does not pass with {pathreq.tsp_mode}\n' +\ + f'\tcomputedSNR in 0.1nm = {temp_snr01nm} - required osnr {pathreq.OSNR}\n' + print(msg) + logger.warning(msg) + total_path = [] + else: + total_path,mode = propagate_and_optimize_mode(total_path,pathreq,equipment) + # if no baudrate satisfies spacing, no mode is returned and an empty path is returned + # a warning is shown in the propagate_and_optimize_mode + if mode is not None : + # propagate_and_optimize_mode function returns the mode with the highest bitrate + # that passes. if no mode passes, then it returns an empty path + pathreq.baud_rate = mode['baud_rate'] + pathreq.tsp_mode = mode['format'] + pathreq.format = mode['format'] + pathreq.OSNR = mode['OSNR'] + pathreq.tx_osnr = mode['tx_osnr'] + pathreq.bit_rate = mode['bit_rate'] + else : + total_path = [] + # we record the last tranceiver object in order to have th whole + # information about spectrum. Important Note: since transceivers + # attached to roadms are actually logical elements to simulate + # performance, several demands having the same destination may use + # the same transponder for the performance simaulation. This is why + # we use deepcopy: to ensure each propagation is recorded and not + # overwritten + + path_res_list.append(deepcopy(total_path)) + return path_res_list + +def correct_route_list(network, pathreqlist): + # prepares the format of route list of nodes to be consistant + # remove wrong names, remove endpoints + # also correct source and destination + anytype = [n.uid for n in network.nodes() if not isinstance(n, Transceiver) and not isinstance(n, Fiber)] + # TODO there is a problem of identification of fibers in case of parallel fibers bitween two adjacent roadms + # so fiber constraint is not supported + transponders = [n.uid for n in network.nodes() if isinstance(n, Transceiver)] + for pathreq in pathreqlist: + for i,n_id in enumerate(pathreq.nodes_list): + # replace possibly wrong name with a formated roadm name + # print(n_id) + if n_id not in anytype : + nodes_suggestion = [uid for uid in anytype \ + if n_id.lower() in uid.lower()] + if pathreq.loose_list[i] == 'loose': + if len(nodes_suggestion)>0 : + new_n = nodes_suggestion[0] + print(f'invalid route node specified:\ + \n\'{n_id}\', replaced with \'{new_n}\'') + pathreq.nodes_list[i] = new_n + else: + print(f'\x1b[1;33;40m'+f'invalid route node specified \'{n_id}\', could not use it as constraint, skipped!'+'\x1b[0m') + pathreq.nodes_list.remove(n_id) + pathreq.loose_list.pop(i) + else: + msg = f'\x1b[1;33;40m'+f'could not find node : {n_id} in network topology. Strict constraint can not be applied.'+'\x1b[0m' + logger.critical(msg) + raise ValueError(msg) + if pathreq.source not in transponders: + msg = f'\x1b[1;31;40m'+f'Request: {pathreq.request_id}: could not find transponder source : {pathreq.source}.'+'\x1b[0m' + logger.critical(msg) + print(f'{msg}\nComputation stopped.') + exit() + + if pathreq.destination not in transponders: + msg = f'\x1b[1;31;40m'+f'Request: {pathreq.request_id}: could not find transponder destination : {pathreq.destination}.'+'\x1b[0m' + logger.critical(msg) + print(f'{msg}\nComputation stopped.') + exit() + + # TODO remove endpoints from this list in case they were added by the user in the xls or json files + return pathreqlist + +def correct_disjn(disjn): + local_disjn = disjn.copy() + for el in local_disjn: + for d in local_disjn: + if set(el.disjunctions_req) == set(d.disjunctions_req) and\ + el.disjunction_id != d.disjunction_id: + local_disjn.remove(d) + return local_disjn + + def path_result_json(pathresult): data = { 'path': [n.json for n in pathresult] @@ -122,44 +299,101 @@ def path_result_json(pathresult): if __name__ == '__main__': + start = time.time() args = parser.parse_args() - basicConfig(level={2: DEBUG, 1: INFO, 0: CRITICAL}.get(args.verbose, CRITICAL)) + basicConfig(level={2: DEBUG, 1: INFO, 0: CRITICAL}.get(args.verbose, DEBUG)) logger.info(f'Computing path requests {args.service_filename} into JSON format') + print('\x1b[1;34;40m'+f'Computing path requests {args.service_filename} into JSON format'+ '\x1b[0m') # for debug # print( args.eqpt_filename) data = load_requests(args.service_filename,args.eqpt_filename) equipment = load_equipment(args.eqpt_filename) network = load_network(args.network_filename,equipment) - pths = requests_from_json(data, equipment) - print(pths) - test = compute_path(network, equipment, pths) - #TODO write results + # Build the network once using the default power defined in SI in eqpt config + # TODO power density : db2linp(ower_dbm": 0)/power_dbm": 0 * nb channels as defined by + # spacing, f_min and f_max + 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(args.network_filename, network) - header = ['demand','snr@bandwidth','snr@0.1nm','Receiver minOSNR'] + rqs = requests_from_json(data, equipment) + + # check that request ids are unique. Non unique ids, may + # mess the computation : better to stop the computation + all_ids = [r.request_id for r in rqs] + if len(all_ids) != len(set(all_ids)): + for a in list(set(all_ids)): + all_ids.remove(a) + msg = f'Requests id {all_ids} are not unique' + logger.critical(msg) + exit() + rqs = correct_route_list(network, rqs) + + # pths = compute_path(network, equipment, rqs) + dsjn = disjunctions_from_json(data) + + print('\x1b[1;34;40m'+f'List of disjunctions'+ '\x1b[0m') + print(dsjn) + # need to warn or correct in case of wrong disjunction form + # disjunction must not be repeated with same or different ids + dsjn = correct_disjn(dsjn) + + # Aggregate demands with same exact constraints + print('\x1b[1;34;40m'+f'Aggregating similar requests'+ '\x1b[0m') + + rqs,dsjn = requests_aggregation(rqs,dsjn) + # TODO export novel set of aggregated demands in a json file + + print('\x1b[1;34;40m'+'The following services have been requested:'+ '\x1b[0m') + print(rqs) + + print('\x1b[1;34;40m'+f'Computing all paths with constraints'+ '\x1b[0m') + pths = compute_path_dsjctn(network, equipment, rqs, dsjn) + + print('\x1b[1;34;40m'+f'Propagating on selected path'+ '\x1b[0m') + propagatedpths = compute_path_with_disjunction(network, equipment, rqs, pths) + + end = time.time() + print(f'computation time {end-start}') + print('\x1b[1;34;40m'+f'Result summary'+ '\x1b[0m') + + header = ['req id', ' demand',' snr@bandwidth',' snr@0.1nm',' Receiver minOSNR', ' mode', ' Gbit/s' , ' nb of tsp pairs'] data = [] data.append(header) - for i, p in enumerate(test): + for i, p in enumerate(propagatedpths): if p: - line = [f'{pths[i].source} to {pths[i].destination} : ', f'{round(mean(p[-1].snr),2)}',\ - f'{round(mean(p[-1].snr+lin2db(pths[i].baud_rate/(12.5e9))),2)}',\ - f'{pths[i].OSNR}'] + line = [f'{rqs[i].request_id}', f' {rqs[i].source} to {rqs[i].destination} : ', f'{round(mean(p[-1].snr),2)}',\ + f'{round(mean(p[-1].snr+lin2db(rqs[i].baud_rate/(12.5e9))),2)}',\ + f'{rqs[i].OSNR}', f'{rqs[i].tsp_mode}' , f'{round(rqs[i].path_bandwidth * 1e-9,2)}' , f'{ceil(rqs[i].path_bandwidth / rqs[i].bit_rate) }'] else: - line = [f'no path from {pths[i].source} to {pths[i].destination} '] + line = [f'{rqs[i].request_id}',f' {rqs[i].source} to {rqs[i].destination} : not feasible '] data.append(line) - col_width = max(len(word) for row in data for word in row) # padding + col_width = max(len(word) for row in data for word in row[2:]) # padding + firstcol_width = max(len(row[0]) for row in data ) # padding + secondcol_width = max(len(row[1]) for row in data ) # padding for row in data: - print(''.join(word.ljust(col_width) for word in row)) - + firstcol = ''.join(row[0].ljust(firstcol_width)) + secondcol = ''.join(row[1].ljust(secondcol_width)) + remainingcols = ''.join(word.center(col_width,' ') for word in row[2:]) + print(f'{firstcol} {secondcol} {remainingcols}') if args.output : result = [] - for p in test: - result.append(Result_element(pths[test.index(p)],p)) - with open(args.output, 'w') as f: - f.write(dumps(path_result_json(result), indent=2)) - fnamecsv = next(s for s in args.output.split('.')) + '.csv' - with open(fnamecsv,"w") as fcsv : - jsontocsv(path_result_json(result),equipment,fcsv) + # assumes that list of rqs and list of propgatedpths have same order + for i,p in enumerate(propagatedpths): + result.append(Result_element(rqs[i],p)) + temp = path_result_json(result) + fnamecsv = f'{str(args.output)[0:len(str(args.output))-len(str(args.output.suffix))]}.csv' + fnamejson = f'{str(args.output)[0:len(str(args.output))-len(str(args.output.suffix))]}.json' + with open(fnamejson, 'w', encoding='utf-8') as f: + f.write(dumps(path_result_json(result), indent=2, ensure_ascii=False)) + with open(fnamecsv,"w", encoding='utf-8') as fcsv : + jsontocsv(temp,equipment,fcsv) + print('\x1b[1;34;40m'+f'saving in {args.output} and {fnamecsv}'+ '\x1b[0m') + diff --git a/examples/transmission_main_example.py b/examples/transmission_main_example.py index ed39a27c..de86d760 100755 --- a/examples/transmission_main_example.py +++ b/examples/transmission_main_example.py @@ -18,7 +18,7 @@ from pathlib import Path from json import loads from collections import Counter from logging import getLogger, basicConfig, INFO, ERROR, DEBUG -from numpy import arange, mean +from numpy import linspace, mean from matplotlib.pyplot import show, axis, figure, title from networkx import (draw_networkx_nodes, draw_networkx_edges, draw_networkx_labels, dijkstra_path) @@ -85,12 +85,9 @@ def main(network, equipment, source, destination, req = None): print(f'\nNow propagating between {source.uid} and {destination.uid}:') try: - power_range = list(arange(*equipment['SI']['default'].power_range_db)) - last = equipment['SI']['default'].power_range_db[-2] - if len(power_range) == 0 : #bad input that will lead to no simulation - power_range = [0] #better than an error message - else: - power_range.append(last) + p_start, p_stop, p_step = equipment['SI']['default'].power_range_db + p_num = abs(int(round((p_stop - p_start)/p_step))) + 1 if p_step != 0 else 1 + power_range = list(linspace(p_start, p_stop, p_num)) except TypeError: print('invalid power range definition in eqpt_config, should be power_range_db: [lower, upper, step]') power_range = [0] @@ -101,6 +98,12 @@ def main(network, equipment, source, destination, req = None): propagate(path, req, equipment, show=len(power_range)==1) print(f'\nTransmission result for input power = {lin2db(req.power*1e3):.2f}dBm :') print(destination) + + #print(f'\n !!!!!!!!!!!!!!!!! TEST POINT !!!!!!!!!!!!!!!!!!!!!') + #print(f'carriers ase output of {path[1]} =\n {list(path[1].carriers("out", "nli"))}') + # => use "in" or "out" parameter + # => use "nli" or "ase" or "signal" or "total" parameter + simulation_data.append({ 'Pch_dBm' : pref_ch_db + dp_db, 'OSNR_ASE_0.1nm' : round(mean(destination.osnr_ase_01nm),2), @@ -115,10 +118,11 @@ def main(network, equipment, source, destination, req = None): parser = ArgumentParser() parser.add_argument('-e', '--equipment', type=Path, default=Path(__file__).parent / 'eqpt_config.json') -parser.add_argument('-pl', '--plot', action='store_true', default=False) -parser.add_argument('-v', '--verbose', action='count') -parser.add_argument('-l', '--list-nodes', action='store_true', default=False, help='list all transceiver nodes') +parser.add_argument('-pl', '--plot', action='store_true') +parser.add_argument('-v', '--verbose', action='count', default=0, help='increases verbosity for each occurence') +parser.add_argument('-l', '--list-nodes', action='store_true', help='list all transceiver nodes') parser.add_argument('-po', '--power', default=0, help='channel ref power in dBm') +parser.add_argument('-names', '--names-matching', action='store_true', help='display network names that are closed matches') #parser.add_argument('-plb', '--power-lower-bound', default=0, help='power sweep lower bound') #parser.add_argument('-pub', '--power-upper-bound', default=1, help='power sweep upper bound') parser.add_argument('filename', nargs='?', type=Path, @@ -129,12 +133,12 @@ parser.add_argument('destination', nargs='?', help='destination node') if __name__ == '__main__': args = parser.parse_args() - basicConfig(level={0: ERROR, 1: INFO, 2: DEBUG}.get(args.verbose, ERROR)) + basicConfig(level={0: ERROR, 1: INFO, 2: DEBUG}.get(args.verbose, DEBUG)) equipment = load_equipment(args.equipment) # logger.info(equipment) # print(args.filename) - network = load_network(args.filename, equipment) + network = load_network(args.filename, equipment, args.names_matching) # print(network) transceivers = {n.uid: n for n in network.nodes() if isinstance(n, Transceiver)} @@ -148,38 +152,40 @@ if __name__ == '__main__': for uid in transceivers: print(uid) exit() - + + #First try to find exact match if source/destination provided if args.source: - try: - source = next(transceivers[uid] for uid in transceivers if uid == args.source) - except StopIteration as e: - #TODO code a more advanced regex to find nodes match - nodes_suggestion = [uid for uid in transceivers \ - if args.source.lower() in uid.lower()] - source = transceivers[nodes_suggestion[0]] \ - if len(nodes_suggestion)>0 else list(transceivers.values())[0] - print(f'invalid souce node specified, did you mean:\ - \n{nodes_suggestion}?\ - \n{args.source!r}, replaced with {source.uid}') - del transceivers[source.uid] + source = transceivers.pop(args.source, None) + valid_source = True if source else False else: + source = None logger.info('No source node specified: picking random transceiver') - source = list(transceivers.values())[0] - + if args.destination: - try: - destination = next(transceivers[uid] for uid in transceivers if uid == args.destination) - except StopIteration as e: - nodes_suggestion = [uid for uid in transceivers \ - if args.destination.lower() in uid.lower()] - destination = transceivers[nodes_suggestion[0]] \ - if len(nodes_suggestion)>0 else list(transceivers.values())[0] - print(f'invalid destination node specified, did you mean:\ - \n{nodes_suggestion}?\ - \n{args.destination!r}, replaced with {destination.uid}') + destination = transceivers.pop(args.destination, None) + valid_destination = True if destination else False else: + destination = None logger.info('No destination node specified: picking random transceiver') - destination = list(transceivers.values())[1] + + #If no exact match try to find partial match + if args.source and not source: + #TODO code a more advanced regex to find nodes match + source = next((transceivers.pop(uid) for uid in transceivers \ + if args.source.lower() in uid.lower()), None) + + if args.destination and not destination: + #TODO code a more advanced regex to find nodes match + destination = next((transceivers.pop(uid) for uid in transceivers \ + if args.destination.lower() in uid.lower()), None) + + #If no partial match or no source/destination provided pick random + if not source: + source = list(transceivers.values())[0] + del transceivers[source.uid] + + if not destination: + destination = list(transceivers.values())[0] logger.info(f'source = {args.source!r}') logger.info(f'destination = {args.destination!r}') @@ -193,6 +199,7 @@ if __name__ == '__main__': params['nodes_list'] = [destination.uid] params['loose_list'] = ['strict'] params['format'] = '' + params['path_bandwidth'] = 0 trx_params = trx_mode_params(equipment) if args.power: trx_params['power'] = db2lin(float(args.power))*1e-3 @@ -201,5 +208,15 @@ if __name__ == '__main__': path = main(network, equipment, source, destination, req) save_network(args.filename, network) + if not args.source: + print(f'\n(No source node specified: picked {source.uid})') + elif not valid_source: + print(f'\n(Invalid source node {args.source!r} replaced with {source.uid})') + + if not args.destination: + print(f'\n(No destination node specified: picked {destination.uid})') + elif not valid_destination: + print(f'\n(Invalid destination node {args.destination!r} replaced with {destination.uid})') + if args.plot: plot_results(network, path, source, destination) diff --git a/examples/write_path_jsontocsv.py b/examples/write_path_jsontocsv.py index 1a7584b3..b7b50dd2 100644 --- a/examples/write_path_jsontocsv.py +++ b/examples/write_path_jsontocsv.py @@ -26,8 +26,8 @@ parser.add_argument('eqpt_filename', nargs='?', type = Path, default=Path(__file if __name__ == '__main__': args = parser.parse_args() - with open(args.output_filename,"w") as file : - with open(args.filename) as f: + with open(args.output_filename, 'w', encoding='utf-8') as file: + with open(args.filename, encoding='utf-8') as f: print(f'Reading {args.filename}') json_data = loads(f.read()) equipment = load_equipment(args.eqpt_filename) diff --git a/gnpy/core/convert.py b/gnpy/core/convert.py index 38d25217..6eea917e 100755 --- a/gnpy/core/convert.py +++ b/gnpy/core/convert.py @@ -30,49 +30,181 @@ from collections import namedtuple, Counter, defaultdict from itertools import chain from json import dumps from pathlib import Path +from difflib import get_close_matches +import time all_rows = lambda sh, start=0: (sh.row(x) for x in range(start, sh.nrows)) -class Node(namedtuple('Node', 'city state country region latitude longitude node_type')): - def __new__(cls, city, state='', country='', region='', latitude=0, longitude=0, node_type='ILA'): - values = [latitude, longitude, node_type] - default_values = [0, 0, 'ILA'] - values = [x[0] if x[0] != '' else x[1] for x in zip(values,default_values)] - return super().__new__(cls, city, state, country, region, *values) +class Node(object): + def __init__(self, **kwargs): + super(Node, self).__init__() + self.update_attr(kwargs) -class Link(namedtuple('Link', 'from_city to_city \ - east_distance east_fiber east_lineic east_con_in east_con_out east_pmd east_cable \ - west_distance west_fiber west_lineic west_con_in west_con_out west_pmd west_cable \ - distance_units')): - def __new__(cls, from_city, to_city, - east_distance, east_fiber='SSMF', east_lineic=0.2, - east_con_in=None, east_con_out=None, east_pmd=0.1, east_cable='', - west_distance='', west_fiber='', west_lineic='', - west_con_in='', west_con_out='', west_pmd='', west_cable='', - distance_units='km'): - east_values = [east_distance, east_fiber, east_lineic, east_con_in, east_con_out, - east_pmd, east_cable] - west_values = [west_distance, west_fiber, west_lineic, west_con_in, west_con_out, - west_pmd, west_cable] - default_values = [80,'SSMF',0.2,None,None,0.1,''] - east_values = [x[0] if x[0] != '' else x[1] for x in zip(east_values,default_values)] - west_values = [x[0] if x[0] != '' else x[1] for x in zip(west_values,east_values)] - return super().__new__(cls, from_city, to_city, *east_values, *west_values, distance_units) + 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(): + v = clean_kwargs.get(k,v) + setattr(self, k, v) + + default_values = \ + { + 'city': '', + 'state': '', + 'country': '', + 'region': '', + 'latitude': 0, + 'longitude': 0, + 'node_type': 'ILA' + } -class Eqpt(namedtuple('Eqpt', 'from_city to_city \ - egress_amp_type egress_att_in egress_amp_gain egress_amp_tilt egress_amp_att_out\ - ingress_amp_type ingress_att_in ingress_amp_gain ingress_amp_tilt ingress_amp_att_out')): - def __new__(cls, from_city='', to_city='', - egress_amp_type='', egress_att_in=0, egress_amp_gain=0, egress_amp_tilt=0, egress_amp_att_out=0, - ingress_amp_type='', ingress_att_in=0, ingress_amp_gain=0, ingress_amp_tilt=0, ingress_amp_att_out=0): - values = [from_city, to_city, - egress_amp_type, egress_att_in, egress_amp_gain, egress_amp_tilt, egress_amp_att_out, - ingress_amp_type, ingress_att_in, ingress_amp_gain, ingress_amp_tilt, ingress_amp_att_out] - default_values = ['','','',0,0,0,0,'',0,0,0,0] - values = [x[0] if x[0] != '' else x[1] for x in zip(values,default_values)] - return super().__new__(cls, *values) +class Link(object): + """attribtes from west parse_ept_headers dict + +node_a, node_z, west_fiber_con_in, east_fiber_con_in + """ + def __init__(self, **kwargs): + super(Link, self).__init__() + self.update_attr(kwargs) + self.distance_units = 'km' + + 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(): + v = clean_kwargs.get(k,v) + setattr(self, k, v) + k = 'west' + k.split('east')[-1] + v = clean_kwargs.get(k,v) + setattr(self, k, v) + + def __eq__(self, link): + return (self.from_city == link.from_city and self.to_city == link.to_city) \ + or (self.from_city == link.to_city and self.to_city == link.from_city) + + default_values = \ + { + 'from_city': '', + 'to_city': '', + 'east_distance': 80, + 'east_fiber': 'SSMF', + 'east_lineic': 0.2, + 'east_con_in': None, + 'east_con_out': None, + 'east_pmd': 0.1, + 'east_cable': '' + } + + +class Eqpt(object): + def __init__(self, **kwargs): + super(Eqpt, self).__init__() + self.update_attr(kwargs) + + 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(): + v_east = clean_kwargs.get(k,v) + setattr(self, k, v_east) + k = 'west' + k.split('east')[-1] + v_west = clean_kwargs.get(k,v) + setattr(self, k, v_west) + + default_values = \ + { + 'from_city': '', + 'to_city': '', + 'east_amp_type': '', + 'east_att_in': 0, + 'east_amp_gain': 0, + 'east_tilt': 0, + 'east_att_out': 0 + } + + +def read_header(my_sheet, line, slice_): + """ return the list of headers !:= '' + header_i = [(header, header_column_index), ...] + in a {line, slice1_x, slice_y} range + """ + Param_header = namedtuple('Param_header', 'header colindex') + try: + header = [x.value.strip() for x in my_sheet.row_slice(line, slice_[0], slice_[1])] + header_i = [Param_header(header,i+slice_[0]) for i, header in enumerate(header) if header != ''] + except: + header_i = [] + if header_i != [] and header_i[-1].colindex != slice_[1]: + header_i.append(Param_header('',slice_[1])) + return header_i + +def read_slice(my_sheet, line, slice_, header): + """return the slice range of a given header + in a defined range {line, slice_x, slice_y}""" + header_i = read_header(my_sheet, line, slice_) + slice_range = (-1,-1) + if header_i != []: + try: + slice_range = next((h.colindex,header_i[i+1].colindex) \ + for i,h in enumerate(header_i) if header in h.header) + except: + pass + return slice_range + + +def parse_headers(my_sheet, input_headers_dict, headers, start_line, slice_in): + """return a dict of header_slice + key = column index + value = header name""" + + + for h0 in input_headers_dict: + slice_out = read_slice(my_sheet, start_line, slice_in, h0) + iteration = 1 + while slice_out == (-1,-1) and iteration < 10: + #try next lines + #print(h0, iteration) + slice_out = read_slice(my_sheet, start_line+iteration, slice_in, h0) + iteration += 1 + if slice_out == (-1, -1): + if h0 == 'east': + print(f'\x1b[1;31;40m'+f'CRITICAL: missing _east_ header above other headers (hierarchical) _ ABORT'+ '\x1b[0m') + exit() + else: + print(f'missing header {h0}') + elif not isinstance(input_headers_dict[h0], dict): + headers[slice_out[0]] = input_headers_dict[h0] + else: + headers = parse_headers(my_sheet, input_headers_dict[h0], headers, start_line+1, slice_out) + if headers == {}: + print(f'\x1b[1;31;40m'+f'CRITICAL ERROR: could not find any header to read _ ABORT'+ '\x1b[0m') + exit() + return headers + +def parse_row(row, headers): + #print([label for label in ept.values()]) + #print([i for i in ept.keys()]) + #print(row[i for i in ept.keys()]) + return {f: r.value for f, r in \ + zip([label for label in headers.values()], [row[i] for i in headers])} + #if r.ctype != XL_CELL_EMPTY} + +def parse_sheet(my_sheet, input_headers_dict, header_line, start_line, column): + headers = parse_headers(my_sheet, input_headers_dict, {}, header_line, (0,column)) + for row in all_rows(my_sheet, start=start_line): + yield parse_row(row[0: column], headers) + +def sanity_check(nodes, links, nodes_by_city, links_by_city, eqpts_by_city): + + duplicate_links = [] + for l1 in links: + for l2 in links: + if l1 is not l2 and l1 == l2 and l2 not in duplicate_links: + print(f'\nWARNING\n \ + link {l1.from_city}-{l1.to_city} is duplicate \ + \nthe 1st duplicate link will be removed but you should check Links sheet input') + duplicate_links.append(l1) + #if duplicate_links != []: + #time.sleep(3) + for l in duplicate_links: + links.remove(l) -def sanity_check(nodes, nodes_by_city, links_by_city, eqpts_by_city): try : test_nodes = [n for n in nodes_by_city if not n in links_by_city] test_links = [n for n in links_by_city if not n in nodes_by_city] @@ -81,7 +213,7 @@ def sanity_check(nodes, nodes_by_city, links_by_city, eqpts_by_city): and (test_links == [] or test_links ==[''])\ and (test_eqpts == [] or test_eqpts ==['']) except AssertionError: - print(f'!names in Nodes and Links sheets do no match, check:\ + print(f'CRITICAL error: \nNames in Nodes and Links sheets do no match, check:\ \n{test_nodes} in Nodes sheet\ \n{test_links} in Links sheet\ \n{test_eqpts} in Eqpt sheet') @@ -94,11 +226,13 @@ def sanity_check(nodes, nodes_by_city, links_by_city, eqpts_by_city): #TODO : put in log rather than print print(f'invalid node type ({nodes_by_city[city].node_type})\ specified in {city}, replaced by ROADM') - nodes_by_city[city] = nodes_by_city[city]._replace(node_type='ROADM') - nodes = [n._replace(node_type='ROADM') if n.city==city else n for n in nodes] - return nodes + nodes_by_city[city].node_type = 'ROADM' + for n in nodes: + if n.city==city: + n.node_type='ROADM' + return nodes, links -def convert_file(input_filename, filter_region=[]): +def convert_file(input_filename, names_matching=False, filter_region=[]): nodes, links, eqpts = parse_excel(input_filename) if filter_region: @@ -109,9 +243,32 @@ def convert_file(input_filename, filter_region=[]): cities = {lnk.from_city for lnk in links} | {lnk.to_city for lnk in links} nodes = [n for n in nodes if n.city in cities] + global nodes_by_city nodes_by_city = {n.city: n for n in nodes} + #create matching dictionary for node name mismatch analysis + + cities = {''.join(c.strip() for c in n.city.split('C+L')).lower(): n.city for n in nodes} + cities_to_match = [k for k in cities] + city_match_dic = defaultdict(list) + for city in cities: + if city in cities_to_match: + cities_to_match.remove(city) + matches = get_close_matches(city, cities_to_match, 4, 0.85) + for m in matches: + city_match_dic[cities[city]].append(cities[m]) + #check lower case/upper case + for city in nodes_by_city: + for match_city in nodes_by_city: + if match_city.lower() == city.lower() and match_city != city: + city_match_dic[city].append(match_city) + + if names_matching: + print('\ncity match dictionary:',city_match_dic) + with open('name_match_dictionary.json', 'w', encoding='utf-8') as city_match_dic_file: + city_match_dic_file.write(dumps(city_match_dic, indent=2, ensure_ascii=False)) + global links_by_city links_by_city = defaultdict(list) for link in links: @@ -123,7 +280,7 @@ def convert_file(input_filename, filter_region=[]): for eqpt in eqpts: eqpts_by_city[eqpt.from_city].append(eqpt) - nodes = sanity_check(nodes, nodes_by_city, links_by_city, eqpts_by_city) + nodes, links = sanity_check(nodes, links, nodes_by_city, links_by_city, eqpts_by_city) data = { 'elements': @@ -141,21 +298,21 @@ def convert_file(input_filename, filter_region=[]): 'longitude': x.longitude}}, 'type': 'Roadm'} for x in nodes_by_city.values() if x.node_type.lower() == 'roadm'] + - [{'uid': f'ingress fused spans in {x.city}', + [{'uid': f'west fused spans in {x.city}', 'metadata': {'location': {'city': x.city, 'region': x.region, 'latitude': x.latitude, 'longitude': x.longitude}}, 'type': 'Fused'} for x in nodes_by_city.values() if x.node_type.lower() == 'fused'] + - [{'uid': f'egress fused spans in {x.city}', + [{'uid': f'east fused spans in {x.city}', 'metadata': {'location': {'city': x.city, 'region': x.region, 'latitude': x.latitude, 'longitude': x.longitude}}, 'type': 'Fused'} for x in nodes_by_city.values() if x.node_type.lower() == 'fused'] + - [{'uid': f'fiber ({x.from_city} → {x.to_city})-{x.east_cable}', + [{'uid': f'fiber ({x.from_city} \u2192 {x.to_city})-{x.east_cable}', 'metadata': {'location': midpoint(nodes_by_city[x.from_city], nodes_by_city[x.to_city])}, 'type': 'Fiber', @@ -167,7 +324,7 @@ def convert_file(input_filename, filter_region=[]): 'con_out':x.east_con_out} } for x in links] + - [{'uid': f'fiber ({x.to_city} → {x.from_city})-{x.west_cable}', + [{'uid': f'fiber ({x.to_city} \u2192 {x.from_city})-{x.west_cable}', 'metadata': {'location': midpoint(nodes_by_city[x.from_city], nodes_by_city[x.to_city])}, 'type': 'Fiber', @@ -179,28 +336,30 @@ def convert_file(input_filename, filter_region=[]): 'con_out':x.west_con_out} } # missing ILA construction for x in links] + - [{'uid': f'egress edfa in {e.from_city} to {e.to_city}', + [{'uid': f'east edfa in {e.from_city} to {e.to_city}', 'metadata': {'location': {'city': nodes_by_city[e.from_city].city, 'region': nodes_by_city[e.from_city].region, 'latitude': nodes_by_city[e.from_city].latitude, 'longitude': nodes_by_city[e.from_city].longitude}}, 'type': 'Edfa', - 'type_variety': e.egress_amp_type, - 'operational': {'gain_target': e.egress_amp_gain, - 'tilt_target': e.egress_amp_tilt} + 'type_variety': e.east_amp_type, + 'operational': {'gain_target': e.east_amp_gain, + 'tilt_target': e.east_tilt, + 'out_voa' : e.east_att_out} } - for e in eqpts if e.egress_amp_type.lower() != ''] + - [{'uid': f'ingress edfa in {e.from_city} to {e.to_city}', + for e in eqpts if e.east_amp_type.lower() != ''] + + [{'uid': f'west edfa in {e.from_city} to {e.to_city}', 'metadata': {'location': {'city': nodes_by_city[e.from_city].city, 'region': nodes_by_city[e.from_city].region, 'latitude': nodes_by_city[e.from_city].latitude, 'longitude': nodes_by_city[e.from_city].longitude}}, 'type': 'Edfa', - 'type_variety': e.ingress_amp_type, - 'operational': {'gain_target': e.ingress_amp_gain, - 'tilt_target': e.ingress_amp_tilt} + 'type_variety': e.west_amp_type, + 'operational': {'gain_target': e.west_amp_gain, + 'tilt_target': e.west_tilt, + 'out_voa' : e.west_att_out} } - for e in eqpts if e.ingress_amp_type.lower() != ''], + for e in eqpts if e.west_amp_type.lower() != ''], 'connections': list(chain.from_iterable([eqpt_connection_by_city(n.city) for n in nodes])) @@ -214,17 +373,65 @@ def convert_file(input_filename, filter_region=[]): for x in nodes_by_city.values() if x.node_type.lower()=='roadm']))) } - #print(dumps(data, indent=2)) - # output_json_file_name = input_filename.split(".")[0]+".json" suffix_filename = str(input_filename.suffixes[0]) full_input_filename = str(input_filename) split_filename = [full_input_filename[0:len(full_input_filename)-len(suffix_filename)] , suffix_filename[1:]] output_json_file_name = split_filename[0]+'.json' - with open(output_json_file_name,'w') as edfa_json_file: - edfa_json_file.write(dumps(data, indent=2)) + with open(output_json_file_name, 'w', encoding='utf-8') as edfa_json_file: + edfa_json_file.write(dumps(data, indent=2, ensure_ascii=False)) return output_json_file_name def parse_excel(input_filename): + link_headers = \ + { 'Node A': 'from_city', + 'Node Z': 'to_city', + 'east':{ + 'Distance (km)': 'east_distance', + 'Fiber type': 'east_fiber', + 'lineic att': 'east_lineic', + 'Con_in': 'east_con_in', + 'Con_out': 'east_con_out', + 'PMD': 'east_pmd', + 'Cable id': 'east_cable' + }, + 'west':{ + 'Distance (km)': 'west_distance', + 'Fiber type': 'west_fiber', + 'lineic att': 'west_lineic', + 'Con_in': 'west_con_in', + 'Con_out': 'west_con_out', + 'PMD': 'west_pmd', + 'Cable id': 'west_cable' + } + } + node_headers = \ + { 'City': 'city', + 'State': 'state', + 'Country': 'country', + 'Region': 'region', + 'Latitude': 'latitude', + 'Longitude': 'longitude', + 'Type': 'node_type' + } + eqpt_headers = \ + { 'Node A': 'from_city', + 'Node Z': 'to_city', + 'east':{ + 'amp type': 'east_amp_type', + 'att_in': 'east_att_in', + 'amp gain': 'east_amp_gain', + 'tilt': 'east_tilt', + 'att_out': 'east_att_out' + }, + 'west':{ + 'amp type': 'west_amp_type', + 'att_in': 'west_att_in', + 'amp gain': 'west_amp_gain', + 'tilt': 'west_tilt', + 'att_out': 'west_att_out' + } + } + with open_workbook(input_filename) as wb: nodes_sheet = wb.sheet_by_name('Nodes') links_sheet = wb.sheet_by_name('Links') @@ -234,40 +441,23 @@ def parse_excel(input_filename): #eqpt_sheet is optional eqpt_sheet = None - - # sanity check - """ - header = [x.value.strip() for x in nodes_sheet.row(4)] - expected = ['City', 'State', 'Country', 'Region', 'Latitude', 'Longitude'] - if header != expected: - raise ValueError(f'Malformed header on Nodes sheet: {header} != {expected}') - """ - nodes = [] - for row in all_rows(nodes_sheet, start=5): - nodes.append(Node(*(x.value for x in row[0:NODES_COLUMN]))) - #check input + for node in parse_sheet(nodes_sheet, node_headers, NODES_LINE, NODES_LINE+1, NODES_COLUMN): + nodes.append(Node(**node)) expected_node_types = ('ROADM', 'ILA', 'FUSED') - nodes = [n._replace(node_type='ILA') - if not (n.node_type in expected_node_types) else n for n in nodes] + for n in nodes: + if not (n.node_type in expected_node_types): + n.node_type='ILA' - # sanity check - """ - header = [x.value.strip() for x in links_sheet.row(4)] - expected = ['Node A', 'Node Z', - 'Distance (km)', 'Fiber type', 'lineic att', 'Con_in', 'Con_out', 'PMD', 'Cable id', - 'Distance (km)', 'Fiber type', 'lineic att', 'Con_in', 'Con_out', 'PMD', 'Cable id'] - if header != expected: - raise ValueError(f'Malformed header on Nodes sheet: {header} != {expected}') - """ links = [] - for row in all_rows(links_sheet, start=5): - links.append(Link(*(x.value for x in row[0:LINKS_COLUMN]))) + for link in parse_sheet(links_sheet, link_headers, LINKS_LINE, LINKS_LINE+2, LINKS_COLUMN): + links.append(Link(**link)) + #print('\n', [l.__dict__ for l in links]) eqpts = [] - if eqpt_sheet != None: - for row in all_rows(eqpt_sheet, start=5): - eqpts.append(Eqpt(*(x.value for x in row[0:EQPTS_COLUMN]))) + if eqpt_sheet != None: + for eqpt in parse_sheet(eqpt_sheet, eqpt_headers, EQPTS_LINE, EQPTS_LINE+2, EQPTS_COLUMN): + eqpts.append(Eqpt(**eqpt)) # sanity check all_cities = Counter(n.city for n in nodes) @@ -285,7 +475,7 @@ def eqpt_connection_by_city(city_name): subdata = [] if nodes_by_city[city_name].node_type.lower() in ('ila', 'fused'): # Then len(other_cities) == 2 - direction = ['ingress', 'egress'] + direction = ['west', 'east'] for i in range(2): from_ = fiber_link(other_cities[i], city_name) in_ = eqpt_in_city_to_city(city_name, other_cities[0],direction[i]) @@ -299,7 +489,7 @@ def eqpt_connection_by_city(city_name): subdata += connect_eqpt(from_, in_, to_) from_ = fiber_link(other_city, city_name) - in_ = eqpt_in_city_to_city(city_name, other_city, "ingress") + in_ = eqpt_in_city_to_city(city_name, other_city, "west") to_ = f'roadm {city_name}' subdata += connect_eqpt(from_, in_, to_) return subdata @@ -315,8 +505,8 @@ def connect_eqpt(from_, in_, to_): return connections -def eqpt_in_city_to_city(in_city, to_city, direction='egress'): - rev_direction = 'ingress' if direction == 'egress' else 'egress' +def eqpt_in_city_to_city(in_city, to_city, direction='east'): + rev_direction = 'west' if direction == 'east' else 'east' amp_direction = f'{direction}_amp_type' amp_rev_direction = f'{rev_direction}_amp_type' return_eqpt = '' @@ -352,9 +542,9 @@ def fiber_link(from_city, to_city): link = links_by_city[from_city] l = next(l for l in link if l.from_city in source_dest and l.to_city in source_dest) if l.from_city == from_city: - fiber = f'fiber ({l.from_city} → {l.to_city})-{l.east_cable}' + fiber = f'fiber ({l.from_city} \u2192 {l.to_city})-{l.east_cable}' else: - fiber = f'fiber ({l.to_city} → {l.from_city})-{l.west_cable}' + fiber = f'fiber ({l.to_city} \u2192 {l.from_city})-{l.west_cable}' return fiber @@ -375,8 +565,12 @@ def midpoint(city_a, city_b): #output_json_file_name = 'coronet_conus_example.json' #TODO get column size automatically from tupple size + NODES_COLUMN = 7 +NODES_LINE = 4 LINKS_COLUMN = 16 +LINKS_LINE = 3 +EQPTS_LINE = 3 EQPTS_COLUMN = 12 parser = ArgumentParser() parser.add_argument('workbook', nargs='?', type=Path , default='meshTopologyExampleV2.xls') diff --git a/gnpy/core/elements.py b/gnpy/core/elements.py index 9372a79c..9cc50601 100644 --- a/gnpy/core/elements.py +++ b/gnpy/core/elements.py @@ -18,14 +18,14 @@ Network elements MUST implement two attributes .uid and .name representing a unique identifier and a printable name. ''' -from numpy import abs, arange, arcsinh, array, exp +from numpy import abs, arange, arcsinh, array, exp, divide, errstate from numpy import interp, log10, mean, pi, polyfit, polyval, sum from scipy.constants import c, h from collections import namedtuple from gnpy.core.node import Node from gnpy.core.units import UNITS -from gnpy.core.utils import lin2db, db2lin, itufs +from gnpy.core.utils import lin2db, db2lin, itufs, snr_sum class Transceiver(Node): def __init__(self, *args, **kwargs): @@ -35,23 +35,46 @@ class Transceiver(Node): self.osnr_nli = None self.snr = None self.passive = False + self.baud_rate = None - def _calc_snr(self, spectral_info): - ase = [c.power.ase for c in spectral_info.carriers] - nli = [c.power.nli for c in spectral_info.carriers] - if min(ase) > 1e-20: - self.osnr_ase = [lin2db(c.power.signal/c.power.ase) + def _calc_snr(self, spectral_info): + with errstate(divide='ignore'): + self.baud_rate = [c.baud_rate for c in spectral_info.carriers] + ratio_01nm = [lin2db(12.5e9/b_rate) for b_rate in self.baud_rate] + + #set raw values to record original calculation, before update_snr() + self.raw_osnr_ase = [lin2db(divide(c.power.signal, c.power.ase)) + for c in spectral_info.carriers] + self.raw_osnr_ase_01nm = [ase - ratio for ase, ratio + in zip(self.raw_osnr_ase, ratio_01nm)] + self.raw_osnr_nli = [lin2db(divide(c.power.signal, c.power.nli)) for c in spectral_info.carriers] - ratio_01nm = [lin2db(12.5e9/c.baud_rate) - for c in spectral_info.carriers] - self.osnr_ase_01nm = [ase - ratio for ase, ratio - in zip(self.osnr_ase, ratio_01nm)] - if min(nli) > 1e-20: - self.osnr_nli = [lin2db(c.power.signal/c.power.nli) - for c in spectral_info.carriers] - self.snr = [lin2db(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] + self.osnr_ase = self.raw_osnr_ase + self.osnr_ase_01nm = self.raw_osnr_ase_01nm + self.osnr_nli = self.raw_osnr_nli + self.snr = self.raw_snr + + def update_snr(self, *args): + """ + snr_added in 0.1nm + compute SNR penalties such as transponder Tx_osnr or Roadm add_drop_osnr + only applied in request.py / propagate on the last Trasceiver node of the path + all penalties are added in a single call because to avoid uncontrolled cumul + """ + #use raw_values so that the added snr penalties are not cumulated + snr_added = 0 + for s in args: + snr_added += db2lin(-s) + snr_added = -lin2db(snr_added) + self.osnr_ase = list(map(lambda x,y:snr_sum(x,y,snr_added), + self.raw_osnr_ase, self.baud_rate)) + self.snr = list(map(lambda x,y:snr_sum(x,y,snr_added), + self.raw_snr, self.baud_rate)) + self.osnr_ase_01nm = list(map(lambda x:snr_sum(x,12.5e9,snr_added), + self.raw_osnr_ase_01nm)) @property def to_json(self): @@ -80,7 +103,7 @@ class Transceiver(Node): return '\n'.join([f'{type(self).__name__} {self.uid}', - f' OSNR ASE (1nm): {osnr_ase_01nm:.2f}', + f' OSNR ASE (0.1nm): {osnr_ase_01nm:.2f}', f' OSNR ASE (signal bw): {osnr_ase:.2f}', f' SNR total (signal bw): {snr:.2f}']) @@ -98,7 +121,9 @@ class Roadm(Node): params = {'loss':None} super().__init__(*args, params=RoadmParams(**params), **kwargs) self.loss = self.params.loss - self.pch_out = None + self.target_pch_out_db = None #set in Networks.py by def set_roadm_loss + self.effective_pch_out_db = None + self.effective_loss = None #set in self.propagate self.passive = True @property @@ -116,11 +141,20 @@ class Roadm(Node): def __str__(self): return '\n'.join([f'{type(self).__name__} {self.uid}', - f' loss (dB): {self.loss:.2f}', - f' pch out (dBm): {self.pch_out!r}']) + f' loss (dB): {self.effective_loss:.2f}', + f' pch out (dBm): {self.effective_pch_out_db!r}']) - def propagate(self, *carriers): - attenuation = db2lin(self.loss) + def propagate(self, pref, *carriers): + #pin_target and loss are read from eqpt_config.json['Roadm'] + #all ingress channels in xpress are set to this power level + #but add channels are not, so we define an effective loss + #in the case of add channels + if self.target_pch_out_db: + self.effective_loss = pref.pi - self.target_pch_out_db + else: + self.effective_loss = self.loss + self.effective_pch_out_db = pref.pi - self.effective_loss + attenuation = db2lin(self.effective_loss) for carrier in carriers: pwr = carrier.power @@ -130,11 +164,10 @@ class Roadm(Node): yield carrier._replace(power=pwr) def update_pref(self, pref): - self.pch_out = round(pref.pi - self.loss, 2) - return pref._replace(p_span0=pref.p0, p_spani=pref.pi - self.loss) + return pref._replace(p_span0=pref.p0, p_spani=self.effective_pch_out_db) def __call__(self, spectral_info): - carriers = tuple(self.propagate(*spectral_info.carriers)) + carriers = tuple(self.propagate(spectral_info.pref, *spectral_info.carriers)) pref = self.update_pref(spectral_info.pref) return spectral_info.update(carriers=carriers, pref=pref) @@ -210,7 +243,9 @@ class Fiber(Node): self.con_out = self.params.con_out self.dispersion = self.params.dispersion # s/m/m self.gamma = self.params.gamma # 1/W/m - self.pch_out = None + self.pch_out_db = None + self.carriers_in = None + self.carriers_out = None # TODO|jla: discuss factor 2 in the linear lineic attenuation @property @@ -243,7 +278,8 @@ class Fiber(Node): f' pad att_in (dB): {self.att_in:.2f}', f' total loss (dB): {self.loss:.2f}', f' (includes conn loss (dB) in: {self.con_in:.2f} out: {self.con_out:.2f})', - f' (conn loss out includes EOL margin defined in eqpt_config.json)']) + f' (conn loss out includes EOL margin defined in eqpt_config.json)', + f' pch out (dBm): {self.pch_out_db!r}']) @property def fiber_loss(self): @@ -275,6 +311,25 @@ class Fiber(Node): aleff = 1 / (2 * alpha) return aleff + def carriers(self, loc, attr): + """retrieve carriers information + loc = (in, out) of the class element + attr = (ase, nli, signal, total) power information""" + if not (loc in ('in', 'out') and attr in ('nli', 'signal', 'total', 'ase')): + yield None + return + power_dict = { + 'nli': 'nonlinear_interference', + 'ase': 'amplified_spontaneous_emission' + } + attr = power_dict.get(attr, attr) + loc_attr = 'carriers_'+loc + for c in getattr(self, loc_attr) : + if attr == 'total': + yield c.power.ase+c.power.nli+c.power.signal + else: + yield c.power._asdict().get(attr, None) + def beta2(self, ref_wavelength=None): """ Returns beta2 from dispersion parameter. Dispersion is entered in ps/nm/km. @@ -359,12 +414,14 @@ class Fiber(Node): yield carrier._replace(power=pwr) def update_pref(self, pref): - self.pch_out = round(pref.pi - self.loss, 2) - return pref._replace(p_span0=pref.p0, p_spani=pref.pi - self.loss) + self.pch_out_db = round(pref.pi - self.loss, 2) + return pref._replace(p_span0=pref.p0, p_spani=self.pch_out_db) def __call__(self, spectral_info): + self.carriers_in = spectral_info.carriers carriers = tuple(self.propagate(*spectral_info.carriers)) pref = self.update_pref(spectral_info.pref) + self.carriers_out = carriers return spectral_info.update(carriers=carriers, pref=pref) class EdfaParams: @@ -420,13 +477,16 @@ class Edfa(Node): self.nf = None # dB edfa nf at operational.gain_target self.gprofile = None self.pin_db = None + self.nch = None self.pout_db = None self.dp_db = None #delta P with Pref (power swwep) in power mode - self.target_pch_db = None - self.effective_pch_db = None + self.target_pch_out_db = None + self.effective_pch_out_db = None self.passive = False self.effective_gain = self.operational.gain_target self.att_in = None + self.carriers_in = None + self.carriers_out = None @property def to_json(self): @@ -469,10 +529,29 @@ class Edfa(Node): f' Power In (dBm): {self.pin_db:.2f}', f' Power Out (dBm): {self.pout_db:.2f}', f' Delta_P (dB): {self.dp_db!r}', - f' target pch (dBm): {self.target_pch_db!r}', - f' effective pch (dBm): {self.effective_pch_db!r}', + f' target pch (dBm): {self.target_pch_out_db!r}', + f' effective pch (dBm): {self.effective_pch_out_db!r}', f' output VOA (dB): {self.operational.out_voa:.2f}']) + def carriers(self, loc, attr): + """retrieve carriers information + loc = (in, out) of the class element + attr = (ase, nli, signal, total) power information""" + if not (loc in ('in', 'out') and attr in ('nli', 'signal', 'total', 'ase')): + yield None + return + power_dict = { + 'nli': 'nonlinear_interference', + 'ase': 'amplified_spontaneous_emission' + } + attr = power_dict.get(attr, attr) + loc_attr = 'carriers_'+loc + for c in getattr(self, loc_attr) : + if attr == 'total': + yield c.power.ase+c.power.nli+c.power.signal + else: + yield c.power._asdict().get(attr, None) + def interpol_params(self, frequencies, pin, baud_rates, pref): """interpolate SI channel frequencies with the edfa dgt and gain_ripple frquencies from json set the edfa class __init__ None parameters : @@ -485,15 +564,20 @@ class Edfa(Node): self.interpol_gain_ripple = interp(self.channel_freq, amplifier_freq, self.params.gain_ripple) self.interpol_nf_ripple =interp(self.channel_freq, amplifier_freq, self.params.nf_ripple) + self.nch = frequencies.size self.pin_db = lin2db(sum(pin*1e3)) - """check power saturation and correct target_gain accordingly:""" - - if self.dp_db is not None: - self.target_pch_db = round(self.dp_db + pref.p0, 2) - self.effective_gain = self.target_pch_db - pref.pi + """in power mode: dp_db is defined and can be used to calculate the power target + This power target is used calculate the amplifier gain""" + if self.dp_db is not None: + self.target_pch_out_db = round(self.dp_db + pref.p0, 2) + self.effective_gain = self.target_pch_out_db - pref.pi + else: + self.effective_gain = self.operational.gain_target + + """check power saturation and correct target_gain accordingly:""" self.effective_gain = min(self.effective_gain, self.params.p_max - self.pin_db) - self.effective_pch_db = round(pref.pi + self.effective_gain, 2) + self.effective_pch_out_db = round(pref.pi + self.effective_gain, 2) self.nf = self._calc_nf() self.gprofile = self._gain_profile(pin) @@ -519,6 +603,10 @@ class Edfa(Node): nf_avg = lin2db(db2lin(self.params.nf_model.nf1) + db2lin(self.params.nf_model.nf2)/db2lin(g1a)) elif self.params.type_def == 'fixed_gain': nf_avg = self.params.nf_model.nf0 + elif self.params.type_def == 'openroadm': + pin_ch = self.pin_db - lin2db(self.nch) + # model OSNR = f(Pin) + nf_avg = pin_ch - polyval(self.params.nf_model.nf_coef, pin_ch) + 58 else: nf_avg = polyval(self.params.nf_fit_coeff, -dg) if avg: @@ -705,6 +793,8 @@ class Edfa(Node): p_spani=pref.pi + self.effective_gain - self.operational.out_voa) def __call__(self, spectral_info): + self.carriers_in = spectral_info.carriers carriers = tuple(self.propagate(spectral_info.pref, *spectral_info.carriers)) pref = self.update_pref(spectral_info.pref) + self.carriers_out = carriers return spectral_info.update(carriers=carriers, pref=pref) diff --git a/gnpy/core/equipment.py b/gnpy/core/equipment.py index eac94e1b..dcf910d7 100644 --- a/gnpy/core/equipment.py +++ b/gnpy/core/equipment.py @@ -13,20 +13,21 @@ from sys import exit from operator import itemgetter from math import isclose from pathlib import Path -from json import loads +from json import load from gnpy.core.utils import lin2db, db2lin, load_json from collections import namedtuple from gnpy.core.elements import Edfa Model_vg = namedtuple('Model_vg', 'nf1 nf2 delta_p') Model_fg = namedtuple('Model_fg', 'nf0') +Model_openroadm = namedtuple('Model_openroadm', 'nf_coef') Fiber = namedtuple('Fiber', 'type_variety dispersion gamma') Spans = namedtuple('Spans', 'power_mode delta_power_range_db max_length length_units \ max_loss padding EOL con_in con_out') Transceiver = namedtuple('Transceiver', 'type_variety frequency mode') -Roadms = namedtuple('Roadms', 'gain_mode_default_loss power_mode_pref') +Roadms = namedtuple('Roadms', 'gain_mode_default_loss power_mode_pout_target add_drop_osnr') SI = namedtuple('SI', 'f_min f_max baud_rate spacing roll_off \ - power_dbm power_range_db OSNR bit_rate') + power_dbm power_range_db tx_osnr sys_margins') AmpBase = namedtuple( 'AmpBase', 'type_variety type_def gain_flatmax gain_min p_max' @@ -43,14 +44,14 @@ class Amp(AmpBase): @classmethod def from_advanced_json(cls, filename, **kwargs): - with open(filename) as f: - json_data = loads(f.read()) + with open(filename, encoding='utf-8') as f: + 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) as f: - json_data = loads(f.read()) + with open(filename, encoding='utf-8') as f: + json_data = load(f) type_variety = kwargs['type_variety'] type_def = kwargs.get('type_def', 'variable_gain') #default compatibility with older json eqpt files nf_def = None @@ -79,6 +80,13 @@ class Amp(AmpBase): except KeyError: pass #nf0 is not needed for variable gain amp nf1, nf2, delta_p = nf_model(type_variety, gain_min, gain_max, nf_min, nf_max) nf_def = Model_vg(nf1, nf2, delta_p) + elif type_def == 'openroadm': + try: + nf_coef = kwargs.pop('nf_coef') + except KeyError: #nf_coef is expected for openroadm amp + print(f'missing nf_coef input for amplifier: {type_variety} in eqpt_config.json') + exit() + nf_def = Model_openroadm(nf_coef) return cls(**{**kwargs, **json_data, 'nf_model': nf_def}) @@ -140,24 +148,51 @@ def edfa_nf(gain_target, variety_type, equipment): params = amp_params._asdict(), operational = { 'gain_target': gain_target, - 'tilt_target': 0, - }) + 'tilt_target': 0 + } + ) + amp.pin_db = 0 + amp.nch = 88 return amp._calc_nf(True) def trx_mode_params(equipment, trx_type_variety='', trx_mode='', error_message=False): """return the trx and SI parameters from eqpt_config for a given type_variety and mode (ie format)""" trx_params = {} default_si_data = equipment['SI']['default'] + try: trxs = equipment['Transceiver'] - mode_params = next(mode for trx in trxs \ - if trx == trx_type_variety \ - for mode in trxs[trx].mode \ - if mode['format'] == trx_mode) - trx_params = {**mode_params} - trx_params['frequency'] = equipment['Transceiver'][trx_type_variety].frequency + #if called from path_requests_run.py, trx_mode is filled with None when not specified by user + #if called from transmission_main.py, trx_mode is '' + if trx_mode is not None: + mode_params = next(mode for trx in trxs \ + if trx == trx_type_variety \ + for mode in trxs[trx].mode \ + if mode['format'] == trx_mode) + trx_params = {**mode_params} + # sanity check: spacing baudrate must be smaller than min spacing + if trx_params['baud_rate'] > trx_params['min_spacing'] : + msg = f'Inconsistency in equipment library:\n Transpoder "{trx_type_variety}" mode "{trx_params["format"]}" '+\ + f'has baud rate: {trx_params["baud_rate"]*1e-9} GHz greater than min_spacing {trx_params["min_spacing"]*1e-9}.' + print(msg) + exit() + else: + mode_params = {"format": "undetermined", + "baud_rate": None, + "OSNR": None, + "bit_rate": None, + "roll_off": None, + "tx_osnr":None, + "min_spacing":None, + "cost":None} + trx_params = {**mode_params} + trx_params['f_min'] = equipment['Transceiver'][trx_type_variety].frequency['min'] + trx_params['f_max'] = equipment['Transceiver'][trx_type_variety].frequency['max'] + # TODO: novel automatic feature maybe unwanted if spacing is specified - trx_params['spacing'] = automatic_spacing(trx_params['baud_rate']) + # trx_params['spacing'] = automatic_spacing(trx_params['baud_rate']) + # temp = trx_params['spacing'] + # print(f'spacing {temp}') except StopIteration : if error_message: print(f'could not find tsp : {trx_type_variety} with mode: {trx_mode} in eqpt library') @@ -165,38 +200,49 @@ def trx_mode_params(equipment, trx_type_variety='', trx_mode='', error_message=F exit() else: # default transponder charcteristics - trx_params['frequency'] = {'min': default_si_data.f_min, 'max': default_si_data.f_max} + # mainly used with transmission_main_example.py + trx_params['f_min'] = default_si_data.f_min + trx_params['f_max'] = default_si_data.f_max trx_params['baud_rate'] = default_si_data.baud_rate trx_params['spacing'] = default_si_data.spacing - trx_params['OSNR'] = default_si_data.OSNR - trx_params['bit_rate'] = default_si_data.bit_rate + trx_params['OSNR'] = None + trx_params['bit_rate'] = None + trx_params['cost'] = None trx_params['roll_off'] = default_si_data.roll_off + trx_params['tx_osnr'] = default_si_data.tx_osnr + trx_params['min_spacing'] = None + nch = automatic_nch(trx_params['f_min'], trx_params['f_max'], trx_params['spacing']) + trx_params['nb_channel'] = nch + print(f'There are {nch} channels propagating') + trx_params['power'] = db2lin(default_si_data.power_dbm)*1e-3 - trx_params['nb_channel'] = automatic_nch(trx_params['frequency']['min'], - trx_params['frequency']['max'], - trx_params['spacing']) - print('N channels = ', trx_params['nb_channel']) + return trx_params def automatic_spacing(baud_rate): """return the min possible channel spacing for a given baud rate""" - spacing_list = [(38e9,50e9), (67e9,75e9), (92e9,100e9)] #list of possible tuples + # TODO : this should parametrized in a cfg file + spacing_list = [(33e9,37.5e9), (38e9,50e9), (50e9,62.5e9), (67e9,75e9), (92e9,100e9)] #list of possible tuples #[(max_baud_rate, spacing_for_this_baud_rate)] - acceptable_spacing_list = list(filter(lambda x : x[0]>baud_rate, spacing_list)) - if len(acceptable_spacing_list) < 1: - #can't find an adequate spacing from the list, so default to: - return baud_rate*1.2 - else: - #chose the lowest possible spacing - return min(acceptable_spacing_list, key=itemgetter(0))[1] + return min((s[1] for s in spacing_list if s[0] > baud_rate), default=baud_rate*1.2) def automatic_nch(f_min, f_max, spacing): return int((f_max - f_min)//spacing) +def automatic_fmax(f_min, spacing, nch): + return f_min + spacing * nch + def load_equipment(filename): json_data = load_json(filename) return equipment_from_json(json_data, filename) +def update_trx_osnr(equipment): + """add sys_margins to all Transceivers OSNR values""" + for trx in equipment['Transceiver'].values(): + for m in trx.mode: + m['OSNR'] = m['OSNR'] + equipment['SI']['default'].sys_margins + return equipment + def equipment_from_json(json_data, filename): """build global dictionnary eqpt_library that stores all eqpt characteristics: edfa type type_variety, fiber type_variety @@ -208,17 +254,18 @@ def equipment_from_json(json_data, filename): """ equipment = {} for key, entries in json_data.items(): + equipment[key] = {} + typ = globals()[key] for entry in entries: - if key not in equipment: - equipment[key] = {} - subkey = entry.get('type_variety', 'default') - typ = globals()[key] + subkey = entry.get('type_variety', 'default') if key == 'Edfa': if 'advanced_config_from_json' in entry: config = Path(filename).parent / entry.pop('advanced_config_from_json') - typ = lambda **kws: Amp.from_advanced_json(config, **kws) + equipment[key][subkey] = Amp.from_advanced_json(config, **entry) else: config = Path(filename).parent / 'default_edfa_config.json' - typ = lambda **kws: Amp.from_default_json(config, **kws) - equipment[key][subkey] = typ(**entry) + equipment[key][subkey] = Amp.from_default_json(config, **entry) + else: + equipment[key][subkey] = typ(**entry) + equipment = update_trx_osnr(equipment) return equipment diff --git a/gnpy/core/info.py b/gnpy/core/info.py index d63b3069..c1da0cd2 100644 --- a/gnpy/core/info.py +++ b/gnpy/core/info.py @@ -11,9 +11,10 @@ This module contains classes for modelling SpectralInformation. from collections import namedtuple from numpy import array -from gnpy.core.utils import lin2db +from gnpy.core.utils import lin2db, db2lin from json import loads from gnpy.core.utils import load_json +from gnpy.core.equipment import automatic_nch, automatic_spacing class ConvenienceAccess: @@ -56,17 +57,17 @@ def merge_input_spectral_information(*si): #TODO pass -def create_input_spectral_information(f_min, roll_off, baud_rate, power, spacing, nb_channel): +def create_input_spectral_information(f_min, f_max, roll_off, baud_rate, power, spacing): # pref in dB : convert power lin into power in dB pref = lin2db(power * 1e3) si = SpectralInformation(pref=Pref(pref, pref)) + nb_channel = automatic_nch(f_min, f_max, spacing) si = si.update(carriers=[ Channel(f, (f_min+spacing*f), baud_rate, roll_off, Power(power, 0, 0)) for f in range(1,nb_channel+1) ]) return si - if __name__ == '__main__': pref = lin2db(power * 1e3) si = SpectralInformation( diff --git a/gnpy/core/network.py b/gnpy/core/network.py index db236709..6e4131d2 100644 --- a/gnpy/core/network.py +++ b/gnpy/core/network.py @@ -24,11 +24,11 @@ from collections import namedtuple logger = getLogger(__name__) -def load_network(filename, equipment): +def load_network(filename, equipment, name_matching = False): json_filename = '' if filename.suffix.lower() == '.xls': logger.info('Automatically generating topology JSON file') - json_filename = convert_file(filename) + json_filename = convert_file(filename, name_matching) elif filename.suffix.lower() == '.json': json_filename = filename else: @@ -64,7 +64,12 @@ def network_from_json(json_data, equipment): for cx in json_data['connections']: from_node, to_node = cx['from_node'], cx['to_node'] - g.add_edge(nodes[from_node], nodes[to_node]) + try: + g.add_edge(nodes[from_node], nodes[to_node]) + except KeyError: + msg = f'In {__name__} network_from_json function:\n\tcan not find {from_node} or {to_node} defined in {cx}' + print(msg) + exit(1) return g @@ -126,16 +131,18 @@ def select_edfa(gain_target, power_target, equipment): # =>chose the amp with the best NF among the acceptable ones: return min(acceptable_power_list, key=itemgetter(3)).variety #filter on NF + def set_roadm_loss(network, equipment, pref_ch_db): roadms = [roadm for roadm in network if isinstance(roadm, Roadm)] power_mode = equipment['Spans']['default'].power_mode default_roadm_loss = equipment['Roadms']['default'].gain_mode_default_loss - pref_roadm_db = equipment['Roadms']['default'].power_mode_pref - roadm_loss = pref_ch_db - pref_roadm_db + pout_target = equipment['Roadms']['default'].power_mode_pout_target + roadm_loss = pref_ch_db - pout_target for roadm in roadms: if power_mode: roadm.loss = roadm_loss + roadm.target_pch_out_db = pout_target elif roadm.loss == None: roadm.loss = default_roadm_loss @@ -171,7 +178,13 @@ def target_power(dp_from_gain, network, node, equipment): #get_fiber_dp def prev_node_generator(network, node): """fused spans interest: iterate over all predecessors while they are Fused or Fiber type""" - prev_node = next(n for n in network.predecessors(node)) + try: + prev_node = next(n for n in network.predecessors(node)) + except StopIteration: + msg = f'In {__name__} prev_node_generator function:\n\t{node.uid} is not properly connected, please check network topology' + print(msg) + logger.critical(msg) + exit(1) # yield and re-iterate if isinstance(prev_node, Fused) or isinstance(node, Fused): yield prev_node @@ -182,7 +195,11 @@ def prev_node_generator(network, node): def next_node_generator(network, node): """fused spans interest: iterate over all successors while they are Fused or Fiber type""" - next_node = next(n for n in network.successors(node)) + try: + next_node = next(n for n in network.successors(node)) + except StopIteration: + print(f'In {__name__} next_node_generator function:\n\t{node.uid} is not properly connected, please check network topology') + exit(1) # yield and re-iterate if isinstance(next_node, Fused) or isinstance(node, Fused): yield next_node @@ -334,26 +351,21 @@ def split_fiber(network, fiber, bounds, target_length, equipment): next_node = next(network.successors(fiber)) prev_node = next(network.predecessors(fiber)) except StopIteration: - print(f'{repr(fiber)} is not properly connected, please check network topology') + + print(f'In {__name__} split_fiber function:\n\t{fiber.uid} is not properly connected, please check network topology') exit() - network.remove_edge(fiber, next_node) - network.remove_edge(prev_node, fiber) network.remove_node(fiber) - # update connector loss parameter with default values + fiber_params = fiber.params._asdict() + fiber_params['length'] = new_length / UNITS[fiber.params.length_units] fiber_params['con_in'] = fiber.con_in fiber_params['con_out'] = fiber.con_out - new_spans = [ - Fiber( - uid = f'{fiber.uid}_({span}/{n_spans})', - metadata = fiber.metadata, - params = fiber_params - ) for span in range(n_spans) - ] - for new_span in new_spans: - new_span.length = new_length - network.add_node(new_span) + + for span in range(n_spans): + new_span = Fiber(uid = f'{fiber.uid}_({span+1}/{n_spans})', + metadata = fiber.metadata, + params = fiber_params) network.add_edge(prev_node, new_span) prev_node = new_span network.add_edge(prev_node, next_node) @@ -373,7 +385,13 @@ def add_fiber_padding(network, fibers, padding): if isinstance(fiber, Fiber))""" for fiber in fibers: this_span_loss = span_loss(network, fiber) - next_node = next(network.successors(fiber)) + try: + next_node = next(network.successors(fiber)) + except StopIteration: + msg = f'In {__name__} add_fiber_padding function:\n\t{fiber.uid} is not properly connected, please check network topology' + print(msg) + logger.critical(msg) + exit(1) if this_span_loss < padding and not (isinstance(next_node, Fused)): #add a padding att_in at the input of the 1st fiber: #address the case when several fibers are spliced together diff --git a/gnpy/core/node.py b/gnpy/core/node.py index 52265338..875b6d94 100644 --- a/gnpy/core/node.py +++ b/gnpy/core/node.py @@ -36,7 +36,7 @@ class Node: @property def coords(self): - return tuple(self.lng, self.lat) + return self.lng, self.lat @property def location(self): diff --git a/gnpy/core/request.py b/gnpy/core/request.py index c711e20a..16aa69ff 100644 --- a/gnpy/core/request.py +++ b/gnpy/core/request.py @@ -15,9 +15,11 @@ and feasibility See: draft-ietf-teas-yang-path-computation-01.txt """ +from sys import exit from collections import namedtuple from logging import getLogger, basicConfig, CRITICAL, DEBUG, INFO -from networkx import (dijkstra_path, NetworkXNoPath) +from networkx import (dijkstra_path, NetworkXNoPath, all_simple_paths) +from networkx.utils import pairwise from numpy import mean from gnpy.core.service_sheet import convert_service_sheet, Request_element, Element from gnpy.core.elements import Transceiver, Roadm, Edfa, Fused @@ -26,12 +28,14 @@ from gnpy.core.utils import db2lin, lin2db from gnpy.core.info import create_input_spectral_information, SpectralInformation, Channel, Power from copy import copy, deepcopy from csv import writer +from math import ceil logger = getLogger(__name__) RequestParams = namedtuple('RequestParams','request_id source destination trx_type'+ -' trx_mode nodes_list loose_list spacing power nb_channel frequency format baud_rate OSNR bit_rate roll_off') +' trx_mode nodes_list loose_list spacing power nb_channel f_min f_max format baud_rate OSNR bit_rate roll_off tx_osnr min_spacing cost path_bandwidth') +DisjunctionParams = namedtuple('DisjunctionParams','disjunction_id relaxable link_diverse node_diverse disjunctions_req') class Path_request: def __init__(self, *args, **params): @@ -47,26 +51,64 @@ class Path_request: self.spacing = params.spacing self.power = params.power self.nb_channel = params.nb_channel - self.frequency = params.frequency + self.f_min = params.f_min + self.f_max = params.f_max self.format = params.format self.OSNR = params.OSNR self.bit_rate = params.bit_rate self.roll_off = params.roll_off + self.tx_osnr = params.tx_osnr + self.min_spacing = params.min_spacing + self.cost = params.cost + self.path_bandwidth = params.path_bandwidth def __str__(self): return '\n\t'.join([ f'{type(self).__name__} {self.request_id}', f'source: {self.source}', f'destination: {self.destination}']) def __repr__(self): + if self.baud_rate is not None: + temp = self.baud_rate * 1e-9 + temp2 = self.bit_rate * 1e-9 + else: + temp = self.baud_rate + temp2 = self.bit_rate + return '\n\t'.join([ f'{type(self).__name__} {self.request_id}', f'source: \t{self.source}', f'destination:\t{self.destination}', f'trx type:\t{self.tsp}', f'trx mode:\t{self.tsp_mode}', - f'baud_rate:\t{self.baud_rate * 1e-9} Gbaud', - f'bit_rate:\t{self.bit_rate * 1e-9} Gb/s', + f'baud_rate:\t{temp} Gbaud', + f'bit_rate:\t{temp2} Gb/s', f'spacing:\t{self.spacing * 1e-9} GHz', - f'power: \t{round(lin2db(self.power)+30,2)} dBm' + f'power: \t{round(lin2db(self.power)+30,2)} dBm', + f'nb channels: \t{self.nb_channel}', + f'path_bandwidth: \t{round(self.path_bandwidth * 1e-9,2)} Gbit/s', + f'nodes-list:\t{self.nodes_list}', + f'loose-list:\t{self.loose_list}' + '\n']) +class Disjunction: + def __init__(self, *args, **params): + params = DisjunctionParams(**params) + self.disjunction_id = params.disjunction_id + self.relaxable = params.relaxable + self.link_diverse = params.link_diverse + self.node_diverse = params.node_diverse + self.disjunctions_req = params.disjunctions_req + + def __str__(self): + return '\n\t'.join([f'relaxable: {self.relaxable}', + f'link-diverse: {self.link_diverse}', + f'node-diverse: {self.node_diverse}', + f'request-id-numbers: {self.disjunctions_req}'] + ) + def __repr__(self): + return '\n\t'.join([ f'{type(self).__name__} {self.disjunction_id}', + f'relaxable: {self.relaxable}', + f'link-diverse: {self.link_diverse}', + f'node-diverse: {self.node_diverse}', + f'request-id-numbers: {self.disjunctions_req}' '\n']) class Result_element(Element): @@ -75,11 +117,17 @@ class Result_element(Element): self.path_request = path_request self.computed_path = computed_path hop_type = [] - for e in computed_path : - if isinstance(e, Transceiver) : - hop_type.append(' - '.join([path_request.tsp,path_request.tsp_mode])) - else: - hop_type.append('not recorded') + if len(computed_path)>0 : + for e in computed_path : + if isinstance(e, Transceiver) : + hop_type.append(' - '.join([path_request.tsp,path_request.tsp_mode])) + else: + hop_type.append('not recorded') + else: + # TODO differentiate empty path in case not feasible because of tsp or not feasible because + # ther is no path connecting the nodes (whatever the tsp) + mode = 'not feasible with this transponder' + hop_type = ' - '.join([path_request.tsp,mode]) self.hop_type = hop_type uid = property(lambda self: repr(self)) @property @@ -108,6 +156,10 @@ class Result_element(Element): { 'metric-type': 'reference_power', 'accumulative-value': self.path_request.power + }, + { + 'metric-type': 'path_bandwidth', + 'accumulative-value': self.path_request.path_bandwidth } ], 'path-srlgs': { @@ -121,7 +173,7 @@ class Result_element(Element): 'unnumbered-hop': { 'node-id': self.path_request.source, 'link-tp-id': self.path_request.source, - 'hop-type': ' - '.join([self.path_request.tsp, self.path_request.tsp_mode]), + 'hop-type': self.hop_type, 'direction': 'not used' }, 'label-hop': { @@ -138,7 +190,7 @@ class Result_element(Element): 'unnumbered-hop': { 'node-id': self.path_request.destination, 'link-tp-id': self.path_request.destination, - 'hop-type': ' - '.join([self.path_request.tsp, self.path_request.tsp_mode]), + 'hop-type': self.hop_type, 'direction': 'not used' }, 'label-hop': { @@ -176,6 +228,10 @@ class Result_element(Element): { 'metric-type': 'reference_power', 'accumulative-value': self.path_request.power + }, + { + 'metric-type': 'path_bandwidth', + 'accumulative-value': self.path_request.path_bandwidth } ], 'path-srlgs': { @@ -212,50 +268,120 @@ def compute_constrained_path(network, req): trx = [n for n in network.nodes() if isinstance(n, Transceiver)] roadm = [n for n in network.nodes() if isinstance(n, Roadm)] edfa = [n for n in network.nodes() if isinstance(n, Edfa)] + anytypenode = [n for n in network.nodes()] + source = next(el for el in trx if el.uid == req.source) - # start the path with its source - # TODO : avoid loops due to constraints , guess name base on string, - # avoid crashing if on req is not correct - total_path = [source] - for n in req.nodes_list: - # print(n) + + # This method ensures that the constraint can be satisfied without loops + # except when it is not possible : eg if constraints makes a loop + # It requires that the source, dest and nodes are correct (no error in the names) + destination = next(el for el in trx if el.uid == req.destination) + nodes_list = [] + for n in req.nodes_list : + # for debug excel print(n) + nodes_list.append(next(el for el in anytypenode if el.uid == n)) + # nodes_list contains at least the destination + if nodes_list is None : + msg = f'Request {req.request_id} problem in the constitution of nodes_list: should at least include destination' + logger.critical(msg) + exit() + if req.nodes_list[-1] != req.destination: + msg = f'Request {req.request_id} malformed list of nodes: last node should be destination trx' + logger.critical(msg) + exit() + + if len(nodes_list) == 1 : try : - node = next(el for el in trx if el.uid == n) - except StopIteration: - try: - node = next(el for el in roadm if el.uid == f'roadm {n}') - except StopIteration: - try: - node = next(el for el in edfa - if el.uid.startswith(f'egress edfa in {n}')) - except StopIteration: - msg = f'could not find node : {n} in network topology: \ - not a trx, roadm, edfa or fused element' - logger.critical(msg) - raise ValueError(msg) - # extend path list without repeating source -> skip first element in the list - try: - total_path.extend(dijkstra_path(network, source, node)[1:]) - source = node + total_path = dijkstra_path(network, source, destination) except NetworkXNoPath: - # for debug - # print(req.loose_list) - # print(req.nodes_list.index(n)) + 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) + print(msg) + total_path = [] + else : + all_simp_pths = list(all_simple_paths(network,source=source,\ + target=destination, cutoff=120)) + candidate = [] + for p in all_simp_pths : + if ispart(nodes_list, p) : + # print(f'selection{[el.uid for el in p if el in roadm]}') + candidate.append(p) + # select the shortest path (in nb of hops) + if len(candidate)>0 : + candidate.sort(key=lambda x: len(x)) + total_path = candidate[0] + else: if req.loose_list[req.nodes_list.index(n)] == 'loose': - print(f'could not find a path from {source.uid} to loose node : {n} in network topology') - print(f'node {n} is skipped') + print(f'\x1b[1;33;40m'+f'Request {req.request_id} could not find a path crossing {nodes_list} in network topology'+ '\x1b[0m') + print(f'constraint ignored') + total_path = dijkstra_path(network, source, destination) else: - msg = f'could not find a path from {source.uid} to node : {n} in network topology' + 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) - #raise ValueError(msg) print(msg) total_path = [] -# preparing disjonction feature - # for p in all_simple_paths(network,\ - # source=next(el for el in trx if el.uid == req.source),\ - # target=next(el for el in trx if el.uid == req.destination)): - # print([e.uid for e in p if isinstance(e,Roadm)]) + # obsolete method: this does not guaranty to avoid loops or correct results + # Here is the demonstration : + # 1 1 + # eg a----b-----c + # |1 |0.5 |1 + # e----f--h--g + # 1 0.5 0.5 + # if I have to compute a to g with constraint f-c + # result will be a concatenation of: a-b-f and f-b-c and c-g + # which means a loop. + # if to avoid loops I iteratively suppress edges of the segmenst in the topo + # segment 1 = a-b-f + # 1 + # eg a b-----c + # |1 |1 + # e----f--h--g + # 1 0.5 0.5 + # then + # segment 2 = f-h-g-c + # 1 + # eg a b-----c + # |1 + # e----f h g + # 1 + # then there is no more path to g destination + # + # + # total_path = [source] + + # for n in req.nodes_list: + # try : + # node = next(el for el in trx if el.uid == n) + # except StopIteration: + # try: + # node = next(el for el in anytypenode if el.uid == n) + # except StopIteration: + # try: + # # TODO this test is not giving good results: full name of the + # # amp is required to avoid ambiguity on the direction + # node = next(el for el in anytypenode + # if n in el.uid) + # except StopIteration: + # msg = f'could not find node : {n} in network topology: \ + # not a trx, roadm, edfa, fiber or fused element' + # logger.critical(msg) + # raise ValueError(msg) + # # extend path list without repeating source -> skip first element in the list + # try: + # # to avoid looping back: use an alternate graph were current path edges and vertex are suppressed + + # total_path.extend(dijkstra_path(network, source, node)[1:]) + # source = node + # except NetworkXNoPath: + # if req.loose_list[req.nodes_list.index(n)] == 'loose': + # print(f'could not find a path from {source.uid} to loose node : {n} in network topology') + # print(f'node {n} is skipped') + # else: + # msg = f'could not find a path from {source.uid} to node : {n} in network topology' + # logger.critical(msg) + # print(msg) + # total_path = [] return total_path @@ -263,14 +389,63 @@ def propagate(path, req, equipment, show=False): #update roadm loss in case of power sweep (power mode only) set_roadm_loss(path, equipment, lin2db(req.power*1e3)) si = create_input_spectral_information( - req.frequency['min'], req.roll_off, - req.baud_rate, req.power, req.spacing, req.nb_channel) + req.f_min, req.f_max, req.roll_off, req.baud_rate, + req.power, req.spacing) for el in path: si = el(si) if show : print(el) + path[-1].update_snr(req.tx_osnr, equipment['Roadms']['default'].add_drop_osnr) return path +def propagate_and_optimize_mode(path, req, equipment): + #update roadm loss in case of power sweep (power mode only) + set_roadm_loss(path, equipment, lin2db(req.power*1e3)) + # if mode is unknown : loops on the modes starting from the highest baudrate fiting in the + # step 1: create an ordered list of modes based on baudrate + baudrate_to_explore = list(set([m['baud_rate'] for m in equipment['Transceiver'][req.tsp].mode + if float(m['min_spacing'])<= req.spacing])) + # TODO be carefull on limits cases if spacing very close to req spacing eg 50.001 50.000 + baudrate_to_explore = sorted(baudrate_to_explore, reverse=True) + if baudrate_to_explore : + # at least 1 baudrate can be tested wrt spacing + for b in baudrate_to_explore : + modes_to_explore = [m for m in equipment['Transceiver'][req.tsp].mode + if m['baud_rate'] == b] + modes_to_explore = sorted(modes_to_explore, + key = lambda x: x['bit_rate'], reverse=True) + # print(modes_to_explore) + # step2 : computes propagation for each baudrate: stop and select the first that passes + found_a_feasible_mode = False + # TODO : the case of roll of is not included: for now use SI one + # TODO : if the loop in mode optimization does not have a feasible path, then bugs + si = create_input_spectral_information( + req.f_min, req.f_max, equipment['SI']['default'].roll_off, + b, req.power, req.spacing) + for el in path: + si = el(si) + for m in modes_to_explore : + if path[-1].snr is not None: + path[-1].update_snr(m['tx_osnr'], equipment['Roadms']['default'].add_drop_osnr) + if round(min(path[-1].snr+lin2db(b/(12.5e9))),2) > m['OSNR'] : + found_a_feasible_mode = True + return path, m + else: + return [], None + # only get to this point if no baudrate/mode satisfies OSNR requirement + + # returns the last propagated path and mode + msg = f'\tWarning! Request {req.request_id}: no mode satisfies path SNR requirement.\n' + print(msg) + logger.info(msg) + return [],None + else : + # no baudrate satisfying spacing + msg = f'\tWarning! Request {req.request_id}: no baudrate satisfies spacing requirement.\n' + print(msg) + logger.info(msg) + return [], None + def jsontocsv(json_data,equipment,fileout): # read json path result file in accordance with: @@ -279,9 +454,10 @@ def jsontocsv(json_data,equipment,fileout): # and write results in an CSV file mywriter = writer(fileout) - mywriter.writerow(('path-id','source','destination','transponder-type',\ - 'transponder-mode','baud rate (Gbaud)', 'input power (dBm)','path',\ - 'OSNR@bandwidth','OSNR@0.1nm','SNR@bandwidth','SNR@0.1nm','Pass?')) + mywriter.writerow(('path-id','source','destination','path_bandwidth','Pass?',\ + 'nb of tsp pairs','total cost','transponder-type','transponder-mode',\ + 'OSNR@0.1nm','SNR@0.1nm','SNR@bandwidth','baud rate (Gbaud)',\ + 'input power (dBm)','path')) tspjsondata = equipment['Transceiver'] #print(tspjsondata) for p in json_data['path']: @@ -290,24 +466,22 @@ def jsontocsv(json_data,equipment,fileout): ['path-route-object']['unnumbered-hop']['node-id'] destination = p['path-properties']['path-route-objects'][-1]\ ['path-route-object']['unnumbered-hop']['node-id'] + # selects only roadm nodes pth = ' | '.join([ e['path-route-object']['unnumbered-hop']['node-id'] - for e in p['path-properties']['path-route-objects']]) + for e in p['path-properties']['path-route-objects'] + if e['path-route-object']['unnumbered-hop']['node-id'].startswith('roadm') or e['path-route-object']['unnumbered-hop']['node-id'].startswith('Edfa')]) [tsp,mode] = p['path-properties']['path-route-objects'][0]\ ['path-route-object']['unnumbered-hop']['hop-type'].split(' - ') # find the min acceptable OSNR, baud rate from the eqpt library based on tsp (tupe) and mode (format) - try: - [minosnr, baud_rate] = next([m['OSNR'] , m['baud_rate']] + # loading equipment already tests the existence of tsp type and mode: + if mode !='not feasible with this transponder' : + [minosnr, baud_rate, bit_rate, cost] = next([m['OSNR'] , m['baud_rate'] , m['bit_rate'], m['cost']] for m in equipment['Transceiver'][tsp].mode if m['format']==mode) - - # for debug - # print(f'coucou {baud_rate}') - except IndexError: - msg = f'could not find tsp : {self.tsp} with mode: {self.tsp_mode} in eqpt library' - - raise ValueError(msg) - output_snr = next(e['accumulative-value'] + # else: + # [minosnr, baud_rate, bit_rate] = ['','','',''] + output_snr = next(e['accumulative-value'] for e in p['path-properties']['path-metric'] if e['metric-type'] == 'SNR@0.1nm') output_snrbandwidth = next(e['accumulative-value'] for e in p['path-properties']['path-metric'] if e['metric-type'] == 'SNR@bandwidth') @@ -317,21 +491,417 @@ def jsontocsv(json_data,equipment,fileout): for e in p['path-properties']['path-metric'] if e['metric-type'] == 'OSNR@bandwidth') power = next(e['accumulative-value'] for e in p['path-properties']['path-metric'] if e['metric-type'] == 'reference_power') + path_bandwidth = next(e['accumulative-value'] + for e in p['path-properties']['path-metric'] if e['metric-type'] == 'path_bandwidth') if isinstance(output_snr, str): - isok = '' + isok = False + nb_tsp = 0 + pthbdbw = round(path_bandwidth*1e-9,2) + rosnr = '' + rsnr = '' + rsnrb = '' + br = '' + pw = '' + total_cost = '' else: - isok = output_snr >= minosnr + isok = output_snr >= minosnr + nb_tsp = ceil(path_bandwidth / bit_rate) + pthbdbw = round(path_bandwidth*1e-9,2) + rosnr = round(output_osnr,2) + rsnr = round(output_snr,2) + rsnrb = round(output_snrbandwidth,2) + br = round(baud_rate*1e-9,2) + pw = round(lin2db(power)+30,2) + total_cost = nb_tsp * cost mywriter.writerow((path_id, source, destination, + pthbdbw, + isok, + nb_tsp, + total_cost, tsp, mode, - baud_rate*1e-9, - round(lin2db(power)+30,2), - pth, - output_osnrbandwidth, - output_osnr, - output_snrbandwidth, - output_snr, - isok + rosnr, + rsnr, + rsnrb, + br, + pw, + pth )) + + +def compute_path_dsjctn(network, equipment, pathreqlist, disjunctions_list): + # pathreqlist is a list of Path_request objects + # disjunctions_list a list of Disjunction objects + + # given a network, a list of requests with the set of disjunction features between + # request, the function computes the set of path satisfying : first the disjunction + # constraint and second the routing constraint if the request include an explicit + # set of elements to pass through. + # the algorithm used allows to specify disjunction for demands not sharing source or + # destination. + # a request might be declared as disjoint from several requests + # it is a iterative process: + # first computes a list of all shortest path (this may add computation time) + # second elaborate the set of path solution for each synchronization vector + # third select only the candidates that satisfy all synchronization vectors they belong to + # fourth apply route constraints : remove candidate path that do not satisfy the constraint + # fifth select the first candidate among the set of candidates. + # the example network used in comments has been added to the set of data tests files + + # define the list to be returned + path_res_list = [] + + # all disjctn must be computed at once together to avoid blocking + # 1 1 + # eg a----b-----c + # |1 |0.5 |1 + # e----f--h--g + # 1 0.5 0.5 + # if I have to compute a to g and a to h + # I must not compute a-b-f-h-g, otherwise there is no disjoint path remaining for a to h + # instead I should list all most disjoint path and select the one that have the less + # number of commonalities + # \ path abfh aefh abcgh + # \___cost 2 2.5 3.5 + # path| cost + # abfhg| 2.5 x x x + # abcg | 3 x x + # aefhg| 3 x x x + # from this table abcg and aefh have no common links and should be preferred + # even they are not the shortest paths + + # build the list of pathreqlist elements not concerned by disjunction + global_disjunctions_list = [e for d in disjunctions_list for e in d.disjunctions_req ] + pathreqlist_simple = [e for e in pathreqlist if e.request_id not in global_disjunctions_list] + pathreqlist_disjt = [e for e in pathreqlist if e.request_id in global_disjunctions_list] + + # use a mirror class to record path and the corresponding requests + class Pth: + def __init__(self, req, pth, simplepth): + self.req = req + self.pth = pth + self.simplepth = simplepth + + # step 1 + # for each remaining request compute a set of simple path + allpaths = {} + rqs = {} + simple_rqs = {} + simple_rqs_reversed = {} + for pathreq in pathreqlist_disjt : + all_simp_pths = list(all_simple_paths(network,\ + source=next(el for el in network.nodes() if el.uid == pathreq.source),\ + target=next(el for el in network.nodes() if el.uid == pathreq.destination),\ + cutoff=80)) + # sort them + all_simp_pths = sorted(all_simp_pths, key=lambda path: len(path)) + # reversed direction paths required to check disjunction on both direction + all_simp_pths_reversed = [] + for pth in all_simp_pths: + all_simp_pths_reversed.append(find_reversed_path(pth,network)) + rqs[pathreq.request_id] = all_simp_pths + temp =[] + for p in all_simp_pths : + # build a short list representing each roadm+direction with the first item + # start enumeration at 1 to avoid Trx in the list + s = [e.uid for i,e in enumerate(p[1:-1]) \ + if (isinstance(e,Roadm) | (isinstance(p[i],Roadm) ))] + temp.append(s) + # id(s) is unique even if path is the same: two objects with same + # path have two different ids + allpaths[id(s)] = Pth(pathreq,p,s) + simple_rqs[pathreq.request_id] = temp + temp =[] + for p in all_simp_pths_reversed : + # build a short list representing each roadm+direction with the first item + # start enumeration at 1 to avoid Trx in the list + temp.append([e.uid for i,e in enumerate(p[1:-1]) \ + if (isinstance(e,Roadm) | (isinstance(p[i],Roadm) ))] ) + simple_rqs_reversed[pathreq.request_id] = temp + # step 2 + # for each set of requests that need to be disjoint + # select the disjoint path combination + + candidates = {} + for d in disjunctions_list : + dlist = d.disjunctions_req.copy() + # each line of dpath is one combination of path that satisfies disjunction + dpath = [] + for i,p in enumerate(simple_rqs[dlist[0]]): + dpath.append([p]) + # allpaths[id(p)].d_id = d.disjunction_id + # in each loop, dpath is updated with a path for rq that satisfies + # disjunction with each path in dpath + # for example, assume set of requests in the vector (disjunction_list) is {rq1,rq2, rq3} + # rq1 p1: abfhg + # p2: aefhg + # p3: abcg + # rq2 p8: bf + # rq3 p4: abcgh + # p6: aefh + # p7: abfh + # initiate with rq1 + # dpath = [[p1] + # [p2] + # [p3]] + # after first loop: + # dpath = [[p1 p8] + # [p3 p8]] + # since p2 and p8 are not disjoint + # after second loop: + # dpath = [ p3 p8 p6 ] + # since p1 and p4 are not disjoint + # p1 and p7 are not disjoint + # p3 and p4 are not disjoint + # p3 and p7 are not disjoint + + for e1 in dlist[1:] : + temp = [] + for j,p1 in enumerate(simple_rqs[e1]): + # allpaths[id(p1)].d_id = d.disjunction_id + # can use index j in simple_rqs_reversed because index + # of direct and reversed paths have been kept identical + p1_reversed = simple_rqs_reversed[e1][j] + # print(p1_reversed) + # print('\n\n') + for k,c in enumerate(dpath) : + # print(f' c: \t{c}') + temp2 = c.copy() + all_disjoint = 0 + for p in c : + all_disjoint += isdisjoint(p1,p)+ isdisjoint(p1_reversed,p) + if all_disjoint ==0: + temp2.append(p1) + temp.append(temp2) + # print(f' coucou {e1}: \t{temp}') + dpath = temp + # print(dpath) + candidates[d.disjunction_id] = dpath + + # for i in disjunctions_list : + # print(f'\n{candidates[i.disjunction_id]}') + + # step 3 + # now for each request, select the path that satisfies all disjunctions + # path must be in candidates[id] for all concerned ids + # for example, assume set of sync vectors (disjunction groups) is + # s1 = {rq1 rq2} s2 = {rq1 rq3} + # candidate[s1] = [[p1 p8] + # [p3 p8]] + # candidate[s2] = [[p3 p6]] + # for rq1 p3 should be preferred + + + for pathreq in pathreqlist_disjt: + concerned_d_id = [d.disjunction_id for d in disjunctions_list if pathreq.request_id in d.disjunctions_req] + # for each set of solution, verify that the same path is used for the same request + candidate_paths = simple_rqs[pathreq.request_id] + # print('coucou') + # print(pathreq.request_id) + for p in candidate_paths : + iscandidate = 0 + for sol in concerned_d_id : + test = 1 + # for each solution test if p is part of the solution + # if yes, then p can remain a candidate + for i,m in enumerate(candidates[sol]) : + if p in m: + if allpaths[id(m[m.index(p)])].req.request_id == pathreq.request_id : + test = 0 + break + iscandidate += test + if iscandidate != 0: + for l in concerned_d_id : + for m in candidates[l] : + if p in m : + candidates[l].remove(m) + +# for i in disjunctions_list : +# print(i.disjunction_id) +# print(f'\n{candidates[i.disjunction_id]}') + + # step 4 apply route constraints : remove candidate path that do not satisfy the constraint + # only in the case of disjounction: the simple path is processed in request.compute_constrained_path + # TODO : keep a version without the loose constraint + for d in disjunctions_list : + temp = [] + for j,sol in enumerate(candidates[d.disjunction_id]) : + testispartok = True + for i,p in enumerate(sol) : + # print(f'test {allpaths[id(p)].req.request_id}') + # print(f'length of route {len(allpaths[id(p)].req.nodes_list)}') + if allpaths[id(p)].req.nodes_list : + # if p does not containt the ordered list node, remove sol from the candidate + # except if this was the last solution: then check if the constraint is loose or not + if not ispart(allpaths[id(p)].req.nodes_list, p) : + # print(f'nb of solutions {len(temp)}') + if j < len(candidates[d.disjunction_id])-1 : + msg = f'removing {sol}' + logger.info(msg) + testispartok = False + #break + else: + if 'loose' in allpaths[id(p)].req.loose_list: + logger.info(f'Could not apply route constraint'+ + f'{allpaths[id(p)].req.nodes_list} on request {allpaths[id(p)].req.request_id}') + else : + logger.info(f'removing last solution from candidate paths\n{sol}') + testispartok = False + if testispartok : + temp.append(sol) + candidates[d.disjunction_id] = temp + + # step 5 select the first combination that works + pathreslist_disjoint = {} + for d in disjunctions_list : + test_sol = True + while test_sol: + # print('coucou') + if candidates[d.disjunction_id] : + for p in candidates[d.disjunction_id][0]: + if allpaths[id(p)].req in pathreqlist_disjt: + # print(f'selected path :{p} for req {allpaths[id(p)].req.request_id}') + pathreslist_disjoint[allpaths[id(p)].req] = allpaths[id(p)].pth + pathreqlist_disjt.remove(allpaths[id(p)].req) + candidates = remove_candidate(candidates, allpaths, allpaths[id(p)].req, p) + test_sol = False + else: + msg = f'No disjoint path found with added constraint' + logger.critical(msg) + print(f'{msg}\nComputation stopped.') + # TODO in this case: replay step 5 with the candidate without constraints + exit() + + # for i in disjunctions_list : + # print(i.disjunction_id) + # print(f'\n{candidates[i.disjunction_id]}') + + # list the results in the same order as initial pathreqlist + for req in pathreqlist : + req.nodes_list.append(req.destination) + # we assume that the destination is a strict constraint + req.loose_list.append('strict') + if req in pathreqlist_simple: + path_res_list.append(compute_constrained_path(network, req)) + else: + path_res_list.append(pathreslist_disjoint[req]) + return path_res_list + +def isdisjoint(p1,p2) : + # returns 0 if disjoint + edge1 = list(pairwise(p1)) + edge2 = list(pairwise(p2)) + for e in edge1 : + if e in edge2 : + return 1 + return 0 + +def find_reversed_path(p,network) : + # select of intermediate roadms and find the path between them + # note that this function may not give an exact result in case of multiple + # links between two adjacent nodes. + # TODO add some indication on elements to indicate from which other they + # are the reversed direction + reversed_roadm_path = list(reversed([e for e in p if isinstance (e,Roadm)])) + source = p[-1] + destination = p[0] + total_path = [source] + for node in reversed_roadm_path : + total_path.extend(dijkstra_path(network, source, node)[1:]) + source = node + total_path.append(destination) + return total_path + +def ispart(a,b) : + # the functions takes two paths a and b and retrns True + # if all a elements are part of b and in the same order + j = 0 + for i, el in enumerate(a): + if el in b : + if b.index(el) >= j : + j = b.index(el) + else: + return False + else: + return False + return True + +def remove_candidate(candidates, allpaths, rq, pth) : + # print(f'coucou {rq.request_id}') + for key, candidate in candidates.items() : + temp = candidate.copy() + for i,sol in enumerate(candidate) : + for p in sol : + if allpaths[id(p)].req.request_id == rq.request_id : + if id(p) != id(pth) : + temp.remove(sol) + break + candidates[key] = temp + return candidates + +def compare_reqs(req1,req2,disjlist) : + dis1 = [d for d in disjlist if req1.request_id in d.disjunctions_req] + dis2 = [d for d in disjlist if req2.request_id in d.disjunctions_req] + same_disj = False + if dis1 and dis2 : + temp1 = [] + for d in dis1: + temp1.extend(d.disjunctions_req) + temp1.remove(req1.request_id) + temp2 = [] + for d in dis2: + temp2.extend(d.disjunctions_req) + temp2.remove(req2.request_id) + if set(temp1) == set(temp2) : + same_disj = True + elif not dis2 and not dis1: + same_disj = True + + if req1.source == req2.source and \ + req1.destination == req2.destination and \ + req1.tsp == req2.tsp and \ + req1.tsp_mode == req2.tsp_mode and \ + req1.baud_rate == req2.baud_rate and \ + req1.nodes_list == req2.nodes_list and \ + req1.loose_list == req2.loose_list and \ + req1.spacing == req2.spacing and \ + req1.power == req2.power and \ + req1.nb_channel == req2.nb_channel and \ + req1.f_min == req2.f_min and \ + req1.f_max == req2.f_max and \ + req1.format == req2.format and \ + req1.OSNR == req2.OSNR and \ + req1.roll_off == req2.roll_off and \ + same_disj : + return True + else: + return False + +def requests_aggregation(pathreqlist,disjlist) : + # this function aggregates requests so that if several requests + # exist between same source and destination and with same transponder type + # todo maybe add conditions on mode ??, spacing ... + # currently if undefined takes the default values + local_list = pathreqlist.copy() + for req in pathreqlist: + for r in local_list : + if req.request_id != r.request_id and compare_reqs(req, r, disjlist): + # aggregate + r.path_bandwidth += req.path_bandwidth + temp_r_id = r.request_id + r.request_id = ' | '.join((r.request_id,req.request_id)) + # remove request from list + local_list.remove(req) + # todo change also disjunction req with new demand + + for d in disjlist : + if req.request_id in d.disjunctions_req : + d.disjunctions_req.remove(req.request_id) + d.disjunctions_req.append(r.request_id) + for d in disjlist : + if temp_r_id in d.disjunctions_req : + disjlist.remove(d) + break + return local_list, disjlist diff --git a/gnpy/core/service_sheet.py b/gnpy/core/service_sheet.py index 1145bb01..3759e07e 100644 --- a/gnpy/core/service_sheet.py +++ b/gnpy/core/service_sheet.py @@ -23,7 +23,7 @@ from pathlib import Path from gnpy.core.equipment import load_equipment from gnpy.core.utils import db2lin, lin2db -SERVICES_COLUMN = 11 +SERVICES_COLUMN = 12 #EQPT_LIBRARY_FILENAME = Path(__file__).parent / 'eqpt_config.json' all_rows = lambda sheet, start=0: (sheet.row(x) for x in range(start, sheet.nrows)) @@ -31,9 +31,9 @@ logger = getLogger(__name__) # Type for input data class Request(namedtuple('Request', 'request_id source destination trx_type mode \ - spacing power nb_channel disjoint_from nodes_list is_loose')): - def __new__(cls, request_id, source, destination, trx_type, mode , spacing , power , nb_channel , disjoint_from ='' , nodes_list = None, is_loose = ''): - return super().__new__(cls, request_id, source, destination, trx_type, mode, spacing, power, nb_channel, disjoint_from, nodes_list, is_loose) + spacing power nb_channel disjoint_from nodes_list is_loose path_bandwidth')): + def __new__(cls, request_id, source, destination, trx_type, mode=None , spacing= None , power = None, nb_channel = None , disjoint_from ='' , nodes_list = None, is_loose = '', path_bandwidth = None): + return super().__new__(cls, request_id, source, destination, trx_type, mode, spacing, power, nb_channel, disjoint_from, nodes_list, is_loose, path_bandwidth) # Type for output data: // from dutc class Element: @@ -47,15 +47,11 @@ class Request_element(Element): # request_id is str # excel has automatic number formatting that adds .0 on integer values # the next lines recover the pure int value, assuming this .0 is unwanted - if not isinstance(Request.request_id,str): - value = str(int(Request.request_id)) - if value.endswith('.0'): - value = value[:-2] - self.request_id = value - else: - self.request_id = Request.request_id + self.request_id = correct_xlrd_int_to_str_reading(Request.request_id) self.source = Request.source self.destination = Request.destination + # TODO: the automatic naming generated by excel parser requires that source and dest name + # be a string starting with 'trx' : this is manually added here. self.srctpid = f'trx {Request.source}' self.dsttpid = f'trx {Request.destination}' # test that trx_type belongs to eqpt_config.json @@ -63,55 +59,80 @@ class Request_element(Element): equipment = load_equipment(eqpt_filename) try : if equipment['Transceiver'][Request.trx_type]: - self.trx_type = Request.trx_type - if [mode for mode in equipment['Transceiver'][Request.trx_type].mode]: + self.trx_type = correct_xlrd_int_to_str_reading(Request.trx_type) + if Request.mode is not None : + Requestmode = correct_xlrd_int_to_str_reading(Request.mode) + if [mode for mode in equipment['Transceiver'][Request.trx_type].mode if mode['format'] == Requestmode]: + self.mode = Requestmode + else : + msg = f'Request Id: {self.request_id} - could not find tsp : \'{Request.trx_type}\' with mode: \'{Requestmode}\' in eqpt library \nComputation stopped.' + #print(msg) + logger.critical(msg) + exit(1) + else: + Requestmode = None self.mode = Request.mode except KeyError: - msg = f'could not find tsp : {Request.trx_type} with mode: {Request.mode} in eqpt library \nComputation stopped.' + msg = f'Request Id: {self.request_id} - could not find tsp : \'{Request.trx_type}\' with mode: \'{Requestmode}\' in eqpt library \nComputation stopped.' #print(msg) logger.critical(msg) exit() # excel input are in GHz and dBm - self.spacing = Request.spacing * 1e9 - self.power = db2lin(Request.power) * 1e-3 - self.nb_channel = int(Request.nb_channel) - if not isinstance(Request.disjoint_from,str): - value = str(int(Request.disjoint_from)) - if value.endswith('.0'): - value = value[:-2] + if Request.spacing is not None: + self.spacing = Request.spacing * 1e9 else: - value = Request.disjoint_from - self.disjoint_from = [n for n in value.split()] + msg = f'Request {self.request_id} missing spacing: spacing is mandatory.\ncomputation stopped' + logger.critical(msg) + exit() + if Request.power is not None: + self.power = db2lin(Request.power) * 1e-3 + else: + self.power = None + if Request.nb_channel is not None : + self.nb_channel = int(Request.nb_channel) + else: + self.nb_channel = None + + value = correct_xlrd_int_to_str_reading(Request.disjoint_from) + self.disjoint_from = [n for n in value.split(' | ') if value] self.nodes_list = [] if Request.nodes_list : self.nodes_list = Request.nodes_list.split(' | ') + + # cleaning the list of nodes to remove source and destination + # (because the remaining of the program assumes that the nodes list are nodes + # on the path and should not include source and destination) try : self.nodes_list.remove(self.source) msg = f'{self.source} removed from explicit path node-list' logger.info(msg) - # print(msg) except ValueError: msg = f'{self.source} already removed from explicit path node-list' logger.info(msg) - # print(msg) + try : self.nodes_list.remove(self.destination) msg = f'{self.destination} removed from explicit path node-list' logger.info(msg) - # print(msg) except ValueError: msg = f'{self.destination} already removed from explicit path node-list' logger.info(msg) - # print(msg) + # the excel parser applies the same hop-type to all nodes in the route nodes_list. + # user can change this per node in the generated json self.loose = 'loose' if Request.is_loose == 'no' : self.loose = 'strict' + self.path_bandwidth = None + if Request.path_bandwidth is not None: + self.path_bandwidth = Request.path_bandwidth * 1e9 + else: + self.path_bandwidth = 0 uid = property(lambda self: repr(self)) @property def pathrequest(self): - return { + req_dictionnary = { 'request-id':self.request_id, 'source': self.source, 'destination': self.destination, @@ -126,6 +147,7 @@ class Request_element(Element): 'spacing' : self.spacing, 'max-nb-of-channel' : self.nb_channel, 'output-power' : self.power + # 'path_bandwidth' : self.path_bandwidth } }, 'optimizations': { @@ -135,7 +157,7 @@ class Request_element(Element): 'unnumbered-hop':{ 'node-id': f'{node}', 'link-tp-id': 'link-tp-id is not used', - 'hop-type': 'loose', + 'hop-type': f'{self.loose}', 'direction': 'direction is not used' }, 'label-hop':{ @@ -150,10 +172,14 @@ class Request_element(Element): } } + if self.path_bandwidth is not None: + req_dictionnary['path-constraints']['te-bandwidth']['path_bandwidth'] = self.path_bandwidth + + return req_dictionnary @property def pathsync(self): if self.disjoint_from : - return {'synchonization-id':self.request_id, + return {'synchronization-id':self.request_id, 'svec': { 'relaxable' : 'False', 'link-diverse': 'True', @@ -177,13 +203,22 @@ def convert_service_sheet(input_filename, eqpt_filename, output_filename='', fil # print(json_filename) data = { 'path-request': [n.json[0] for n in req], - 'synchronisation': [n.json[1] for n in req + 'synchronization': [n.json[1] for n in req if n.json[1] is not None] } - with open(output_filename, 'w') as f: - f.write(dumps(data, indent=2)) + with open(output_filename, 'w', encoding='utf-8') as f: + f.write(dumps(data, indent=2, ensure_ascii=False)) return data +def correct_xlrd_int_to_str_reading(v) : + if not isinstance(v,str): + value = str(int(v)) + if value.endswith('.0'): + value = value[:-2] + else: + value = v + return value + # to be used from dutc def parse_row(row, fieldnames): return {f: r.value for f, r in zip(fieldnames, row[0:SERVICES_COLUMN]) @@ -198,19 +233,24 @@ def parse_excel(input_filename): def parse_service_sheet(service_sheet): logger.info(f'Validating headers on {service_sheet.name!r}') - header = [x.value.strip() for x in service_sheet.row(4)[0:SERVICES_COLUMN]] - expected = ['route id', 'Source', 'Destination', 'TRX type', \ - 'Mode', 'System: spacing', 'System: input power (dBm)', 'System: nb of channels',\ - 'routing: disjoint from', 'routing: path', 'routing: is loose?'] - if header != expected: - msg = f'Malformed header on Service sheet: {header} != {expected}' + # add a test on field to enable the '' field case that arises when columns on the + # right hand side are used as comments or drawing in the excel sheet + header = [x.value.strip() for x in service_sheet.row(4)[0:SERVICES_COLUMN] if len(x.value.strip())>0] + + # create a service_fieldname independant from the excel column order + # to be compatible with any version of the sheet + # the following dictionnary records the excel field names and the corresponding parameter's name + + authorized_fieldnames = {'route id':'request_id', 'Source':'source', 'Destination':'destination', \ + 'TRX type':'trx_type', 'Mode' : 'mode', 'System: spacing':'spacing', \ + 'System: input power (dBm)':'power', 'System: nb of channels':'nb_channel',\ + 'routing: disjoint from': 'disjoint_from', 'routing: path':'nodes_list',\ + 'routing: is loose?':'is_loose', 'path bandwidth':'path_bandwidth'} + try : + service_fieldnames = [authorized_fieldnames[e] for e in header] + except KeyError: + msg = f'Malformed header on Service sheet: {header} field not in {authorized_fieldnames}' logger.critical(msg) raise ValueError(msg) - - service_fieldnames = 'request_id source destination trx_type mode spacing power nb_channel disjoint_from nodes_list is_loose'.split() - # Important Note: it reads all colum on each row so that - # it is not possible to write annotation in the excel sheet - # outside the SERVICES_COLUMN ... TO BE IMPROVED - # request_id should be unique for disjunction constraints (not used yet) for row in all_rows(service_sheet, start=5): yield Request(**parse_row(row[0:SERVICES_COLUMN], service_fieldnames)) diff --git a/gnpy/core/utils.py b/gnpy/core/utils.py index 96d1716f..6225e0dc 100644 --- a/gnpy/core/utils.py +++ b/gnpy/core/utils.py @@ -18,14 +18,14 @@ from scipy import constants def load_json(filename): - with open(filename, 'r') as f: + with open(filename, 'r', encoding='utf-8') as f: data = json.load(f) return data def save_json(obj, filename): - with open(filename, 'w') as f: - json.dump(obj, f, indent=2) + with open(filename, 'w', encoding='utf-8') as f: + json.dump(obj, f, indent=2, ensure_ascii=False) def write_csv(obj, filename): """ @@ -55,7 +55,7 @@ def write_csv(obj, filename): result_category 2 ... """ - with open(filename, 'w') as f: + with open(filename, 'w', encoding='utf-8') as f: w = writer(f) for data_key, data_list in obj.items(): #main header @@ -120,6 +120,10 @@ def freq2wavelength(value): """ return c() / value +def snr_sum(snr, bw, snr_added, bw_added=12.5e9): + snr_added = snr_added - lin2db(bw/bw_added) + snr = -lin2db(db2lin(-snr)+db2lin(-snr_added)) + return snr def deltawl2deltaf(delta_wl, wavelength): """ deltawl2deltaf(delta_wl, wavelength): diff --git a/service-template.json b/service-template.json index fd23b58f..8d7a1d77 100644 --- a/service-template.json +++ b/service-template.json @@ -19,7 +19,8 @@ ], "spacing": null, "max-nb-of-channel": null, - "output-power": null + "output-power": null, + "path_bandwidth": null } }, "optimizations": { diff --git a/tests/compare.py b/tests/compare.py index d208969b..d11423c6 100644 --- a/tests/compare.py +++ b/tests/compare.py @@ -77,8 +77,8 @@ def compare_networks(expected, actual): def compare_services(expected, actual): requests = compare(expected['path-request'], actual['path-request'], key=lambda el: el['request-id']) - synchronizations = compare(expected['synchronisation'], actual['synchronisation'], - key=lambda el: el['synchonization-id']) + synchronizations = compare(expected['synchronization'], actual['synchronization'], + key=lambda el: el['synchronization-id']) return ServicesResults(requests, synchronizations) def compare_paths(expected_output, actual_output): @@ -105,16 +105,16 @@ def encode_sets(obj): if __name__ == '__main__': args = parser.parse_args() - with open(args.expected_output) as f: + with open(args.expected_output, encoding='utf-8') as f: expected = load(f) - with open(args.actual_output) as f: + with open(args.actual_output, encoding='utf-8') as f: actual = load(f) result = COMPARISONS[args.comparison](expected, actual) if args.output: - with open(args.output, 'w') as f: - dump(result, f, default=encode_sets, indent=2) + with open(args.output, 'w', encoding='utf-8') as f: + dump(result, f, default=encode_sets, indent=2, ensure_ascii=False) else: print(str(result)) diff --git a/tests/data/CORONET_Global_Topology.xls b/tests/data/CORONET_Global_Topology.xls index 952d008b..6dea7f16 100644 Binary files a/tests/data/CORONET_Global_Topology.xls and b/tests/data/CORONET_Global_Topology.xls differ diff --git a/tests/data/CORONET_Global_Topology_expected.json b/tests/data/CORONET_Global_Topology_expected.json index 4dd8106b..02657f9a 100644 --- a/tests/data/CORONET_Global_Topology_expected.json +++ b/tests/data/CORONET_Global_Topology_expected.json @@ -1,5 +1,29 @@ { "elements": [ + { + "uid": "trx Abilene", + "metadata": { + "location": { + "city": "Abilene", + "region": "CONUS", + "latitude": 32.45, + "longitude": -99.739998 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Albany", + "metadata": { + "location": { + "city": "Albany", + "region": "CONUS", + "latitude": 42.6699982, + "longitude": -73.8000029 + } + }, + "type": "Transceiver" + }, { "uid": "trx Albuquerque", "metadata": { @@ -24,6 +48,18 @@ }, "type": "Transceiver" }, + { + "uid": "trx Austin", + "metadata": { + "location": { + "city": "Austin", + "region": "CONUS", + "latitude": 30.3099988, + "longitude": -97.7500018 + } + }, + "type": "Transceiver" + }, { "uid": "trx Baltimore", "metadata": { @@ -36,6 +72,18 @@ }, "type": "Transceiver" }, + { + "uid": "trx Baton_Rouge", + "metadata": { + "location": { + "city": "Baton_Rouge", + "region": "CONUS", + "latitude": 30.4499996, + "longitude": -91.1299968 + } + }, + "type": "Transceiver" + }, { "uid": "trx Billings", "metadata": { @@ -60,6 +108,66 @@ }, "type": "Transceiver" }, + { + "uid": "trx Bismarck", + "metadata": { + "location": { + "city": "Bismarck", + "region": "CONUS", + "latitude": 46.81000154, + "longitude": -100.7699965 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Boston", + "metadata": { + "location": { + "city": "Boston", + "region": "CONUS", + "latitude": 42.3400005, + "longitude": -71.0199959 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Buffalo", + "metadata": { + "location": { + "city": "Buffalo", + "region": "CONUS", + "latitude": 42.8899993, + "longitude": -78.860001 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Charleston", + "metadata": { + "location": { + "city": "Charleston", + "region": "CONUS", + "latitude": 32.7900008, + "longitude": -79.9899982 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Charlotte", + "metadata": { + "location": { + "city": "Charlotte", + "region": "CONUS", + "latitude": 35.2, + "longitude": -80.83 + } + }, + "type": "Transceiver" + }, { "uid": "trx Chicago", "metadata": { @@ -132,6 +240,18 @@ }, "type": "Transceiver" }, + { + "uid": "trx Detroit", + "metadata": { + "location": { + "city": "Detroit", + "region": "CONUS", + "latitude": 42.3800019, + "longitude": -83.0999998 + } + }, + "type": "Transceiver" + }, { "uid": "trx El_Paso", "metadata": { @@ -168,6 +288,18 @@ }, "type": "Transceiver" }, + { + "uid": "trx Hartford", + "metadata": { + "location": { + "city": "Hartford", + "region": "CONUS", + "latitude": 41.7700004, + "longitude": -72.6800003 + } + }, + "type": "Transceiver" + }, { "uid": "trx Houston", "metadata": { @@ -216,6 +348,30 @@ }, "type": "Transceiver" }, + { + "uid": "trx Little_Rock", + "metadata": { + "location": { + "city": "Little_Rock", + "region": "CONUS", + "latitude": 34.72, + "longitude": -92.35 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Long_Island", + "metadata": { + "location": { + "city": "Long_Island", + "region": "CONUS", + "latitude": 40.5899999, + "longitude": -73.6699993 + } + }, + "type": "Transceiver" + }, { "uid": "trx Los_Angeles", "metadata": { @@ -240,6 +396,18 @@ }, "type": "Transceiver" }, + { + "uid": "trx Memphis", + "metadata": { + "location": { + "city": "Memphis", + "region": "CONUS", + "latitude": 35.110001, + "longitude": -90.010004 + } + }, + "type": "Transceiver" + }, { "uid": "trx Miami", "metadata": { @@ -252,6 +420,18 @@ }, "type": "Transceiver" }, + { + "uid": "trx Milwaukee", + "metadata": { + "location": { + "city": "Milwaukee", + "region": "CONUS", + "latitude": 43.0600013, + "longitude": -87.9700005 + } + }, + "type": "Transceiver" + }, { "uid": "trx Minneapolis", "metadata": { @@ -300,6 +480,30 @@ }, "type": "Transceiver" }, + { + "uid": "trx Newark", + "metadata": { + "location": { + "city": "Newark", + "region": "CONUS", + "latitude": 40.7200012, + "longitude": -74.1699986 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Norfolk", + "metadata": { + "location": { + "city": "Norfolk", + "region": "CONUS", + "latitude": 36.9199982, + "longitude": -76.2399978 + } + }, + "type": "Transceiver" + }, { "uid": "trx Oakland", "metadata": { @@ -312,6 +516,18 @@ }, "type": "Transceiver" }, + { + "uid": "trx Oklahoma_City", + "metadata": { + "location": { + "city": "Oklahoma_City", + "region": "CONUS", + "latitude": 35.4700015, + "longitude": -97.5100028 + } + }, + "type": "Transceiver" + }, { "uid": "trx Omaha", "metadata": { @@ -324,6 +540,18 @@ }, "type": "Transceiver" }, + { + "uid": "trx Orlando", + "metadata": { + "location": { + "city": "Orlando", + "region": "CONUS", + "latitude": 28.4999994, + "longitude": -81.370003 + } + }, + "type": "Transceiver" + }, { "uid": "trx Philadelphia", "metadata": { @@ -372,6 +600,18 @@ }, "type": "Transceiver" }, + { + "uid": "trx Providence", + "metadata": { + "location": { + "city": "Providence", + "region": "CONUS", + "latitude": 41.82, + "longitude": -71.42 + } + }, + "type": "Transceiver" + }, { "uid": "trx Raleigh", "metadata": { @@ -384,6 +624,42 @@ }, "type": "Transceiver" }, + { + "uid": "trx Richmond", + "metadata": { + "location": { + "city": "Richmond", + "region": "CONUS", + "latitude": 37.5299986, + "longitude": -77.4700015 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Rochester", + "metadata": { + "location": { + "city": "Rochester", + "region": "CONUS", + "latitude": 43.1699985, + "longitude": -77.620003 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Sacramento", + "metadata": { + "location": { + "city": "Sacramento", + "region": "CONUS", + "latitude": 38.56999946, + "longitude": -121.4700016 + } + }, + "type": "Transceiver" + }, { "uid": "trx Salt_Lake_City", "metadata": { @@ -396,6 +672,66 @@ }, "type": "Transceiver" }, + { + "uid": "trx San_Antonio", + "metadata": { + "location": { + "city": "San_Antonio", + "region": "CONUS", + "latitude": 29.459997, + "longitude": -98.510002 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx San_Diego", + "metadata": { + "location": { + "city": "San_Diego", + "region": "CONUS", + "latitude": 32.8100017, + "longitude": -117.139999 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx San_Francisco", + "metadata": { + "location": { + "city": "San_Francisco", + "region": "CONUS", + "latitude": 37.65999942, + "longitude": -122.4199987 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx San_Jose", + "metadata": { + "location": { + "city": "San_Jose", + "region": "CONUS", + "latitude": 37.29999947, + "longitude": -121.8499985 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Santa_Barbara", + "metadata": { + "location": { + "city": "Santa_Barbara", + "region": "CONUS", + "latitude": 34.43000021, + "longitude": -119.7200014 + } + }, + "type": "Transceiver" + }, { "uid": "trx Scranton", "metadata": { @@ -408,6 +744,42 @@ }, "type": "Transceiver" }, + { + "uid": "trx Seattle", + "metadata": { + "location": { + "city": "Seattle", + "region": "CONUS", + "latitude": 47.61999916, + "longitude": -122.3499985 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Spokane", + "metadata": { + "location": { + "city": "Spokane", + "region": "CONUS", + "latitude": 47.66999805, + "longitude": -117.4100038 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Springfield", + "metadata": { + "location": { + "city": "Springfield", + "region": "CONUS", + "latitude": 39.5, + "longitude": -89.4 + } + }, + "type": "Transceiver" + }, { "uid": "trx St_Louis", "metadata": { @@ -432,6 +804,66 @@ }, "type": "Transceiver" }, + { + "uid": "trx Tallahassee", + "metadata": { + "location": { + "city": "Tallahassee", + "region": "CONUS", + "latitude": 30.46, + "longitude": -84.28 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Tampa", + "metadata": { + "location": { + "city": "Tampa", + "region": "CONUS", + "latitude": 27.9599988, + "longitude": -82.4800035 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Toledo", + "metadata": { + "location": { + "city": "Toledo", + "region": "CONUS", + "latitude": 41.659997, + "longitude": -83.58 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Tucson", + "metadata": { + "location": { + "city": "Tucson", + "region": "CONUS", + "latitude": 32.2, + "longitude": -110.89 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Tulsa", + "metadata": { + "location": { + "city": "Tulsa", + "region": "CONUS", + "latitude": 36.13, + "longitude": -95.92 + } + }, + "type": "Transceiver" + }, { "uid": "trx Washington_DC", "metadata": { @@ -444,6 +876,30 @@ }, "type": "Transceiver" }, + { + "uid": "trx West_Palm_Beach", + "metadata": { + "location": { + "city": "West_Palm_Beach", + "region": "CONUS", + "latitude": 26.7499997, + "longitude": -80.1299975 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Wilmington", + "metadata": { + "location": { + "city": "Wilmington", + "region": "CONUS", + "latitude": 39.7400018, + "longitude": -75.5299989 + } + }, + "type": "Transceiver" + }, { "uid": "trx Amsterdam", "metadata": { @@ -456,6 +912,54 @@ }, "type": "Transceiver" }, + { + "uid": "trx Berlin", + "metadata": { + "location": { + "city": "Berlin", + "region": "Europe", + "latitude": 52.520002, + "longitude": 13.379995 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Brussels", + "metadata": { + "location": { + "city": "Brussels", + "region": "Europe", + "latitude": 50.830002, + "longitude": 4.330002 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Bucharest", + "metadata": { + "location": { + "city": "Bucharest", + "region": "Europe", + "latitude": 44.44, + "longitude": 26.1 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Frankfurt", + "metadata": { + "location": { + "city": "Frankfurt", + "region": "Europe", + "latitude": 50.1199992, + "longitude": 8.68000104 + } + }, + "type": "Transceiver" + }, { "uid": "trx Istanbul", "metadata": { @@ -480,6 +984,18 @@ }, "type": "Transceiver" }, + { + "uid": "trx Madrid", + "metadata": { + "location": { + "city": "Madrid", + "region": "Europe", + "latitude": 40.419998, + "longitude": -3.7100002 + } + }, + "type": "Transceiver" + }, { "uid": "trx Paris", "metadata": { @@ -528,6 +1044,42 @@ }, "type": "Transceiver" }, + { + "uid": "trx Zurich", + "metadata": { + "location": { + "city": "Zurich", + "region": "Europe", + "latitude": 47.3800015, + "longitude": 8.5399996 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Bangkok", + "metadata": { + "location": { + "city": "Bangkok", + "region": "Asia", + "latitude": 13.73, + "longitude": 100.5 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Beijing", + "metadata": { + "location": { + "city": "Beijing", + "region": "Asia", + "latitude": 39.92999979, + "longitude": 116.4000013 + } + }, + "type": "Transceiver" + }, { "uid": "trx Delhi", "metadata": { @@ -576,6 +1128,42 @@ }, "type": "Transceiver" }, + { + "uid": "trx Seoul", + "metadata": { + "location": { + "city": "Seoul", + "region": "Asia", + "latitude": 37.56000108, + "longitude": 126.9899988 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Shanghai", + "metadata": { + "location": { + "city": "Shanghai", + "region": "Asia", + "latitude": 31.23, + "longitude": 121.47 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx Singapore", + "metadata": { + "location": { + "city": "Singapore", + "region": "Asia", + "latitude": 1.299999907, + "longitude": 103.8499992 + } + }, + "type": "Transceiver" + }, { "uid": "trx Sydney", "metadata": { @@ -612,6 +1200,30 @@ }, "type": "Transceiver" }, + { + "uid": "roadm Abilene", + "metadata": { + "location": { + "city": "Abilene", + "region": "CONUS", + "latitude": 32.45, + "longitude": -99.739998 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Albany", + "metadata": { + "location": { + "city": "Albany", + "region": "CONUS", + "latitude": 42.6699982, + "longitude": -73.8000029 + } + }, + "type": "Roadm" + }, { "uid": "roadm Albuquerque", "metadata": { @@ -636,6 +1248,18 @@ }, "type": "Roadm" }, + { + "uid": "roadm Austin", + "metadata": { + "location": { + "city": "Austin", + "region": "CONUS", + "latitude": 30.3099988, + "longitude": -97.7500018 + } + }, + "type": "Roadm" + }, { "uid": "roadm Baltimore", "metadata": { @@ -648,6 +1272,18 @@ }, "type": "Roadm" }, + { + "uid": "roadm Baton_Rouge", + "metadata": { + "location": { + "city": "Baton_Rouge", + "region": "CONUS", + "latitude": 30.4499996, + "longitude": -91.1299968 + } + }, + "type": "Roadm" + }, { "uid": "roadm Billings", "metadata": { @@ -672,6 +1308,66 @@ }, "type": "Roadm" }, + { + "uid": "roadm Bismarck", + "metadata": { + "location": { + "city": "Bismarck", + "region": "CONUS", + "latitude": 46.81000154, + "longitude": -100.7699965 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Boston", + "metadata": { + "location": { + "city": "Boston", + "region": "CONUS", + "latitude": 42.3400005, + "longitude": -71.0199959 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Buffalo", + "metadata": { + "location": { + "city": "Buffalo", + "region": "CONUS", + "latitude": 42.8899993, + "longitude": -78.860001 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Charleston", + "metadata": { + "location": { + "city": "Charleston", + "region": "CONUS", + "latitude": 32.7900008, + "longitude": -79.9899982 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Charlotte", + "metadata": { + "location": { + "city": "Charlotte", + "region": "CONUS", + "latitude": 35.2, + "longitude": -80.83 + } + }, + "type": "Roadm" + }, { "uid": "roadm Chicago", "metadata": { @@ -744,6 +1440,18 @@ }, "type": "Roadm" }, + { + "uid": "roadm Detroit", + "metadata": { + "location": { + "city": "Detroit", + "region": "CONUS", + "latitude": 42.3800019, + "longitude": -83.0999998 + } + }, + "type": "Roadm" + }, { "uid": "roadm El_Paso", "metadata": { @@ -780,6 +1488,18 @@ }, "type": "Roadm" }, + { + "uid": "roadm Hartford", + "metadata": { + "location": { + "city": "Hartford", + "region": "CONUS", + "latitude": 41.7700004, + "longitude": -72.6800003 + } + }, + "type": "Roadm" + }, { "uid": "roadm Houston", "metadata": { @@ -828,6 +1548,30 @@ }, "type": "Roadm" }, + { + "uid": "roadm Little_Rock", + "metadata": { + "location": { + "city": "Little_Rock", + "region": "CONUS", + "latitude": 34.72, + "longitude": -92.35 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Long_Island", + "metadata": { + "location": { + "city": "Long_Island", + "region": "CONUS", + "latitude": 40.5899999, + "longitude": -73.6699993 + } + }, + "type": "Roadm" + }, { "uid": "roadm Los_Angeles", "metadata": { @@ -852,6 +1596,18 @@ }, "type": "Roadm" }, + { + "uid": "roadm Memphis", + "metadata": { + "location": { + "city": "Memphis", + "region": "CONUS", + "latitude": 35.110001, + "longitude": -90.010004 + } + }, + "type": "Roadm" + }, { "uid": "roadm Miami", "metadata": { @@ -864,6 +1620,18 @@ }, "type": "Roadm" }, + { + "uid": "roadm Milwaukee", + "metadata": { + "location": { + "city": "Milwaukee", + "region": "CONUS", + "latitude": 43.0600013, + "longitude": -87.9700005 + } + }, + "type": "Roadm" + }, { "uid": "roadm Minneapolis", "metadata": { @@ -912,6 +1680,30 @@ }, "type": "Roadm" }, + { + "uid": "roadm Newark", + "metadata": { + "location": { + "city": "Newark", + "region": "CONUS", + "latitude": 40.7200012, + "longitude": -74.1699986 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Norfolk", + "metadata": { + "location": { + "city": "Norfolk", + "region": "CONUS", + "latitude": 36.9199982, + "longitude": -76.2399978 + } + }, + "type": "Roadm" + }, { "uid": "roadm Oakland", "metadata": { @@ -924,6 +1716,18 @@ }, "type": "Roadm" }, + { + "uid": "roadm Oklahoma_City", + "metadata": { + "location": { + "city": "Oklahoma_City", + "region": "CONUS", + "latitude": 35.4700015, + "longitude": -97.5100028 + } + }, + "type": "Roadm" + }, { "uid": "roadm Omaha", "metadata": { @@ -936,6 +1740,18 @@ }, "type": "Roadm" }, + { + "uid": "roadm Orlando", + "metadata": { + "location": { + "city": "Orlando", + "region": "CONUS", + "latitude": 28.4999994, + "longitude": -81.370003 + } + }, + "type": "Roadm" + }, { "uid": "roadm Philadelphia", "metadata": { @@ -984,6 +1800,18 @@ }, "type": "Roadm" }, + { + "uid": "roadm Providence", + "metadata": { + "location": { + "city": "Providence", + "region": "CONUS", + "latitude": 41.82, + "longitude": -71.42 + } + }, + "type": "Roadm" + }, { "uid": "roadm Raleigh", "metadata": { @@ -996,6 +1824,42 @@ }, "type": "Roadm" }, + { + "uid": "roadm Richmond", + "metadata": { + "location": { + "city": "Richmond", + "region": "CONUS", + "latitude": 37.5299986, + "longitude": -77.4700015 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Rochester", + "metadata": { + "location": { + "city": "Rochester", + "region": "CONUS", + "latitude": 43.1699985, + "longitude": -77.620003 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Sacramento", + "metadata": { + "location": { + "city": "Sacramento", + "region": "CONUS", + "latitude": 38.56999946, + "longitude": -121.4700016 + } + }, + "type": "Roadm" + }, { "uid": "roadm Salt_Lake_City", "metadata": { @@ -1008,6 +1872,66 @@ }, "type": "Roadm" }, + { + "uid": "roadm San_Antonio", + "metadata": { + "location": { + "city": "San_Antonio", + "region": "CONUS", + "latitude": 29.459997, + "longitude": -98.510002 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm San_Diego", + "metadata": { + "location": { + "city": "San_Diego", + "region": "CONUS", + "latitude": 32.8100017, + "longitude": -117.139999 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm San_Francisco", + "metadata": { + "location": { + "city": "San_Francisco", + "region": "CONUS", + "latitude": 37.65999942, + "longitude": -122.4199987 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm San_Jose", + "metadata": { + "location": { + "city": "San_Jose", + "region": "CONUS", + "latitude": 37.29999947, + "longitude": -121.8499985 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Santa_Barbara", + "metadata": { + "location": { + "city": "Santa_Barbara", + "region": "CONUS", + "latitude": 34.43000021, + "longitude": -119.7200014 + } + }, + "type": "Roadm" + }, { "uid": "roadm Scranton", "metadata": { @@ -1020,6 +1944,42 @@ }, "type": "Roadm" }, + { + "uid": "roadm Seattle", + "metadata": { + "location": { + "city": "Seattle", + "region": "CONUS", + "latitude": 47.61999916, + "longitude": -122.3499985 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Spokane", + "metadata": { + "location": { + "city": "Spokane", + "region": "CONUS", + "latitude": 47.66999805, + "longitude": -117.4100038 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Springfield", + "metadata": { + "location": { + "city": "Springfield", + "region": "CONUS", + "latitude": 39.5, + "longitude": -89.4 + } + }, + "type": "Roadm" + }, { "uid": "roadm St_Louis", "metadata": { @@ -1044,6 +2004,66 @@ }, "type": "Roadm" }, + { + "uid": "roadm Tallahassee", + "metadata": { + "location": { + "city": "Tallahassee", + "region": "CONUS", + "latitude": 30.46, + "longitude": -84.28 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Tampa", + "metadata": { + "location": { + "city": "Tampa", + "region": "CONUS", + "latitude": 27.9599988, + "longitude": -82.4800035 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Toledo", + "metadata": { + "location": { + "city": "Toledo", + "region": "CONUS", + "latitude": 41.659997, + "longitude": -83.58 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Tucson", + "metadata": { + "location": { + "city": "Tucson", + "region": "CONUS", + "latitude": 32.2, + "longitude": -110.89 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Tulsa", + "metadata": { + "location": { + "city": "Tulsa", + "region": "CONUS", + "latitude": 36.13, + "longitude": -95.92 + } + }, + "type": "Roadm" + }, { "uid": "roadm Washington_DC", "metadata": { @@ -1056,6 +2076,30 @@ }, "type": "Roadm" }, + { + "uid": "roadm West_Palm_Beach", + "metadata": { + "location": { + "city": "West_Palm_Beach", + "region": "CONUS", + "latitude": 26.7499997, + "longitude": -80.1299975 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Wilmington", + "metadata": { + "location": { + "city": "Wilmington", + "region": "CONUS", + "latitude": 39.7400018, + "longitude": -75.5299989 + } + }, + "type": "Roadm" + }, { "uid": "roadm Amsterdam", "metadata": { @@ -1068,6 +2112,54 @@ }, "type": "Roadm" }, + { + "uid": "roadm Berlin", + "metadata": { + "location": { + "city": "Berlin", + "region": "Europe", + "latitude": 52.520002, + "longitude": 13.379995 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Brussels", + "metadata": { + "location": { + "city": "Brussels", + "region": "Europe", + "latitude": 50.830002, + "longitude": 4.330002 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Bucharest", + "metadata": { + "location": { + "city": "Bucharest", + "region": "Europe", + "latitude": 44.44, + "longitude": 26.1 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Frankfurt", + "metadata": { + "location": { + "city": "Frankfurt", + "region": "Europe", + "latitude": 50.1199992, + "longitude": 8.68000104 + } + }, + "type": "Roadm" + }, { "uid": "roadm Istanbul", "metadata": { @@ -1092,6 +2184,18 @@ }, "type": "Roadm" }, + { + "uid": "roadm Madrid", + "metadata": { + "location": { + "city": "Madrid", + "region": "Europe", + "latitude": 40.419998, + "longitude": -3.7100002 + } + }, + "type": "Roadm" + }, { "uid": "roadm Paris", "metadata": { @@ -1140,6 +2244,42 @@ }, "type": "Roadm" }, + { + "uid": "roadm Zurich", + "metadata": { + "location": { + "city": "Zurich", + "region": "Europe", + "latitude": 47.3800015, + "longitude": 8.5399996 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Bangkok", + "metadata": { + "location": { + "city": "Bangkok", + "region": "Asia", + "latitude": 13.73, + "longitude": 100.5 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Beijing", + "metadata": { + "location": { + "city": "Beijing", + "region": "Asia", + "latitude": 39.92999979, + "longitude": 116.4000013 + } + }, + "type": "Roadm" + }, { "uid": "roadm Delhi", "metadata": { @@ -1188,6 +2328,42 @@ }, "type": "Roadm" }, + { + "uid": "roadm Seoul", + "metadata": { + "location": { + "city": "Seoul", + "region": "Asia", + "latitude": 37.56000108, + "longitude": 126.9899988 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Shanghai", + "metadata": { + "location": { + "city": "Shanghai", + "region": "Asia", + "latitude": 31.23, + "longitude": 121.47 + } + }, + "type": "Roadm" + }, + { + "uid": "roadm Singapore", + "metadata": { + "location": { + "city": "Singapore", + "region": "Asia", + "latitude": 1.299999907, + "longitude": 103.8499992 + } + }, + "type": "Roadm" + }, { "uid": "roadm Sydney", "metadata": { @@ -1225,7 +2401,7 @@ "type": "Roadm" }, { - "uid": "fiber (Abilene \u2192 Dallas)-", + "uid": "fiber (Abilene → Dallas)-", "metadata": { "location": { "latitude": 32.620000000000005, @@ -1243,7 +2419,7 @@ } }, { - "uid": "fiber (Abilene \u2192 El_Paso)-", + "uid": "fiber (Abilene → El_Paso)-", "metadata": { "location": { "latitude": 32.149905000000004, @@ -1261,7 +2437,7 @@ } }, { - "uid": "fiber (Albany \u2192 Boston)-", + "uid": "fiber (Albany → Boston)-", "metadata": { "location": { "latitude": 42.504999350000006, @@ -1279,7 +2455,7 @@ } }, { - "uid": "fiber (Albany \u2192 Syracuse)-", + "uid": "fiber (Albany → Syracuse)-", "metadata": { "location": { "latitude": 42.8549996, @@ -1297,7 +2473,7 @@ } }, { - "uid": "fiber (Albuquerque \u2192 Dallas)-", + "uid": "fiber (Albuquerque → Dallas)-", "metadata": { "location": { "latitude": 33.9549885, @@ -1315,7 +2491,7 @@ } }, { - "uid": "fiber (Albuquerque \u2192 Denver)-", + "uid": "fiber (Albuquerque → Denver)-", "metadata": { "location": { "latitude": 37.444989855, @@ -1333,7 +2509,7 @@ } }, { - "uid": "fiber (Albuquerque \u2192 El_Paso)-", + "uid": "fiber (Albuquerque → El_Paso)-", "metadata": { "location": { "latitude": 33.4848935, @@ -1351,7 +2527,7 @@ } }, { - "uid": "fiber (Albuquerque \u2192 Las_Vegas)-", + "uid": "fiber (Albuquerque → Las_Vegas)-", "metadata": { "location": { "latitude": 35.6649835, @@ -1369,7 +2545,7 @@ } }, { - "uid": "fiber (Amsterdam \u2192 Berlin)-", + "uid": "fiber (Amsterdam → Berlin)-", "metadata": { "location": { "latitude": 52.4450008, @@ -1387,7 +2563,7 @@ } }, { - "uid": "fiber (Amsterdam \u2192 Brussels)-", + "uid": "fiber (Amsterdam → Brussels)-", "metadata": { "location": { "latitude": 51.600000800000004, @@ -1405,7 +2581,7 @@ } }, { - "uid": "fiber (Amsterdam \u2192 Frankfurt)-", + "uid": "fiber (Amsterdam → Frankfurt)-", "metadata": { "location": { "latitude": 51.2449994, @@ -1423,7 +2599,7 @@ } }, { - "uid": "fiber (Amsterdam \u2192 New_York)-", + "uid": "fiber (Amsterdam → New_York)-", "metadata": { "location": { "latitude": 46.51999895, @@ -1441,7 +2617,7 @@ } }, { - "uid": "fiber (Atlanta \u2192 Birmingham)-", + "uid": "fiber (Atlanta → Birmingham)-", "metadata": { "location": { "latitude": 33.644998349999995, @@ -1459,7 +2635,7 @@ } }, { - "uid": "fiber (Atlanta \u2192 Charlotte)-", + "uid": "fiber (Atlanta → Charlotte)-", "metadata": { "location": { "latitude": 34.4799991, @@ -1477,7 +2653,7 @@ } }, { - "uid": "fiber (Atlanta \u2192 Jacksonville)-", + "uid": "fiber (Atlanta → Jacksonville)-", "metadata": { "location": { "latitude": 32.0450006, @@ -1495,7 +2671,7 @@ } }, { - "uid": "fiber (Austin \u2192 Houston)-", + "uid": "fiber (Austin → Houston)-", "metadata": { "location": { "latitude": 30.0399994, @@ -1513,7 +2689,7 @@ } }, { - "uid": "fiber (Austin \u2192 San_Antonio)-", + "uid": "fiber (Austin → San_Antonio)-", "metadata": { "location": { "latitude": 29.884997900000002, @@ -1531,7 +2707,7 @@ } }, { - "uid": "fiber (Baltimore \u2192 Philadelphia)-", + "uid": "fiber (Baltimore → Philadelphia)-", "metadata": { "location": { "latitude": 39.65499885, @@ -1549,7 +2725,7 @@ } }, { - "uid": "fiber (Baltimore \u2192 Pittsburgh)-", + "uid": "fiber (Baltimore → Pittsburgh)-", "metadata": { "location": { "latitude": 39.7999996, @@ -1567,7 +2743,7 @@ } }, { - "uid": "fiber (Baltimore \u2192 Washington_DC)-", + "uid": "fiber (Baltimore → Washington_DC)-", "metadata": { "location": { "latitude": 39.104999750000005, @@ -1585,7 +2761,7 @@ } }, { - "uid": "fiber (Bangkok \u2192 Delhi)-", + "uid": "fiber (Bangkok → Delhi)-", "metadata": { "location": { "latitude": 21.20000015, @@ -1603,7 +2779,7 @@ } }, { - "uid": "fiber (Bangkok \u2192 Hong_Kong)-", + "uid": "fiber (Bangkok → Hong_Kong)-", "metadata": { "location": { "latitude": 17.9985, @@ -1621,7 +2797,7 @@ } }, { - "uid": "fiber (Baton_Rouge \u2192 Houston)-", + "uid": "fiber (Baton_Rouge → Houston)-", "metadata": { "location": { "latitude": 30.1099998, @@ -1639,7 +2815,7 @@ } }, { - "uid": "fiber (Baton_Rouge \u2192 New_Orleans)-", + "uid": "fiber (Baton_Rouge → New_Orleans)-", "metadata": { "location": { "latitude": 30.259999800000003, @@ -1657,7 +2833,7 @@ } }, { - "uid": "fiber (Beijing \u2192 Seoul)-", + "uid": "fiber (Beijing → Seoul)-", "metadata": { "location": { "latitude": 38.745000434999994, @@ -1675,7 +2851,7 @@ } }, { - "uid": "fiber (Beijing \u2192 Shanghai)-", + "uid": "fiber (Beijing → Shanghai)-", "metadata": { "location": { "latitude": 35.579999895, @@ -1693,7 +2869,7 @@ } }, { - "uid": "fiber (Berlin \u2192 Warsaw)-", + "uid": "fiber (Berlin → Warsaw)-", "metadata": { "location": { "latitude": 52.390000349999994, @@ -1711,7 +2887,7 @@ } }, { - "uid": "fiber (Billings \u2192 Bismarck)-", + "uid": "fiber (Billings → Bismarck)-", "metadata": { "location": { "latitude": 46.30000129, @@ -1729,7 +2905,7 @@ } }, { - "uid": "fiber (Billings \u2192 Denver)-", + "uid": "fiber (Billings → Denver)-", "metadata": { "location": { "latitude": 42.780001874999996, @@ -1747,7 +2923,7 @@ } }, { - "uid": "fiber (Billings \u2192 Spokane)-", + "uid": "fiber (Billings → Spokane)-", "metadata": { "location": { "latitude": 46.729999545, @@ -1765,7 +2941,7 @@ } }, { - "uid": "fiber (Birmingham \u2192 Nashville)-", + "uid": "fiber (Birmingham → Nashville)-", "metadata": { "location": { "latitude": 34.84999845, @@ -1783,7 +2959,7 @@ } }, { - "uid": "fiber (Birmingham \u2192 New_Orleans)-", + "uid": "fiber (Birmingham → New_Orleans)-", "metadata": { "location": { "latitude": 31.79999925, @@ -1801,7 +2977,7 @@ } }, { - "uid": "fiber (Bismarck \u2192 Minneapolis)-", + "uid": "fiber (Bismarck → Minneapolis)-", "metadata": { "location": { "latitude": 45.88500017, @@ -1819,7 +2995,7 @@ } }, { - "uid": "fiber (Boston \u2192 Providence)-", + "uid": "fiber (Boston → Providence)-", "metadata": { "location": { "latitude": 42.08000025, @@ -1837,7 +3013,7 @@ } }, { - "uid": "fiber (Brussels \u2192 London)-", + "uid": "fiber (Brussels → London)-", "metadata": { "location": { "latitude": 51.17500125, @@ -1855,7 +3031,7 @@ } }, { - "uid": "fiber (Bucharest \u2192 Istanbul)-", + "uid": "fiber (Bucharest → Istanbul)-", "metadata": { "location": { "latitude": 42.769999999999996, @@ -1873,7 +3049,7 @@ } }, { - "uid": "fiber (Bucharest \u2192 Warsaw)-", + "uid": "fiber (Bucharest → Warsaw)-", "metadata": { "location": { "latitude": 48.34999935, @@ -1891,7 +3067,7 @@ } }, { - "uid": "fiber (Buffalo \u2192 Cleveland)-", + "uid": "fiber (Buffalo → Cleveland)-", "metadata": { "location": { "latitude": 42.184999250000004, @@ -1909,7 +3085,7 @@ } }, { - "uid": "fiber (Buffalo \u2192 Rochester)-", + "uid": "fiber (Buffalo → Rochester)-", "metadata": { "location": { "latitude": 43.029998899999995, @@ -1927,7 +3103,7 @@ } }, { - "uid": "fiber (Charleston \u2192 Jacksonville)-", + "uid": "fiber (Charleston → Jacksonville)-", "metadata": { "location": { "latitude": 31.560001900000003, @@ -1945,7 +3121,7 @@ } }, { - "uid": "fiber (Charleston \u2192 Raleigh)-", + "uid": "fiber (Charleston → Raleigh)-", "metadata": { "location": { "latitude": 34.30500015, @@ -1963,7 +3139,7 @@ } }, { - "uid": "fiber (Charlotte \u2192 Greensboro)-", + "uid": "fiber (Charlotte → Greensboro)-", "metadata": { "location": { "latitude": 35.6400012, @@ -1981,7 +3157,7 @@ } }, { - "uid": "fiber (Chicago \u2192 Detroit)-", + "uid": "fiber (Chicago → Detroit)-", "metadata": { "location": { "latitude": 42.109999450000004, @@ -1999,7 +3175,7 @@ } }, { - "uid": "fiber (Chicago \u2192 Milwaukee)-", + "uid": "fiber (Chicago → Milwaukee)-", "metadata": { "location": { "latitude": 42.44999915, @@ -2017,7 +3193,7 @@ } }, { - "uid": "fiber (Chicago \u2192 Springfield)-", + "uid": "fiber (Chicago → Springfield)-", "metadata": { "location": { "latitude": 40.6699985, @@ -2035,7 +3211,7 @@ } }, { - "uid": "fiber (Cincinnati \u2192 Columbus)-", + "uid": "fiber (Cincinnati → Columbus)-", "metadata": { "location": { "latitude": 39.56500054999999, @@ -2053,7 +3229,7 @@ } }, { - "uid": "fiber (Cincinnati \u2192 Louisville)-", + "uid": "fiber (Cincinnati → Louisville)-", "metadata": { "location": { "latitude": 38.68, @@ -2071,7 +3247,7 @@ } }, { - "uid": "fiber (Cincinnati \u2192 Washington_DC)-", + "uid": "fiber (Cincinnati → Washington_DC)-", "metadata": { "location": { "latitude": 39.024999699999995, @@ -2089,7 +3265,7 @@ } }, { - "uid": "fiber (Cleveland \u2192 Columbus)-", + "uid": "fiber (Cleveland → Columbus)-", "metadata": { "location": { "latitude": 40.7350006, @@ -2107,7 +3283,7 @@ } }, { - "uid": "fiber (Cleveland \u2192 Toledo)-", + "uid": "fiber (Cleveland → Toledo)-", "metadata": { "location": { "latitude": 41.5699981, @@ -2125,7 +3301,7 @@ } }, { - "uid": "fiber (Columbus \u2192 Pittsburgh)-", + "uid": "fiber (Columbus → Pittsburgh)-", "metadata": { "location": { "latitude": 40.14500099999999, @@ -2143,7 +3319,7 @@ } }, { - "uid": "fiber (Dallas \u2192 Houston)-", + "uid": "fiber (Dallas → Houston)-", "metadata": { "location": { "latitude": 31.28, @@ -2161,7 +3337,7 @@ } }, { - "uid": "fiber (Dallas \u2192 Little_Rock)-", + "uid": "fiber (Dallas → Little_Rock)-", "metadata": { "location": { "latitude": 33.754999999999995, @@ -2179,7 +3355,7 @@ } }, { - "uid": "fiber (Dallas \u2192 Oklahoma_City)-", + "uid": "fiber (Dallas → Oklahoma_City)-", "metadata": { "location": { "latitude": 34.13000075, @@ -2197,7 +3373,7 @@ } }, { - "uid": "fiber (Delhi \u2192 Istanbul)-", + "uid": "fiber (Delhi → Istanbul)-", "metadata": { "location": { "latitude": 34.88500015, @@ -2215,7 +3391,7 @@ } }, { - "uid": "fiber (Delhi \u2192 Mumbai)-", + "uid": "fiber (Delhi → Mumbai)-", "metadata": { "location": { "latitude": 23.8149995, @@ -2233,7 +3409,7 @@ } }, { - "uid": "fiber (Denver \u2192 Omaha)-", + "uid": "fiber (Denver → Omaha)-", "metadata": { "location": { "latitude": 40.515000555, @@ -2251,7 +3427,7 @@ } }, { - "uid": "fiber (Denver \u2192 Salt_Lake_City)-", + "uid": "fiber (Denver → Salt_Lake_City)-", "metadata": { "location": { "latitude": 40.27500067, @@ -2269,7 +3445,7 @@ } }, { - "uid": "fiber (Detroit \u2192 Toledo)-", + "uid": "fiber (Detroit → Toledo)-", "metadata": { "location": { "latitude": 42.01999945, @@ -2287,7 +3463,7 @@ } }, { - "uid": "fiber (El_Paso \u2192 San_Antonio)-", + "uid": "fiber (El_Paso → San_Antonio)-", "metadata": { "location": { "latitude": 30.654903500000003, @@ -2305,7 +3481,7 @@ } }, { - "uid": "fiber (El_Paso \u2192 Tucson)-", + "uid": "fiber (El_Paso → Tucson)-", "metadata": { "location": { "latitude": 32.024905000000004, @@ -2323,7 +3499,7 @@ } }, { - "uid": "fiber (Frankfurt \u2192 Vienna)-", + "uid": "fiber (Frankfurt → Vienna)-", "metadata": { "location": { "latitude": 49.1700008, @@ -2341,7 +3517,7 @@ } }, { - "uid": "fiber (Fresno \u2192 Las_Vegas)-", + "uid": "fiber (Fresno → Las_Vegas)-", "metadata": { "location": { "latitude": 36.494995349999996, @@ -2359,7 +3535,7 @@ } }, { - "uid": "fiber (Fresno \u2192 Los_Angeles)-", + "uid": "fiber (Fresno → Los_Angeles)-", "metadata": { "location": { "latitude": 35.44500085, @@ -2377,7 +3553,7 @@ } }, { - "uid": "fiber (Fresno \u2192 Oakland)-", + "uid": "fiber (Fresno → Oakland)-", "metadata": { "location": { "latitude": 37.275000705, @@ -2395,7 +3571,7 @@ } }, { - "uid": "fiber (Greensboro \u2192 Louisville)-", + "uid": "fiber (Greensboro → Louisville)-", "metadata": { "location": { "latitude": 37.15000165, @@ -2413,7 +3589,7 @@ } }, { - "uid": "fiber (Greensboro \u2192 Raleigh)-", + "uid": "fiber (Greensboro → Raleigh)-", "metadata": { "location": { "latitude": 35.95000095, @@ -2431,7 +3607,7 @@ } }, { - "uid": "fiber (Greensboro \u2192 Richmond)-", + "uid": "fiber (Greensboro → Richmond)-", "metadata": { "location": { "latitude": 36.8050005, @@ -2449,7 +3625,7 @@ } }, { - "uid": "fiber (Hartford \u2192 Long_Island)-", + "uid": "fiber (Hartford → Long_Island)-", "metadata": { "location": { "latitude": 41.18000015, @@ -2467,7 +3643,7 @@ } }, { - "uid": "fiber (Hartford \u2192 Providence)-", + "uid": "fiber (Hartford → Providence)-", "metadata": { "location": { "latitude": 41.795000200000004, @@ -2485,7 +3661,7 @@ } }, { - "uid": "fiber (Hong_Kong \u2192 Shanghai)-", + "uid": "fiber (Hong_Kong → Shanghai)-", "metadata": { "location": { "latitude": 26.7485, @@ -2503,7 +3679,7 @@ } }, { - "uid": "fiber (Hong_Kong \u2192 Sydney)-", + "uid": "fiber (Hong_Kong → Sydney)-", "metadata": { "location": { "latitude": -5.801499479999999, @@ -2521,7 +3697,7 @@ } }, { - "uid": "fiber (Hong_Kong \u2192 Taipei)-", + "uid": "fiber (Hong_Kong → Taipei)-", "metadata": { "location": { "latitude": 23.64350025, @@ -2539,7 +3715,7 @@ } }, { - "uid": "fiber (Honolulu \u2192 Los_Angeles)-", + "uid": "fiber (Honolulu → Los_Angeles)-", "metadata": { "location": { "latitude": 27.7150003, @@ -2557,7 +3733,7 @@ } }, { - "uid": "fiber (Honolulu \u2192 Sydney)-", + "uid": "fiber (Honolulu → Sydney)-", "metadata": { "location": { "latitude": -6.274999679999999, @@ -2575,7 +3751,7 @@ } }, { - "uid": "fiber (Honolulu \u2192 Taipei)-", + "uid": "fiber (Honolulu → Taipei)-", "metadata": { "location": { "latitude": 23.17000005, @@ -2593,7 +3769,7 @@ } }, { - "uid": "fiber (Istanbul \u2192 Rome)-", + "uid": "fiber (Istanbul → Rome)-", "metadata": { "location": { "latitude": 41.4949998, @@ -2611,7 +3787,7 @@ } }, { - "uid": "fiber (Jacksonville \u2192 Orlando)-", + "uid": "fiber (Jacksonville → Orlando)-", "metadata": { "location": { "latitude": 29.4150012, @@ -2629,7 +3805,7 @@ } }, { - "uid": "fiber (Kansas_City \u2192 Omaha)-", + "uid": "fiber (Kansas_City → Omaha)-", "metadata": { "location": { "latitude": 40.1899988, @@ -2647,7 +3823,7 @@ } }, { - "uid": "fiber (Kansas_City \u2192 St_Louis)-", + "uid": "fiber (Kansas_City → St_Louis)-", "metadata": { "location": { "latitude": 38.879999600000005, @@ -2665,7 +3841,7 @@ } }, { - "uid": "fiber (Kansas_City \u2192 Tulsa)-", + "uid": "fiber (Kansas_City → Tulsa)-", "metadata": { "location": { "latitude": 37.6249996, @@ -2683,7 +3859,7 @@ } }, { - "uid": "fiber (Las_Vegas \u2192 Phoenix)-", + "uid": "fiber (Las_Vegas → Phoenix)-", "metadata": { "location": { "latitude": 34.87499529, @@ -2701,7 +3877,7 @@ } }, { - "uid": "fiber (Las_Vegas \u2192 Salt_Lake_City)-", + "uid": "fiber (Las_Vegas → Salt_Lake_City)-", "metadata": { "location": { "latitude": 38.494994315, @@ -2719,7 +3895,7 @@ } }, { - "uid": "fiber (Little_Rock \u2192 Memphis)-", + "uid": "fiber (Little_Rock → Memphis)-", "metadata": { "location": { "latitude": 34.9150005, @@ -2737,7 +3913,7 @@ } }, { - "uid": "fiber (London \u2192 Paris)-", + "uid": "fiber (London → Paris)-", "metadata": { "location": { "latitude": 50.19000025, @@ -2755,7 +3931,7 @@ } }, { - "uid": "fiber (London \u2192 Washington_DC)-", + "uid": "fiber (London → Washington_DC)-", "metadata": { "location": { "latitude": 45.2150004, @@ -2773,7 +3949,7 @@ } }, { - "uid": "fiber (Long_Island \u2192 New_York)-", + "uid": "fiber (Long_Island → New_York)-", "metadata": { "location": { "latitude": 40.629999100000006, @@ -2791,7 +3967,7 @@ } }, { - "uid": "fiber (Los_Angeles \u2192 San_Diego)-", + "uid": "fiber (Los_Angeles → San_Diego)-", "metadata": { "location": { "latitude": 33.46000135, @@ -2809,7 +3985,7 @@ } }, { - "uid": "fiber (Los_Angeles \u2192 Santa_Barbara)-", + "uid": "fiber (Los_Angeles → Santa_Barbara)-", "metadata": { "location": { "latitude": 34.270000605, @@ -2827,7 +4003,7 @@ } }, { - "uid": "fiber (Louisville \u2192 Nashville)-", + "uid": "fiber (Louisville → Nashville)-", "metadata": { "location": { "latitude": 37.19499965, @@ -2845,7 +4021,7 @@ } }, { - "uid": "fiber (Louisville \u2192 St_Louis)-", + "uid": "fiber (Louisville → St_Louis)-", "metadata": { "location": { "latitude": 38.43000045, @@ -2863,7 +4039,7 @@ } }, { - "uid": "fiber (Madrid \u2192 Paris)-", + "uid": "fiber (Madrid → Paris)-", "metadata": { "location": { "latitude": 44.639999, @@ -2881,7 +4057,7 @@ } }, { - "uid": "fiber (Madrid \u2192 Zurich)-", + "uid": "fiber (Madrid → Zurich)-", "metadata": { "location": { "latitude": 43.89999975, @@ -2899,7 +4075,7 @@ } }, { - "uid": "fiber (Memphis \u2192 Nashville)-", + "uid": "fiber (Memphis → Nashville)-", "metadata": { "location": { "latitude": 35.6399997, @@ -2917,7 +4093,7 @@ } }, { - "uid": "fiber (Miami \u2192 Paris)-", + "uid": "fiber (Miami → Paris)-", "metadata": { "location": { "latitude": 37.320000300000004, @@ -2935,7 +4111,7 @@ } }, { - "uid": "fiber (Miami \u2192 Tampa)-", + "uid": "fiber (Miami → Tampa)-", "metadata": { "location": { "latitude": 26.8699997, @@ -2953,7 +4129,7 @@ } }, { - "uid": "fiber (Miami \u2192 West_Palm_Beach)-", + "uid": "fiber (Miami → West_Palm_Beach)-", "metadata": { "location": { "latitude": 26.26500015, @@ -2971,7 +4147,7 @@ } }, { - "uid": "fiber (Milwaukee \u2192 Minneapolis)-", + "uid": "fiber (Milwaukee → Minneapolis)-", "metadata": { "location": { "latitude": 44.01000005, @@ -2989,7 +4165,7 @@ } }, { - "uid": "fiber (Minneapolis \u2192 Omaha)-", + "uid": "fiber (Minneapolis → Omaha)-", "metadata": { "location": { "latitude": 43.1099986, @@ -3007,7 +4183,7 @@ } }, { - "uid": "fiber (Mumbai \u2192 Rome)-", + "uid": "fiber (Mumbai → Rome)-", "metadata": { "location": { "latitude": 30.42499915, @@ -3025,7 +4201,7 @@ } }, { - "uid": "fiber (Mumbai \u2192 Singapore)-", + "uid": "fiber (Mumbai → Singapore)-", "metadata": { "location": { "latitude": 10.1299993035, @@ -3043,7 +4219,7 @@ } }, { - "uid": "fiber (New_Orleans \u2192 Tallahassee)-", + "uid": "fiber (New_Orleans → Tallahassee)-", "metadata": { "location": { "latitude": 30.265, @@ -3061,7 +4237,7 @@ } }, { - "uid": "fiber (New_York \u2192 Newark)-", + "uid": "fiber (New_York → Newark)-", "metadata": { "location": { "latitude": 40.69499975, @@ -3079,7 +4255,7 @@ } }, { - "uid": "fiber (New_York \u2192 Scranton)-", + "uid": "fiber (New_York → Scranton)-", "metadata": { "location": { "latitude": 41.034999150000004, @@ -3097,7 +4273,7 @@ } }, { - "uid": "fiber (New_York \u2192 Wilmington)-", + "uid": "fiber (New_York → Wilmington)-", "metadata": { "location": { "latitude": 40.20500005, @@ -3115,7 +4291,7 @@ } }, { - "uid": "fiber (Newark \u2192 Philadelphia)-", + "uid": "fiber (Newark → Philadelphia)-", "metadata": { "location": { "latitude": 40.364999850000004, @@ -3133,7 +4309,7 @@ } }, { - "uid": "fiber (Norfolk \u2192 Raleigh)-", + "uid": "fiber (Norfolk → Raleigh)-", "metadata": { "location": { "latitude": 36.36999885, @@ -3151,7 +4327,7 @@ } }, { - "uid": "fiber (Norfolk \u2192 Wilmington)-", + "uid": "fiber (Norfolk → Wilmington)-", "metadata": { "location": { "latitude": 38.33, @@ -3169,7 +4345,7 @@ } }, { - "uid": "fiber (Oakland \u2192 Sacramento)-", + "uid": "fiber (Oakland → Sacramento)-", "metadata": { "location": { "latitude": 38.170000085, @@ -3187,7 +4363,7 @@ } }, { - "uid": "fiber (Oakland \u2192 Salt_Lake_City)-", + "uid": "fiber (Oakland → Salt_Lake_City)-", "metadata": { "location": { "latitude": 39.27499967, @@ -3205,7 +4381,7 @@ } }, { - "uid": "fiber (Oakland \u2192 San_Francisco)-", + "uid": "fiber (Oakland → San_Francisco)-", "metadata": { "location": { "latitude": 37.715000065, @@ -3223,7 +4399,7 @@ } }, { - "uid": "fiber (Oakland \u2192 Taipei)-", + "uid": "fiber (Oakland → Taipei)-", "metadata": { "location": { "latitude": 31.395000605, @@ -3241,7 +4417,7 @@ } }, { - "uid": "fiber (Oklahoma_City \u2192 Tulsa)-", + "uid": "fiber (Oklahoma_City → Tulsa)-", "metadata": { "location": { "latitude": 35.80000075, @@ -3259,7 +4435,7 @@ } }, { - "uid": "fiber (Orlando \u2192 West_Palm_Beach)-", + "uid": "fiber (Orlando → West_Palm_Beach)-", "metadata": { "location": { "latitude": 27.62499955, @@ -3277,7 +4453,7 @@ } }, { - "uid": "fiber (Philadelphia \u2192 Scranton)-", + "uid": "fiber (Philadelphia → Scranton)-", "metadata": { "location": { "latitude": 40.70499925, @@ -3295,7 +4471,7 @@ } }, { - "uid": "fiber (Phoenix \u2192 San_Diego)-", + "uid": "fiber (Phoenix → San_Diego)-", "metadata": { "location": { "latitude": 33.17500114, @@ -3313,7 +4489,7 @@ } }, { - "uid": "fiber (Phoenix \u2192 Tucson)-", + "uid": "fiber (Phoenix → Tucson)-", "metadata": { "location": { "latitude": 32.87000029, @@ -3331,7 +4507,7 @@ } }, { - "uid": "fiber (Pittsburgh \u2192 Scranton)-", + "uid": "fiber (Pittsburgh → Scranton)-", "metadata": { "location": { "latitude": 40.849999999999994, @@ -3349,7 +4525,7 @@ } }, { - "uid": "fiber (Portland \u2192 Sacramento)-", + "uid": "fiber (Portland → Sacramento)-", "metadata": { "location": { "latitude": 42.05500009, @@ -3367,7 +4543,7 @@ } }, { - "uid": "fiber (Portland \u2192 Salt_Lake_City)-", + "uid": "fiber (Portland → Salt_Lake_City)-", "metadata": { "location": { "latitude": 43.159999675, @@ -3385,7 +4561,7 @@ } }, { - "uid": "fiber (Portland \u2192 Seattle)-", + "uid": "fiber (Portland → Seattle)-", "metadata": { "location": { "latitude": 46.57999994, @@ -3403,7 +4579,7 @@ } }, { - "uid": "fiber (Portland \u2192 Tokyo)-", + "uid": "fiber (Portland → Tokyo)-", "metadata": { "location": { "latitude": 40.604999660000004, @@ -3421,7 +4597,7 @@ } }, { - "uid": "fiber (Richmond \u2192 Washington_DC)-", + "uid": "fiber (Richmond → Washington_DC)-", "metadata": { "location": { "latitude": 38.21999945, @@ -3439,7 +4615,7 @@ } }, { - "uid": "fiber (Rochester \u2192 Syracuse)-", + "uid": "fiber (Rochester → Syracuse)-", "metadata": { "location": { "latitude": 43.10499975, @@ -3457,7 +4633,7 @@ } }, { - "uid": "fiber (Rome \u2192 Vienna)-", + "uid": "fiber (Rome → Vienna)-", "metadata": { "location": { "latitude": 45.055001000000004, @@ -3475,7 +4651,7 @@ } }, { - "uid": "fiber (Rome \u2192 Zurich)-", + "uid": "fiber (Rome → Zurich)-", "metadata": { "location": { "latitude": 44.63500055, @@ -3493,7 +4669,7 @@ } }, { - "uid": "fiber (San_Francisco \u2192 San_Jose)-", + "uid": "fiber (San_Francisco → San_Jose)-", "metadata": { "location": { "latitude": 37.479999445000004, @@ -3511,7 +4687,7 @@ } }, { - "uid": "fiber (San_Jose \u2192 Santa_Barbara)-", + "uid": "fiber (San_Jose → Santa_Barbara)-", "metadata": { "location": { "latitude": 35.86499984, @@ -3529,7 +4705,7 @@ } }, { - "uid": "fiber (Scranton \u2192 Syracuse)-", + "uid": "fiber (Scranton → Syracuse)-", "metadata": { "location": { "latitude": 42.2200005, @@ -3547,7 +4723,7 @@ } }, { - "uid": "fiber (Seattle \u2192 Spokane)-", + "uid": "fiber (Seattle → Spokane)-", "metadata": { "location": { "latitude": 47.644998605, @@ -3565,7 +4741,7 @@ } }, { - "uid": "fiber (Seoul \u2192 Tokyo)-", + "uid": "fiber (Seoul → Tokyo)-", "metadata": { "location": { "latitude": 36.614999839999996, @@ -3583,7 +4759,7 @@ } }, { - "uid": "fiber (Singapore \u2192 Sydney)-", + "uid": "fiber (Singapore → Sydney)-", "metadata": { "location": { "latitude": -16.2849995265, @@ -3601,7 +4777,7 @@ } }, { - "uid": "fiber (Springfield \u2192 St_Louis)-", + "uid": "fiber (Springfield → St_Louis)-", "metadata": { "location": { "latitude": 39.07, @@ -3619,7 +4795,7 @@ } }, { - "uid": "fiber (Taipei \u2192 Tokyo)-", + "uid": "fiber (Taipei → Tokyo)-", "metadata": { "location": { "latitude": 30.344999549999997, @@ -3637,7 +4813,7 @@ } }, { - "uid": "fiber (Tallahassee \u2192 Tampa)-", + "uid": "fiber (Tallahassee → Tampa)-", "metadata": { "location": { "latitude": 29.2099994, @@ -3655,7 +4831,7 @@ } }, { - "uid": "fiber (Vienna \u2192 Warsaw)-", + "uid": "fiber (Vienna → Warsaw)-", "metadata": { "location": { "latitude": 50.24000055, @@ -3673,7 +4849,7 @@ } }, { - "uid": "fiber (Dallas \u2192 Abilene)-", + "uid": "fiber (Dallas → Abilene)-", "metadata": { "location": { "latitude": 32.620000000000005, @@ -3691,7 +4867,7 @@ } }, { - "uid": "fiber (El_Paso \u2192 Abilene)-", + "uid": "fiber (El_Paso → Abilene)-", "metadata": { "location": { "latitude": 32.149905000000004, @@ -3709,7 +4885,7 @@ } }, { - "uid": "fiber (Boston \u2192 Albany)-", + "uid": "fiber (Boston → Albany)-", "metadata": { "location": { "latitude": 42.504999350000006, @@ -3727,7 +4903,7 @@ } }, { - "uid": "fiber (Syracuse \u2192 Albany)-", + "uid": "fiber (Syracuse → Albany)-", "metadata": { "location": { "latitude": 42.8549996, @@ -3745,7 +4921,7 @@ } }, { - "uid": "fiber (Dallas \u2192 Albuquerque)-", + "uid": "fiber (Dallas → Albuquerque)-", "metadata": { "location": { "latitude": 33.9549885, @@ -3763,7 +4939,7 @@ } }, { - "uid": "fiber (Denver \u2192 Albuquerque)-", + "uid": "fiber (Denver → Albuquerque)-", "metadata": { "location": { "latitude": 37.444989855, @@ -3781,7 +4957,7 @@ } }, { - "uid": "fiber (El_Paso \u2192 Albuquerque)-", + "uid": "fiber (El_Paso → Albuquerque)-", "metadata": { "location": { "latitude": 33.4848935, @@ -3799,7 +4975,7 @@ } }, { - "uid": "fiber (Las_Vegas \u2192 Albuquerque)-", + "uid": "fiber (Las_Vegas → Albuquerque)-", "metadata": { "location": { "latitude": 35.6649835, @@ -3817,7 +4993,7 @@ } }, { - "uid": "fiber (Berlin \u2192 Amsterdam)-", + "uid": "fiber (Berlin → Amsterdam)-", "metadata": { "location": { "latitude": 52.4450008, @@ -3835,7 +5011,7 @@ } }, { - "uid": "fiber (Brussels \u2192 Amsterdam)-", + "uid": "fiber (Brussels → Amsterdam)-", "metadata": { "location": { "latitude": 51.600000800000004, @@ -3853,7 +5029,7 @@ } }, { - "uid": "fiber (Frankfurt \u2192 Amsterdam)-", + "uid": "fiber (Frankfurt → Amsterdam)-", "metadata": { "location": { "latitude": 51.2449994, @@ -3871,7 +5047,7 @@ } }, { - "uid": "fiber (New_York \u2192 Amsterdam)-", + "uid": "fiber (New_York → Amsterdam)-", "metadata": { "location": { "latitude": 46.51999895, @@ -3889,7 +5065,7 @@ } }, { - "uid": "fiber (Birmingham \u2192 Atlanta)-", + "uid": "fiber (Birmingham → Atlanta)-", "metadata": { "location": { "latitude": 33.644998349999995, @@ -3907,7 +5083,7 @@ } }, { - "uid": "fiber (Charlotte \u2192 Atlanta)-", + "uid": "fiber (Charlotte → Atlanta)-", "metadata": { "location": { "latitude": 34.4799991, @@ -3925,7 +5101,7 @@ } }, { - "uid": "fiber (Jacksonville \u2192 Atlanta)-", + "uid": "fiber (Jacksonville → Atlanta)-", "metadata": { "location": { "latitude": 32.0450006, @@ -3943,7 +5119,7 @@ } }, { - "uid": "fiber (Houston \u2192 Austin)-", + "uid": "fiber (Houston → Austin)-", "metadata": { "location": { "latitude": 30.0399994, @@ -3961,7 +5137,7 @@ } }, { - "uid": "fiber (San_Antonio \u2192 Austin)-", + "uid": "fiber (San_Antonio → Austin)-", "metadata": { "location": { "latitude": 29.884997900000002, @@ -3979,7 +5155,7 @@ } }, { - "uid": "fiber (Philadelphia \u2192 Baltimore)-", + "uid": "fiber (Philadelphia → Baltimore)-", "metadata": { "location": { "latitude": 39.65499885, @@ -3997,7 +5173,7 @@ } }, { - "uid": "fiber (Pittsburgh \u2192 Baltimore)-", + "uid": "fiber (Pittsburgh → Baltimore)-", "metadata": { "location": { "latitude": 39.7999996, @@ -4015,7 +5191,7 @@ } }, { - "uid": "fiber (Washington_DC \u2192 Baltimore)-", + "uid": "fiber (Washington_DC → Baltimore)-", "metadata": { "location": { "latitude": 39.104999750000005, @@ -4033,7 +5209,7 @@ } }, { - "uid": "fiber (Delhi \u2192 Bangkok)-", + "uid": "fiber (Delhi → Bangkok)-", "metadata": { "location": { "latitude": 21.20000015, @@ -4051,7 +5227,7 @@ } }, { - "uid": "fiber (Hong_Kong \u2192 Bangkok)-", + "uid": "fiber (Hong_Kong → Bangkok)-", "metadata": { "location": { "latitude": 17.9985, @@ -4069,7 +5245,7 @@ } }, { - "uid": "fiber (Houston \u2192 Baton_Rouge)-", + "uid": "fiber (Houston → Baton_Rouge)-", "metadata": { "location": { "latitude": 30.1099998, @@ -4087,7 +5263,7 @@ } }, { - "uid": "fiber (New_Orleans \u2192 Baton_Rouge)-", + "uid": "fiber (New_Orleans → Baton_Rouge)-", "metadata": { "location": { "latitude": 30.259999800000003, @@ -4105,7 +5281,7 @@ } }, { - "uid": "fiber (Seoul \u2192 Beijing)-", + "uid": "fiber (Seoul → Beijing)-", "metadata": { "location": { "latitude": 38.745000434999994, @@ -4123,7 +5299,7 @@ } }, { - "uid": "fiber (Shanghai \u2192 Beijing)-", + "uid": "fiber (Shanghai → Beijing)-", "metadata": { "location": { "latitude": 35.579999895, @@ -4141,7 +5317,7 @@ } }, { - "uid": "fiber (Warsaw \u2192 Berlin)-", + "uid": "fiber (Warsaw → Berlin)-", "metadata": { "location": { "latitude": 52.390000349999994, @@ -4159,7 +5335,7 @@ } }, { - "uid": "fiber (Bismarck \u2192 Billings)-", + "uid": "fiber (Bismarck → Billings)-", "metadata": { "location": { "latitude": 46.30000129, @@ -4177,7 +5353,7 @@ } }, { - "uid": "fiber (Denver \u2192 Billings)-", + "uid": "fiber (Denver → Billings)-", "metadata": { "location": { "latitude": 42.780001874999996, @@ -4195,7 +5371,7 @@ } }, { - "uid": "fiber (Spokane \u2192 Billings)-", + "uid": "fiber (Spokane → Billings)-", "metadata": { "location": { "latitude": 46.729999545, @@ -4213,7 +5389,7 @@ } }, { - "uid": "fiber (Nashville \u2192 Birmingham)-", + "uid": "fiber (Nashville → Birmingham)-", "metadata": { "location": { "latitude": 34.84999845, @@ -4231,7 +5407,7 @@ } }, { - "uid": "fiber (New_Orleans \u2192 Birmingham)-", + "uid": "fiber (New_Orleans → Birmingham)-", "metadata": { "location": { "latitude": 31.79999925, @@ -4249,7 +5425,7 @@ } }, { - "uid": "fiber (Minneapolis \u2192 Bismarck)-", + "uid": "fiber (Minneapolis → Bismarck)-", "metadata": { "location": { "latitude": 45.88500017, @@ -4267,7 +5443,7 @@ } }, { - "uid": "fiber (Providence \u2192 Boston)-", + "uid": "fiber (Providence → Boston)-", "metadata": { "location": { "latitude": 42.08000025, @@ -4285,7 +5461,7 @@ } }, { - "uid": "fiber (London \u2192 Brussels)-", + "uid": "fiber (London → Brussels)-", "metadata": { "location": { "latitude": 51.17500125, @@ -4303,7 +5479,7 @@ } }, { - "uid": "fiber (Istanbul \u2192 Bucharest)-", + "uid": "fiber (Istanbul → Bucharest)-", "metadata": { "location": { "latitude": 42.769999999999996, @@ -4321,7 +5497,7 @@ } }, { - "uid": "fiber (Warsaw \u2192 Bucharest)-", + "uid": "fiber (Warsaw → Bucharest)-", "metadata": { "location": { "latitude": 48.34999935, @@ -4339,7 +5515,7 @@ } }, { - "uid": "fiber (Cleveland \u2192 Buffalo)-", + "uid": "fiber (Cleveland → Buffalo)-", "metadata": { "location": { "latitude": 42.184999250000004, @@ -4357,7 +5533,7 @@ } }, { - "uid": "fiber (Rochester \u2192 Buffalo)-", + "uid": "fiber (Rochester → Buffalo)-", "metadata": { "location": { "latitude": 43.029998899999995, @@ -4375,7 +5551,7 @@ } }, { - "uid": "fiber (Jacksonville \u2192 Charleston)-", + "uid": "fiber (Jacksonville → Charleston)-", "metadata": { "location": { "latitude": 31.560001900000003, @@ -4393,7 +5569,7 @@ } }, { - "uid": "fiber (Raleigh \u2192 Charleston)-", + "uid": "fiber (Raleigh → Charleston)-", "metadata": { "location": { "latitude": 34.30500015, @@ -4411,7 +5587,7 @@ } }, { - "uid": "fiber (Greensboro \u2192 Charlotte)-", + "uid": "fiber (Greensboro → Charlotte)-", "metadata": { "location": { "latitude": 35.6400012, @@ -4429,7 +5605,7 @@ } }, { - "uid": "fiber (Detroit \u2192 Chicago)-", + "uid": "fiber (Detroit → Chicago)-", "metadata": { "location": { "latitude": 42.109999450000004, @@ -4447,7 +5623,7 @@ } }, { - "uid": "fiber (Milwaukee \u2192 Chicago)-", + "uid": "fiber (Milwaukee → Chicago)-", "metadata": { "location": { "latitude": 42.44999915, @@ -4465,7 +5641,7 @@ } }, { - "uid": "fiber (Springfield \u2192 Chicago)-", + "uid": "fiber (Springfield → Chicago)-", "metadata": { "location": { "latitude": 40.6699985, @@ -4483,7 +5659,7 @@ } }, { - "uid": "fiber (Columbus \u2192 Cincinnati)-", + "uid": "fiber (Columbus → Cincinnati)-", "metadata": { "location": { "latitude": 39.56500054999999, @@ -4501,7 +5677,7 @@ } }, { - "uid": "fiber (Louisville \u2192 Cincinnati)-", + "uid": "fiber (Louisville → Cincinnati)-", "metadata": { "location": { "latitude": 38.68, @@ -4519,7 +5695,7 @@ } }, { - "uid": "fiber (Washington_DC \u2192 Cincinnati)-", + "uid": "fiber (Washington_DC → Cincinnati)-", "metadata": { "location": { "latitude": 39.024999699999995, @@ -4537,7 +5713,7 @@ } }, { - "uid": "fiber (Columbus \u2192 Cleveland)-", + "uid": "fiber (Columbus → Cleveland)-", "metadata": { "location": { "latitude": 40.7350006, @@ -4555,7 +5731,7 @@ } }, { - "uid": "fiber (Toledo \u2192 Cleveland)-", + "uid": "fiber (Toledo → Cleveland)-", "metadata": { "location": { "latitude": 41.5699981, @@ -4573,7 +5749,7 @@ } }, { - "uid": "fiber (Pittsburgh \u2192 Columbus)-", + "uid": "fiber (Pittsburgh → Columbus)-", "metadata": { "location": { "latitude": 40.14500099999999, @@ -4591,7 +5767,7 @@ } }, { - "uid": "fiber (Houston \u2192 Dallas)-", + "uid": "fiber (Houston → Dallas)-", "metadata": { "location": { "latitude": 31.28, @@ -4609,7 +5785,7 @@ } }, { - "uid": "fiber (Little_Rock \u2192 Dallas)-", + "uid": "fiber (Little_Rock → Dallas)-", "metadata": { "location": { "latitude": 33.754999999999995, @@ -4627,7 +5803,7 @@ } }, { - "uid": "fiber (Oklahoma_City \u2192 Dallas)-", + "uid": "fiber (Oklahoma_City → Dallas)-", "metadata": { "location": { "latitude": 34.13000075, @@ -4645,7 +5821,7 @@ } }, { - "uid": "fiber (Istanbul \u2192 Delhi)-", + "uid": "fiber (Istanbul → Delhi)-", "metadata": { "location": { "latitude": 34.88500015, @@ -4663,7 +5839,7 @@ } }, { - "uid": "fiber (Mumbai \u2192 Delhi)-", + "uid": "fiber (Mumbai → Delhi)-", "metadata": { "location": { "latitude": 23.8149995, @@ -4681,7 +5857,7 @@ } }, { - "uid": "fiber (Omaha \u2192 Denver)-", + "uid": "fiber (Omaha → Denver)-", "metadata": { "location": { "latitude": 40.515000555, @@ -4699,7 +5875,7 @@ } }, { - "uid": "fiber (Salt_Lake_City \u2192 Denver)-", + "uid": "fiber (Salt_Lake_City → Denver)-", "metadata": { "location": { "latitude": 40.27500067, @@ -4717,7 +5893,7 @@ } }, { - "uid": "fiber (Toledo \u2192 Detroit)-", + "uid": "fiber (Toledo → Detroit)-", "metadata": { "location": { "latitude": 42.01999945, @@ -4735,7 +5911,7 @@ } }, { - "uid": "fiber (San_Antonio \u2192 El_Paso)-", + "uid": "fiber (San_Antonio → El_Paso)-", "metadata": { "location": { "latitude": 30.654903500000003, @@ -4753,7 +5929,7 @@ } }, { - "uid": "fiber (Tucson \u2192 El_Paso)-", + "uid": "fiber (Tucson → El_Paso)-", "metadata": { "location": { "latitude": 32.024905000000004, @@ -4771,7 +5947,7 @@ } }, { - "uid": "fiber (Vienna \u2192 Frankfurt)-", + "uid": "fiber (Vienna → Frankfurt)-", "metadata": { "location": { "latitude": 49.1700008, @@ -4789,7 +5965,7 @@ } }, { - "uid": "fiber (Las_Vegas \u2192 Fresno)-", + "uid": "fiber (Las_Vegas → Fresno)-", "metadata": { "location": { "latitude": 36.494995349999996, @@ -4807,7 +5983,7 @@ } }, { - "uid": "fiber (Los_Angeles \u2192 Fresno)-", + "uid": "fiber (Los_Angeles → Fresno)-", "metadata": { "location": { "latitude": 35.44500085, @@ -4825,7 +6001,7 @@ } }, { - "uid": "fiber (Oakland \u2192 Fresno)-", + "uid": "fiber (Oakland → Fresno)-", "metadata": { "location": { "latitude": 37.275000705, @@ -4843,7 +6019,7 @@ } }, { - "uid": "fiber (Louisville \u2192 Greensboro)-", + "uid": "fiber (Louisville → Greensboro)-", "metadata": { "location": { "latitude": 37.15000165, @@ -4861,7 +6037,7 @@ } }, { - "uid": "fiber (Raleigh \u2192 Greensboro)-", + "uid": "fiber (Raleigh → Greensboro)-", "metadata": { "location": { "latitude": 35.95000095, @@ -4879,7 +6055,7 @@ } }, { - "uid": "fiber (Richmond \u2192 Greensboro)-", + "uid": "fiber (Richmond → Greensboro)-", "metadata": { "location": { "latitude": 36.8050005, @@ -4897,7 +6073,7 @@ } }, { - "uid": "fiber (Long_Island \u2192 Hartford)-", + "uid": "fiber (Long_Island → Hartford)-", "metadata": { "location": { "latitude": 41.18000015, @@ -4915,7 +6091,7 @@ } }, { - "uid": "fiber (Providence \u2192 Hartford)-", + "uid": "fiber (Providence → Hartford)-", "metadata": { "location": { "latitude": 41.795000200000004, @@ -4933,7 +6109,7 @@ } }, { - "uid": "fiber (Shanghai \u2192 Hong_Kong)-", + "uid": "fiber (Shanghai → Hong_Kong)-", "metadata": { "location": { "latitude": 26.7485, @@ -4951,7 +6127,7 @@ } }, { - "uid": "fiber (Sydney \u2192 Hong_Kong)-", + "uid": "fiber (Sydney → Hong_Kong)-", "metadata": { "location": { "latitude": -5.801499479999999, @@ -4969,7 +6145,7 @@ } }, { - "uid": "fiber (Taipei \u2192 Hong_Kong)-", + "uid": "fiber (Taipei → Hong_Kong)-", "metadata": { "location": { "latitude": 23.64350025, @@ -4987,7 +6163,7 @@ } }, { - "uid": "fiber (Los_Angeles \u2192 Honolulu)-", + "uid": "fiber (Los_Angeles → Honolulu)-", "metadata": { "location": { "latitude": 27.7150003, @@ -5005,7 +6181,7 @@ } }, { - "uid": "fiber (Sydney \u2192 Honolulu)-", + "uid": "fiber (Sydney → Honolulu)-", "metadata": { "location": { "latitude": -6.274999679999999, @@ -5023,7 +6199,7 @@ } }, { - "uid": "fiber (Taipei \u2192 Honolulu)-", + "uid": "fiber (Taipei → Honolulu)-", "metadata": { "location": { "latitude": 23.17000005, @@ -5041,7 +6217,7 @@ } }, { - "uid": "fiber (Rome \u2192 Istanbul)-", + "uid": "fiber (Rome → Istanbul)-", "metadata": { "location": { "latitude": 41.4949998, @@ -5059,7 +6235,7 @@ } }, { - "uid": "fiber (Orlando \u2192 Jacksonville)-", + "uid": "fiber (Orlando → Jacksonville)-", "metadata": { "location": { "latitude": 29.4150012, @@ -5077,7 +6253,7 @@ } }, { - "uid": "fiber (Omaha \u2192 Kansas_City)-", + "uid": "fiber (Omaha → Kansas_City)-", "metadata": { "location": { "latitude": 40.1899988, @@ -5095,7 +6271,7 @@ } }, { - "uid": "fiber (St_Louis \u2192 Kansas_City)-", + "uid": "fiber (St_Louis → Kansas_City)-", "metadata": { "location": { "latitude": 38.879999600000005, @@ -5113,7 +6289,7 @@ } }, { - "uid": "fiber (Tulsa \u2192 Kansas_City)-", + "uid": "fiber (Tulsa → Kansas_City)-", "metadata": { "location": { "latitude": 37.6249996, @@ -5131,7 +6307,7 @@ } }, { - "uid": "fiber (Phoenix \u2192 Las_Vegas)-", + "uid": "fiber (Phoenix → Las_Vegas)-", "metadata": { "location": { "latitude": 34.87499529, @@ -5149,7 +6325,7 @@ } }, { - "uid": "fiber (Salt_Lake_City \u2192 Las_Vegas)-", + "uid": "fiber (Salt_Lake_City → Las_Vegas)-", "metadata": { "location": { "latitude": 38.494994315, @@ -5167,7 +6343,7 @@ } }, { - "uid": "fiber (Memphis \u2192 Little_Rock)-", + "uid": "fiber (Memphis → Little_Rock)-", "metadata": { "location": { "latitude": 34.9150005, @@ -5185,7 +6361,7 @@ } }, { - "uid": "fiber (Paris \u2192 London)-", + "uid": "fiber (Paris → London)-", "metadata": { "location": { "latitude": 50.19000025, @@ -5203,7 +6379,7 @@ } }, { - "uid": "fiber (Washington_DC \u2192 London)-", + "uid": "fiber (Washington_DC → London)-", "metadata": { "location": { "latitude": 45.2150004, @@ -5221,7 +6397,7 @@ } }, { - "uid": "fiber (New_York \u2192 Long_Island)-", + "uid": "fiber (New_York → Long_Island)-", "metadata": { "location": { "latitude": 40.629999100000006, @@ -5239,7 +6415,7 @@ } }, { - "uid": "fiber (San_Diego \u2192 Los_Angeles)-", + "uid": "fiber (San_Diego → Los_Angeles)-", "metadata": { "location": { "latitude": 33.46000135, @@ -5257,7 +6433,7 @@ } }, { - "uid": "fiber (Santa_Barbara \u2192 Los_Angeles)-", + "uid": "fiber (Santa_Barbara → Los_Angeles)-", "metadata": { "location": { "latitude": 34.270000605, @@ -5275,7 +6451,7 @@ } }, { - "uid": "fiber (Nashville \u2192 Louisville)-", + "uid": "fiber (Nashville → Louisville)-", "metadata": { "location": { "latitude": 37.19499965, @@ -5293,7 +6469,7 @@ } }, { - "uid": "fiber (St_Louis \u2192 Louisville)-", + "uid": "fiber (St_Louis → Louisville)-", "metadata": { "location": { "latitude": 38.43000045, @@ -5311,7 +6487,7 @@ } }, { - "uid": "fiber (Paris \u2192 Madrid)-", + "uid": "fiber (Paris → Madrid)-", "metadata": { "location": { "latitude": 44.639999, @@ -5329,7 +6505,7 @@ } }, { - "uid": "fiber (Zurich \u2192 Madrid)-", + "uid": "fiber (Zurich → Madrid)-", "metadata": { "location": { "latitude": 43.89999975, @@ -5347,7 +6523,7 @@ } }, { - "uid": "fiber (Nashville \u2192 Memphis)-", + "uid": "fiber (Nashville → Memphis)-", "metadata": { "location": { "latitude": 35.6399997, @@ -5365,7 +6541,7 @@ } }, { - "uid": "fiber (Paris \u2192 Miami)-", + "uid": "fiber (Paris → Miami)-", "metadata": { "location": { "latitude": 37.320000300000004, @@ -5383,7 +6559,7 @@ } }, { - "uid": "fiber (Tampa \u2192 Miami)-", + "uid": "fiber (Tampa → Miami)-", "metadata": { "location": { "latitude": 26.8699997, @@ -5401,7 +6577,7 @@ } }, { - "uid": "fiber (West_Palm_Beach \u2192 Miami)-", + "uid": "fiber (West_Palm_Beach → Miami)-", "metadata": { "location": { "latitude": 26.26500015, @@ -5419,7 +6595,7 @@ } }, { - "uid": "fiber (Minneapolis \u2192 Milwaukee)-", + "uid": "fiber (Minneapolis → Milwaukee)-", "metadata": { "location": { "latitude": 44.01000005, @@ -5437,7 +6613,7 @@ } }, { - "uid": "fiber (Omaha \u2192 Minneapolis)-", + "uid": "fiber (Omaha → Minneapolis)-", "metadata": { "location": { "latitude": 43.1099986, @@ -5455,7 +6631,7 @@ } }, { - "uid": "fiber (Rome \u2192 Mumbai)-", + "uid": "fiber (Rome → Mumbai)-", "metadata": { "location": { "latitude": 30.42499915, @@ -5473,7 +6649,7 @@ } }, { - "uid": "fiber (Singapore \u2192 Mumbai)-", + "uid": "fiber (Singapore → Mumbai)-", "metadata": { "location": { "latitude": 10.1299993035, @@ -5491,7 +6667,7 @@ } }, { - "uid": "fiber (Tallahassee \u2192 New_Orleans)-", + "uid": "fiber (Tallahassee → New_Orleans)-", "metadata": { "location": { "latitude": 30.265, @@ -5509,7 +6685,7 @@ } }, { - "uid": "fiber (Newark \u2192 New_York)-", + "uid": "fiber (Newark → New_York)-", "metadata": { "location": { "latitude": 40.69499975, @@ -5527,7 +6703,7 @@ } }, { - "uid": "fiber (Scranton \u2192 New_York)-", + "uid": "fiber (Scranton → New_York)-", "metadata": { "location": { "latitude": 41.034999150000004, @@ -5545,7 +6721,7 @@ } }, { - "uid": "fiber (Wilmington \u2192 New_York)-", + "uid": "fiber (Wilmington → New_York)-", "metadata": { "location": { "latitude": 40.20500005, @@ -5563,7 +6739,7 @@ } }, { - "uid": "fiber (Philadelphia \u2192 Newark)-", + "uid": "fiber (Philadelphia → Newark)-", "metadata": { "location": { "latitude": 40.364999850000004, @@ -5581,7 +6757,7 @@ } }, { - "uid": "fiber (Raleigh \u2192 Norfolk)-", + "uid": "fiber (Raleigh → Norfolk)-", "metadata": { "location": { "latitude": 36.36999885, @@ -5599,7 +6775,7 @@ } }, { - "uid": "fiber (Wilmington \u2192 Norfolk)-", + "uid": "fiber (Wilmington → Norfolk)-", "metadata": { "location": { "latitude": 38.33, @@ -5617,7 +6793,7 @@ } }, { - "uid": "fiber (Sacramento \u2192 Oakland)-", + "uid": "fiber (Sacramento → Oakland)-", "metadata": { "location": { "latitude": 38.170000085, @@ -5635,7 +6811,7 @@ } }, { - "uid": "fiber (Salt_Lake_City \u2192 Oakland)-", + "uid": "fiber (Salt_Lake_City → Oakland)-", "metadata": { "location": { "latitude": 39.27499967, @@ -5653,7 +6829,7 @@ } }, { - "uid": "fiber (San_Francisco \u2192 Oakland)-", + "uid": "fiber (San_Francisco → Oakland)-", "metadata": { "location": { "latitude": 37.715000065, @@ -5671,7 +6847,7 @@ } }, { - "uid": "fiber (Taipei \u2192 Oakland)-", + "uid": "fiber (Taipei → Oakland)-", "metadata": { "location": { "latitude": 31.395000605, @@ -5689,7 +6865,7 @@ } }, { - "uid": "fiber (Tulsa \u2192 Oklahoma_City)-", + "uid": "fiber (Tulsa → Oklahoma_City)-", "metadata": { "location": { "latitude": 35.80000075, @@ -5707,7 +6883,7 @@ } }, { - "uid": "fiber (West_Palm_Beach \u2192 Orlando)-", + "uid": "fiber (West_Palm_Beach → Orlando)-", "metadata": { "location": { "latitude": 27.62499955, @@ -5725,7 +6901,7 @@ } }, { - "uid": "fiber (Scranton \u2192 Philadelphia)-", + "uid": "fiber (Scranton → Philadelphia)-", "metadata": { "location": { "latitude": 40.70499925, @@ -5743,7 +6919,7 @@ } }, { - "uid": "fiber (San_Diego \u2192 Phoenix)-", + "uid": "fiber (San_Diego → Phoenix)-", "metadata": { "location": { "latitude": 33.17500114, @@ -5761,7 +6937,7 @@ } }, { - "uid": "fiber (Tucson \u2192 Phoenix)-", + "uid": "fiber (Tucson → Phoenix)-", "metadata": { "location": { "latitude": 32.87000029, @@ -5779,7 +6955,7 @@ } }, { - "uid": "fiber (Scranton \u2192 Pittsburgh)-", + "uid": "fiber (Scranton → Pittsburgh)-", "metadata": { "location": { "latitude": 40.849999999999994, @@ -5797,7 +6973,7 @@ } }, { - "uid": "fiber (Sacramento \u2192 Portland)-", + "uid": "fiber (Sacramento → Portland)-", "metadata": { "location": { "latitude": 42.05500009, @@ -5815,7 +6991,7 @@ } }, { - "uid": "fiber (Salt_Lake_City \u2192 Portland)-", + "uid": "fiber (Salt_Lake_City → Portland)-", "metadata": { "location": { "latitude": 43.159999675, @@ -5833,7 +7009,7 @@ } }, { - "uid": "fiber (Seattle \u2192 Portland)-", + "uid": "fiber (Seattle → Portland)-", "metadata": { "location": { "latitude": 46.57999994, @@ -5851,7 +7027,7 @@ } }, { - "uid": "fiber (Tokyo \u2192 Portland)-", + "uid": "fiber (Tokyo → Portland)-", "metadata": { "location": { "latitude": 40.604999660000004, @@ -5869,7 +7045,7 @@ } }, { - "uid": "fiber (Washington_DC \u2192 Richmond)-", + "uid": "fiber (Washington_DC → Richmond)-", "metadata": { "location": { "latitude": 38.21999945, @@ -5887,7 +7063,7 @@ } }, { - "uid": "fiber (Syracuse \u2192 Rochester)-", + "uid": "fiber (Syracuse → Rochester)-", "metadata": { "location": { "latitude": 43.10499975, @@ -5905,7 +7081,7 @@ } }, { - "uid": "fiber (Vienna \u2192 Rome)-", + "uid": "fiber (Vienna → Rome)-", "metadata": { "location": { "latitude": 45.055001000000004, @@ -5923,7 +7099,7 @@ } }, { - "uid": "fiber (Zurich \u2192 Rome)-", + "uid": "fiber (Zurich → Rome)-", "metadata": { "location": { "latitude": 44.63500055, @@ -5941,7 +7117,7 @@ } }, { - "uid": "fiber (San_Jose \u2192 San_Francisco)-", + "uid": "fiber (San_Jose → San_Francisco)-", "metadata": { "location": { "latitude": 37.479999445000004, @@ -5959,7 +7135,7 @@ } }, { - "uid": "fiber (Santa_Barbara \u2192 San_Jose)-", + "uid": "fiber (Santa_Barbara → San_Jose)-", "metadata": { "location": { "latitude": 35.86499984, @@ -5977,7 +7153,7 @@ } }, { - "uid": "fiber (Syracuse \u2192 Scranton)-", + "uid": "fiber (Syracuse → Scranton)-", "metadata": { "location": { "latitude": 42.2200005, @@ -5995,7 +7171,7 @@ } }, { - "uid": "fiber (Spokane \u2192 Seattle)-", + "uid": "fiber (Spokane → Seattle)-", "metadata": { "location": { "latitude": 47.644998605, @@ -6013,7 +7189,7 @@ } }, { - "uid": "fiber (Tokyo \u2192 Seoul)-", + "uid": "fiber (Tokyo → Seoul)-", "metadata": { "location": { "latitude": 36.614999839999996, @@ -6031,7 +7207,7 @@ } }, { - "uid": "fiber (Sydney \u2192 Singapore)-", + "uid": "fiber (Sydney → Singapore)-", "metadata": { "location": { "latitude": -16.2849995265, @@ -6049,7 +7225,7 @@ } }, { - "uid": "fiber (St_Louis \u2192 Springfield)-", + "uid": "fiber (St_Louis → Springfield)-", "metadata": { "location": { "latitude": 39.07, @@ -6067,7 +7243,7 @@ } }, { - "uid": "fiber (Tokyo \u2192 Taipei)-", + "uid": "fiber (Tokyo → Taipei)-", "metadata": { "location": { "latitude": 30.344999549999997, @@ -6085,7 +7261,7 @@ } }, { - "uid": "fiber (Tampa \u2192 Tallahassee)-", + "uid": "fiber (Tampa → Tallahassee)-", "metadata": { "location": { "latitude": 29.2099994, @@ -6103,7 +7279,7 @@ } }, { - "uid": "fiber (Warsaw \u2192 Vienna)-", + "uid": "fiber (Warsaw → Vienna)-", "metadata": { "location": { "latitude": 50.24000055, @@ -6123,1789 +7299,2197 @@ ], "connections": [ { - "from_node": "fiber (Dallas \u2192 Abilene)-", - "to_node": "fiber (Abilene \u2192 El_Paso)-" + "from_node": "roadm Abilene", + "to_node": "fiber (Abilene → Dallas)-" }, { - "from_node": "fiber (El_Paso \u2192 Abilene)-", - "to_node": "fiber (Abilene \u2192 Dallas)-" + "from_node": "fiber (Dallas → Abilene)-", + "to_node": "roadm Abilene" }, { - "from_node": "fiber (Boston \u2192 Albany)-", - "to_node": "fiber (Albany \u2192 Syracuse)-" + "from_node": "roadm Abilene", + "to_node": "fiber (Abilene → El_Paso)-" }, { - "from_node": "fiber (Syracuse \u2192 Albany)-", - "to_node": "fiber (Albany \u2192 Boston)-" + "from_node": "fiber (El_Paso → Abilene)-", + "to_node": "roadm Abilene" + }, + { + "from_node": "roadm Albany", + "to_node": "fiber (Albany → Boston)-" + }, + { + "from_node": "fiber (Boston → Albany)-", + "to_node": "roadm Albany" + }, + { + "from_node": "roadm Albany", + "to_node": "fiber (Albany → Syracuse)-" + }, + { + "from_node": "fiber (Syracuse → Albany)-", + "to_node": "roadm Albany" }, { "from_node": "roadm Albuquerque", - "to_node": "fiber (Albuquerque \u2192 Dallas)-" + "to_node": "fiber (Albuquerque → Dallas)-" }, { - "from_node": "fiber (Dallas \u2192 Albuquerque)-", + "from_node": "fiber (Dallas → Albuquerque)-", "to_node": "roadm Albuquerque" }, { "from_node": "roadm Albuquerque", - "to_node": "fiber (Albuquerque \u2192 Denver)-" + "to_node": "fiber (Albuquerque → Denver)-" }, { - "from_node": "fiber (Denver \u2192 Albuquerque)-", + "from_node": "fiber (Denver → Albuquerque)-", "to_node": "roadm Albuquerque" }, { "from_node": "roadm Albuquerque", - "to_node": "fiber (Albuquerque \u2192 El_Paso)-" + "to_node": "fiber (Albuquerque → El_Paso)-" }, { - "from_node": "fiber (El_Paso \u2192 Albuquerque)-", + "from_node": "fiber (El_Paso → Albuquerque)-", "to_node": "roadm Albuquerque" }, { "from_node": "roadm Albuquerque", - "to_node": "fiber (Albuquerque \u2192 Las_Vegas)-" + "to_node": "fiber (Albuquerque → Las_Vegas)-" }, { - "from_node": "fiber (Las_Vegas \u2192 Albuquerque)-", + "from_node": "fiber (Las_Vegas → Albuquerque)-", "to_node": "roadm Albuquerque" }, { "from_node": "roadm Atlanta", - "to_node": "fiber (Atlanta \u2192 Birmingham)-" + "to_node": "fiber (Atlanta → Birmingham)-" }, { - "from_node": "fiber (Birmingham \u2192 Atlanta)-", + "from_node": "fiber (Birmingham → Atlanta)-", "to_node": "roadm Atlanta" }, { "from_node": "roadm Atlanta", - "to_node": "fiber (Atlanta \u2192 Charlotte)-" + "to_node": "fiber (Atlanta → Charlotte)-" }, { - "from_node": "fiber (Charlotte \u2192 Atlanta)-", + "from_node": "fiber (Charlotte → Atlanta)-", "to_node": "roadm Atlanta" }, { "from_node": "roadm Atlanta", - "to_node": "fiber (Atlanta \u2192 Jacksonville)-" + "to_node": "fiber (Atlanta → Jacksonville)-" }, { - "from_node": "fiber (Jacksonville \u2192 Atlanta)-", + "from_node": "fiber (Jacksonville → Atlanta)-", "to_node": "roadm Atlanta" }, { - "from_node": "fiber (Houston \u2192 Austin)-", - "to_node": "fiber (Austin \u2192 San_Antonio)-" + "from_node": "roadm Austin", + "to_node": "fiber (Austin → Houston)-" }, { - "from_node": "fiber (San_Antonio \u2192 Austin)-", - "to_node": "fiber (Austin \u2192 Houston)-" + "from_node": "fiber (Houston → Austin)-", + "to_node": "roadm Austin" + }, + { + "from_node": "roadm Austin", + "to_node": "fiber (Austin → San_Antonio)-" + }, + { + "from_node": "fiber (San_Antonio → Austin)-", + "to_node": "roadm Austin" }, { "from_node": "roadm Baltimore", - "to_node": "fiber (Baltimore \u2192 Philadelphia)-" + "to_node": "fiber (Baltimore → Philadelphia)-" }, { - "from_node": "fiber (Philadelphia \u2192 Baltimore)-", + "from_node": "fiber (Philadelphia → Baltimore)-", "to_node": "roadm Baltimore" }, { "from_node": "roadm Baltimore", - "to_node": "fiber (Baltimore \u2192 Pittsburgh)-" + "to_node": "fiber (Baltimore → Pittsburgh)-" }, { - "from_node": "fiber (Pittsburgh \u2192 Baltimore)-", + "from_node": "fiber (Pittsburgh → Baltimore)-", "to_node": "roadm Baltimore" }, { "from_node": "roadm Baltimore", - "to_node": "fiber (Baltimore \u2192 Washington_DC)-" + "to_node": "fiber (Baltimore → Washington_DC)-" }, { - "from_node": "fiber (Washington_DC \u2192 Baltimore)-", + "from_node": "fiber (Washington_DC → Baltimore)-", "to_node": "roadm Baltimore" }, { - "from_node": "fiber (Houston \u2192 Baton_Rouge)-", - "to_node": "fiber (Baton_Rouge \u2192 New_Orleans)-" + "from_node": "roadm Baton_Rouge", + "to_node": "fiber (Baton_Rouge → Houston)-" }, { - "from_node": "fiber (New_Orleans \u2192 Baton_Rouge)-", - "to_node": "fiber (Baton_Rouge \u2192 Houston)-" + "from_node": "fiber (Houston → Baton_Rouge)-", + "to_node": "roadm Baton_Rouge" + }, + { + "from_node": "roadm Baton_Rouge", + "to_node": "fiber (Baton_Rouge → New_Orleans)-" + }, + { + "from_node": "fiber (New_Orleans → Baton_Rouge)-", + "to_node": "roadm Baton_Rouge" }, { "from_node": "roadm Billings", - "to_node": "fiber (Billings \u2192 Bismarck)-" + "to_node": "fiber (Billings → Bismarck)-" }, { - "from_node": "fiber (Bismarck \u2192 Billings)-", + "from_node": "fiber (Bismarck → Billings)-", "to_node": "roadm Billings" }, { "from_node": "roadm Billings", - "to_node": "fiber (Billings \u2192 Denver)-" + "to_node": "fiber (Billings → Denver)-" }, { - "from_node": "fiber (Denver \u2192 Billings)-", + "from_node": "fiber (Denver → Billings)-", "to_node": "roadm Billings" }, { "from_node": "roadm Billings", - "to_node": "fiber (Billings \u2192 Spokane)-" + "to_node": "fiber (Billings → Spokane)-" }, { - "from_node": "fiber (Spokane \u2192 Billings)-", + "from_node": "fiber (Spokane → Billings)-", "to_node": "roadm Billings" }, { "from_node": "roadm Birmingham", - "to_node": "fiber (Birmingham \u2192 Atlanta)-" + "to_node": "fiber (Birmingham → Atlanta)-" }, { - "from_node": "fiber (Atlanta \u2192 Birmingham)-", + "from_node": "fiber (Atlanta → Birmingham)-", "to_node": "roadm Birmingham" }, { "from_node": "roadm Birmingham", - "to_node": "fiber (Birmingham \u2192 Nashville)-" + "to_node": "fiber (Birmingham → Nashville)-" }, { - "from_node": "fiber (Nashville \u2192 Birmingham)-", + "from_node": "fiber (Nashville → Birmingham)-", "to_node": "roadm Birmingham" }, { "from_node": "roadm Birmingham", - "to_node": "fiber (Birmingham \u2192 New_Orleans)-" + "to_node": "fiber (Birmingham → New_Orleans)-" }, { - "from_node": "fiber (New_Orleans \u2192 Birmingham)-", + "from_node": "fiber (New_Orleans → Birmingham)-", "to_node": "roadm Birmingham" }, { - "from_node": "fiber (Billings \u2192 Bismarck)-", - "to_node": "fiber (Bismarck \u2192 Minneapolis)-" + "from_node": "roadm Bismarck", + "to_node": "fiber (Bismarck → Billings)-" }, { - "from_node": "fiber (Minneapolis \u2192 Bismarck)-", - "to_node": "fiber (Bismarck \u2192 Billings)-" + "from_node": "fiber (Billings → Bismarck)-", + "to_node": "roadm Bismarck" }, { - "from_node": "fiber (Albany \u2192 Boston)-", - "to_node": "fiber (Boston \u2192 Providence)-" + "from_node": "roadm Bismarck", + "to_node": "fiber (Bismarck → Minneapolis)-" }, { - "from_node": "fiber (Providence \u2192 Boston)-", - "to_node": "fiber (Boston \u2192 Albany)-" + "from_node": "fiber (Minneapolis → Bismarck)-", + "to_node": "roadm Bismarck" }, { - "from_node": "fiber (Cleveland \u2192 Buffalo)-", - "to_node": "fiber (Buffalo \u2192 Rochester)-" + "from_node": "roadm Boston", + "to_node": "fiber (Boston → Albany)-" }, { - "from_node": "fiber (Rochester \u2192 Buffalo)-", - "to_node": "fiber (Buffalo \u2192 Cleveland)-" + "from_node": "fiber (Albany → Boston)-", + "to_node": "roadm Boston" }, { - "from_node": "fiber (Jacksonville \u2192 Charleston)-", - "to_node": "fiber (Charleston \u2192 Raleigh)-" + "from_node": "roadm Boston", + "to_node": "fiber (Boston → Providence)-" }, { - "from_node": "fiber (Raleigh \u2192 Charleston)-", - "to_node": "fiber (Charleston \u2192 Jacksonville)-" + "from_node": "fiber (Providence → Boston)-", + "to_node": "roadm Boston" }, { - "from_node": "fiber (Atlanta \u2192 Charlotte)-", - "to_node": "fiber (Charlotte \u2192 Greensboro)-" + "from_node": "roadm Buffalo", + "to_node": "fiber (Buffalo → Cleveland)-" }, { - "from_node": "fiber (Greensboro \u2192 Charlotte)-", - "to_node": "fiber (Charlotte \u2192 Atlanta)-" + "from_node": "fiber (Cleveland → Buffalo)-", + "to_node": "roadm Buffalo" + }, + { + "from_node": "roadm Buffalo", + "to_node": "fiber (Buffalo → Rochester)-" + }, + { + "from_node": "fiber (Rochester → Buffalo)-", + "to_node": "roadm Buffalo" + }, + { + "from_node": "roadm Charleston", + "to_node": "fiber (Charleston → Jacksonville)-" + }, + { + "from_node": "fiber (Jacksonville → Charleston)-", + "to_node": "roadm Charleston" + }, + { + "from_node": "roadm Charleston", + "to_node": "fiber (Charleston → Raleigh)-" + }, + { + "from_node": "fiber (Raleigh → Charleston)-", + "to_node": "roadm Charleston" + }, + { + "from_node": "roadm Charlotte", + "to_node": "fiber (Charlotte → Atlanta)-" + }, + { + "from_node": "fiber (Atlanta → Charlotte)-", + "to_node": "roadm Charlotte" + }, + { + "from_node": "roadm Charlotte", + "to_node": "fiber (Charlotte → Greensboro)-" + }, + { + "from_node": "fiber (Greensboro → Charlotte)-", + "to_node": "roadm Charlotte" }, { "from_node": "roadm Chicago", - "to_node": "fiber (Chicago \u2192 Detroit)-" + "to_node": "fiber (Chicago → Detroit)-" }, { - "from_node": "fiber (Detroit \u2192 Chicago)-", + "from_node": "fiber (Detroit → Chicago)-", "to_node": "roadm Chicago" }, { "from_node": "roadm Chicago", - "to_node": "fiber (Chicago \u2192 Milwaukee)-" + "to_node": "fiber (Chicago → Milwaukee)-" }, { - "from_node": "fiber (Milwaukee \u2192 Chicago)-", + "from_node": "fiber (Milwaukee → Chicago)-", "to_node": "roadm Chicago" }, { "from_node": "roadm Chicago", - "to_node": "fiber (Chicago \u2192 Springfield)-" + "to_node": "fiber (Chicago → Springfield)-" }, { - "from_node": "fiber (Springfield \u2192 Chicago)-", + "from_node": "fiber (Springfield → Chicago)-", "to_node": "roadm Chicago" }, { "from_node": "roadm Cincinnati", - "to_node": "fiber (Cincinnati \u2192 Columbus)-" + "to_node": "fiber (Cincinnati → Columbus)-" }, { - "from_node": "fiber (Columbus \u2192 Cincinnati)-", + "from_node": "fiber (Columbus → Cincinnati)-", "to_node": "roadm Cincinnati" }, { "from_node": "roadm Cincinnati", - "to_node": "fiber (Cincinnati \u2192 Louisville)-" + "to_node": "fiber (Cincinnati → Louisville)-" }, { - "from_node": "fiber (Louisville \u2192 Cincinnati)-", + "from_node": "fiber (Louisville → Cincinnati)-", "to_node": "roadm Cincinnati" }, { "from_node": "roadm Cincinnati", - "to_node": "fiber (Cincinnati \u2192 Washington_DC)-" + "to_node": "fiber (Cincinnati → Washington_DC)-" }, { - "from_node": "fiber (Washington_DC \u2192 Cincinnati)-", + "from_node": "fiber (Washington_DC → Cincinnati)-", "to_node": "roadm Cincinnati" }, { "from_node": "roadm Cleveland", - "to_node": "fiber (Cleveland \u2192 Buffalo)-" + "to_node": "fiber (Cleveland → Buffalo)-" }, { - "from_node": "fiber (Buffalo \u2192 Cleveland)-", + "from_node": "fiber (Buffalo → Cleveland)-", "to_node": "roadm Cleveland" }, { "from_node": "roadm Cleveland", - "to_node": "fiber (Cleveland \u2192 Columbus)-" + "to_node": "fiber (Cleveland → Columbus)-" }, { - "from_node": "fiber (Columbus \u2192 Cleveland)-", + "from_node": "fiber (Columbus → Cleveland)-", "to_node": "roadm Cleveland" }, { "from_node": "roadm Cleveland", - "to_node": "fiber (Cleveland \u2192 Toledo)-" + "to_node": "fiber (Cleveland → Toledo)-" }, { - "from_node": "fiber (Toledo \u2192 Cleveland)-", + "from_node": "fiber (Toledo → Cleveland)-", "to_node": "roadm Cleveland" }, { "from_node": "roadm Columbus", - "to_node": "fiber (Columbus \u2192 Cincinnati)-" + "to_node": "fiber (Columbus → Cincinnati)-" }, { - "from_node": "fiber (Cincinnati \u2192 Columbus)-", + "from_node": "fiber (Cincinnati → Columbus)-", "to_node": "roadm Columbus" }, { "from_node": "roadm Columbus", - "to_node": "fiber (Columbus \u2192 Cleveland)-" + "to_node": "fiber (Columbus → Cleveland)-" }, { - "from_node": "fiber (Cleveland \u2192 Columbus)-", + "from_node": "fiber (Cleveland → Columbus)-", "to_node": "roadm Columbus" }, { "from_node": "roadm Columbus", - "to_node": "fiber (Columbus \u2192 Pittsburgh)-" + "to_node": "fiber (Columbus → Pittsburgh)-" }, { - "from_node": "fiber (Pittsburgh \u2192 Columbus)-", + "from_node": "fiber (Pittsburgh → Columbus)-", "to_node": "roadm Columbus" }, { "from_node": "roadm Dallas", - "to_node": "fiber (Dallas \u2192 Abilene)-" + "to_node": "fiber (Dallas → Abilene)-" }, { - "from_node": "fiber (Abilene \u2192 Dallas)-", + "from_node": "fiber (Abilene → Dallas)-", "to_node": "roadm Dallas" }, { "from_node": "roadm Dallas", - "to_node": "fiber (Dallas \u2192 Albuquerque)-" + "to_node": "fiber (Dallas → Albuquerque)-" }, { - "from_node": "fiber (Albuquerque \u2192 Dallas)-", + "from_node": "fiber (Albuquerque → Dallas)-", "to_node": "roadm Dallas" }, { "from_node": "roadm Dallas", - "to_node": "fiber (Dallas \u2192 Houston)-" + "to_node": "fiber (Dallas → Houston)-" }, { - "from_node": "fiber (Houston \u2192 Dallas)-", + "from_node": "fiber (Houston → Dallas)-", "to_node": "roadm Dallas" }, { "from_node": "roadm Dallas", - "to_node": "fiber (Dallas \u2192 Little_Rock)-" + "to_node": "fiber (Dallas → Little_Rock)-" }, { - "from_node": "fiber (Little_Rock \u2192 Dallas)-", + "from_node": "fiber (Little_Rock → Dallas)-", "to_node": "roadm Dallas" }, { "from_node": "roadm Dallas", - "to_node": "fiber (Dallas \u2192 Oklahoma_City)-" + "to_node": "fiber (Dallas → Oklahoma_City)-" }, { - "from_node": "fiber (Oklahoma_City \u2192 Dallas)-", + "from_node": "fiber (Oklahoma_City → Dallas)-", "to_node": "roadm Dallas" }, { "from_node": "roadm Denver", - "to_node": "fiber (Denver \u2192 Albuquerque)-" + "to_node": "fiber (Denver → Albuquerque)-" }, { - "from_node": "fiber (Albuquerque \u2192 Denver)-", + "from_node": "fiber (Albuquerque → Denver)-", "to_node": "roadm Denver" }, { "from_node": "roadm Denver", - "to_node": "fiber (Denver \u2192 Billings)-" + "to_node": "fiber (Denver → Billings)-" }, { - "from_node": "fiber (Billings \u2192 Denver)-", + "from_node": "fiber (Billings → Denver)-", "to_node": "roadm Denver" }, { "from_node": "roadm Denver", - "to_node": "fiber (Denver \u2192 Omaha)-" + "to_node": "fiber (Denver → Omaha)-" }, { - "from_node": "fiber (Omaha \u2192 Denver)-", + "from_node": "fiber (Omaha → Denver)-", "to_node": "roadm Denver" }, { "from_node": "roadm Denver", - "to_node": "fiber (Denver \u2192 Salt_Lake_City)-" + "to_node": "fiber (Denver → Salt_Lake_City)-" }, { - "from_node": "fiber (Salt_Lake_City \u2192 Denver)-", + "from_node": "fiber (Salt_Lake_City → Denver)-", "to_node": "roadm Denver" }, { - "from_node": "fiber (Chicago \u2192 Detroit)-", - "to_node": "fiber (Detroit \u2192 Toledo)-" + "from_node": "roadm Detroit", + "to_node": "fiber (Detroit → Chicago)-" }, { - "from_node": "fiber (Toledo \u2192 Detroit)-", - "to_node": "fiber (Detroit \u2192 Chicago)-" + "from_node": "fiber (Chicago → Detroit)-", + "to_node": "roadm Detroit" + }, + { + "from_node": "roadm Detroit", + "to_node": "fiber (Detroit → Toledo)-" + }, + { + "from_node": "fiber (Toledo → Detroit)-", + "to_node": "roadm Detroit" }, { "from_node": "roadm El_Paso", - "to_node": "fiber (El_Paso \u2192 Abilene)-" + "to_node": "fiber (El_Paso → Abilene)-" }, { - "from_node": "fiber (Abilene \u2192 El_Paso)-", + "from_node": "fiber (Abilene → El_Paso)-", "to_node": "roadm El_Paso" }, { "from_node": "roadm El_Paso", - "to_node": "fiber (El_Paso \u2192 Albuquerque)-" + "to_node": "fiber (El_Paso → Albuquerque)-" }, { - "from_node": "fiber (Albuquerque \u2192 El_Paso)-", + "from_node": "fiber (Albuquerque → El_Paso)-", "to_node": "roadm El_Paso" }, { "from_node": "roadm El_Paso", - "to_node": "fiber (El_Paso \u2192 San_Antonio)-" + "to_node": "fiber (El_Paso → San_Antonio)-" }, { - "from_node": "fiber (San_Antonio \u2192 El_Paso)-", + "from_node": "fiber (San_Antonio → El_Paso)-", "to_node": "roadm El_Paso" }, { "from_node": "roadm El_Paso", - "to_node": "fiber (El_Paso \u2192 Tucson)-" + "to_node": "fiber (El_Paso → Tucson)-" }, { - "from_node": "fiber (Tucson \u2192 El_Paso)-", + "from_node": "fiber (Tucson → El_Paso)-", "to_node": "roadm El_Paso" }, { "from_node": "roadm Fresno", - "to_node": "fiber (Fresno \u2192 Las_Vegas)-" + "to_node": "fiber (Fresno → Las_Vegas)-" }, { - "from_node": "fiber (Las_Vegas \u2192 Fresno)-", + "from_node": "fiber (Las_Vegas → Fresno)-", "to_node": "roadm Fresno" }, { "from_node": "roadm Fresno", - "to_node": "fiber (Fresno \u2192 Los_Angeles)-" + "to_node": "fiber (Fresno → Los_Angeles)-" }, { - "from_node": "fiber (Los_Angeles \u2192 Fresno)-", + "from_node": "fiber (Los_Angeles → Fresno)-", "to_node": "roadm Fresno" }, { "from_node": "roadm Fresno", - "to_node": "fiber (Fresno \u2192 Oakland)-" + "to_node": "fiber (Fresno → Oakland)-" }, { - "from_node": "fiber (Oakland \u2192 Fresno)-", + "from_node": "fiber (Oakland → Fresno)-", "to_node": "roadm Fresno" }, { "from_node": "roadm Greensboro", - "to_node": "fiber (Greensboro \u2192 Charlotte)-" + "to_node": "fiber (Greensboro → Charlotte)-" }, { - "from_node": "fiber (Charlotte \u2192 Greensboro)-", + "from_node": "fiber (Charlotte → Greensboro)-", "to_node": "roadm Greensboro" }, { "from_node": "roadm Greensboro", - "to_node": "fiber (Greensboro \u2192 Louisville)-" + "to_node": "fiber (Greensboro → Louisville)-" }, { - "from_node": "fiber (Louisville \u2192 Greensboro)-", + "from_node": "fiber (Louisville → Greensboro)-", "to_node": "roadm Greensboro" }, { "from_node": "roadm Greensboro", - "to_node": "fiber (Greensboro \u2192 Raleigh)-" + "to_node": "fiber (Greensboro → Raleigh)-" }, { - "from_node": "fiber (Raleigh \u2192 Greensboro)-", + "from_node": "fiber (Raleigh → Greensboro)-", "to_node": "roadm Greensboro" }, { "from_node": "roadm Greensboro", - "to_node": "fiber (Greensboro \u2192 Richmond)-" + "to_node": "fiber (Greensboro → Richmond)-" }, { - "from_node": "fiber (Richmond \u2192 Greensboro)-", + "from_node": "fiber (Richmond → Greensboro)-", "to_node": "roadm Greensboro" }, { - "from_node": "fiber (Long_Island \u2192 Hartford)-", - "to_node": "fiber (Hartford \u2192 Providence)-" + "from_node": "roadm Hartford", + "to_node": "fiber (Hartford → Long_Island)-" }, { - "from_node": "fiber (Providence \u2192 Hartford)-", - "to_node": "fiber (Hartford \u2192 Long_Island)-" + "from_node": "fiber (Long_Island → Hartford)-", + "to_node": "roadm Hartford" + }, + { + "from_node": "roadm Hartford", + "to_node": "fiber (Hartford → Providence)-" + }, + { + "from_node": "fiber (Providence → Hartford)-", + "to_node": "roadm Hartford" }, { "from_node": "roadm Houston", - "to_node": "fiber (Houston \u2192 Austin)-" + "to_node": "fiber (Houston → Austin)-" }, { - "from_node": "fiber (Austin \u2192 Houston)-", + "from_node": "fiber (Austin → Houston)-", "to_node": "roadm Houston" }, { "from_node": "roadm Houston", - "to_node": "fiber (Houston \u2192 Baton_Rouge)-" + "to_node": "fiber (Houston → Baton_Rouge)-" }, { - "from_node": "fiber (Baton_Rouge \u2192 Houston)-", + "from_node": "fiber (Baton_Rouge → Houston)-", "to_node": "roadm Houston" }, { "from_node": "roadm Houston", - "to_node": "fiber (Houston \u2192 Dallas)-" + "to_node": "fiber (Houston → Dallas)-" }, { - "from_node": "fiber (Dallas \u2192 Houston)-", + "from_node": "fiber (Dallas → Houston)-", "to_node": "roadm Houston" }, { "from_node": "roadm Jacksonville", - "to_node": "fiber (Jacksonville \u2192 Atlanta)-" + "to_node": "fiber (Jacksonville → Atlanta)-" }, { - "from_node": "fiber (Atlanta \u2192 Jacksonville)-", + "from_node": "fiber (Atlanta → Jacksonville)-", "to_node": "roadm Jacksonville" }, { "from_node": "roadm Jacksonville", - "to_node": "fiber (Jacksonville \u2192 Charleston)-" + "to_node": "fiber (Jacksonville → Charleston)-" }, { - "from_node": "fiber (Charleston \u2192 Jacksonville)-", + "from_node": "fiber (Charleston → Jacksonville)-", "to_node": "roadm Jacksonville" }, { "from_node": "roadm Jacksonville", - "to_node": "fiber (Jacksonville \u2192 Orlando)-" + "to_node": "fiber (Jacksonville → Orlando)-" }, { - "from_node": "fiber (Orlando \u2192 Jacksonville)-", + "from_node": "fiber (Orlando → Jacksonville)-", "to_node": "roadm Jacksonville" }, { "from_node": "roadm Kansas_City", - "to_node": "fiber (Kansas_City \u2192 Omaha)-" + "to_node": "fiber (Kansas_City → Omaha)-" }, { - "from_node": "fiber (Omaha \u2192 Kansas_City)-", + "from_node": "fiber (Omaha → Kansas_City)-", "to_node": "roadm Kansas_City" }, { "from_node": "roadm Kansas_City", - "to_node": "fiber (Kansas_City \u2192 St_Louis)-" + "to_node": "fiber (Kansas_City → St_Louis)-" }, { - "from_node": "fiber (St_Louis \u2192 Kansas_City)-", + "from_node": "fiber (St_Louis → Kansas_City)-", "to_node": "roadm Kansas_City" }, { "from_node": "roadm Kansas_City", - "to_node": "fiber (Kansas_City \u2192 Tulsa)-" + "to_node": "fiber (Kansas_City → Tulsa)-" }, { - "from_node": "fiber (Tulsa \u2192 Kansas_City)-", + "from_node": "fiber (Tulsa → Kansas_City)-", "to_node": "roadm Kansas_City" }, { "from_node": "roadm Las_Vegas", - "to_node": "fiber (Las_Vegas \u2192 Albuquerque)-" + "to_node": "fiber (Las_Vegas → Albuquerque)-" }, { - "from_node": "fiber (Albuquerque \u2192 Las_Vegas)-", + "from_node": "fiber (Albuquerque → Las_Vegas)-", "to_node": "roadm Las_Vegas" }, { "from_node": "roadm Las_Vegas", - "to_node": "fiber (Las_Vegas \u2192 Fresno)-" + "to_node": "fiber (Las_Vegas → Fresno)-" }, { - "from_node": "fiber (Fresno \u2192 Las_Vegas)-", + "from_node": "fiber (Fresno → Las_Vegas)-", "to_node": "roadm Las_Vegas" }, { "from_node": "roadm Las_Vegas", - "to_node": "fiber (Las_Vegas \u2192 Phoenix)-" + "to_node": "fiber (Las_Vegas → Phoenix)-" }, { - "from_node": "fiber (Phoenix \u2192 Las_Vegas)-", + "from_node": "fiber (Phoenix → Las_Vegas)-", "to_node": "roadm Las_Vegas" }, { "from_node": "roadm Las_Vegas", - "to_node": "fiber (Las_Vegas \u2192 Salt_Lake_City)-" + "to_node": "fiber (Las_Vegas → Salt_Lake_City)-" }, { - "from_node": "fiber (Salt_Lake_City \u2192 Las_Vegas)-", + "from_node": "fiber (Salt_Lake_City → Las_Vegas)-", "to_node": "roadm Las_Vegas" }, { - "from_node": "fiber (Dallas \u2192 Little_Rock)-", - "to_node": "fiber (Little_Rock \u2192 Memphis)-" + "from_node": "roadm Little_Rock", + "to_node": "fiber (Little_Rock → Dallas)-" }, { - "from_node": "fiber (Memphis \u2192 Little_Rock)-", - "to_node": "fiber (Little_Rock \u2192 Dallas)-" + "from_node": "fiber (Dallas → Little_Rock)-", + "to_node": "roadm Little_Rock" }, { - "from_node": "fiber (Hartford \u2192 Long_Island)-", - "to_node": "fiber (Long_Island \u2192 New_York)-" + "from_node": "roadm Little_Rock", + "to_node": "fiber (Little_Rock → Memphis)-" }, { - "from_node": "fiber (New_York \u2192 Long_Island)-", - "to_node": "fiber (Long_Island \u2192 Hartford)-" + "from_node": "fiber (Memphis → Little_Rock)-", + "to_node": "roadm Little_Rock" + }, + { + "from_node": "roadm Long_Island", + "to_node": "fiber (Long_Island → Hartford)-" + }, + { + "from_node": "fiber (Hartford → Long_Island)-", + "to_node": "roadm Long_Island" + }, + { + "from_node": "roadm Long_Island", + "to_node": "fiber (Long_Island → New_York)-" + }, + { + "from_node": "fiber (New_York → Long_Island)-", + "to_node": "roadm Long_Island" }, { "from_node": "roadm Los_Angeles", - "to_node": "fiber (Los_Angeles \u2192 Fresno)-" + "to_node": "fiber (Los_Angeles → Fresno)-" }, { - "from_node": "fiber (Fresno \u2192 Los_Angeles)-", + "from_node": "fiber (Fresno → Los_Angeles)-", "to_node": "roadm Los_Angeles" }, { "from_node": "roadm Los_Angeles", - "to_node": "fiber (Los_Angeles \u2192 Honolulu)-" + "to_node": "fiber (Los_Angeles → Honolulu)-" }, { - "from_node": "fiber (Honolulu \u2192 Los_Angeles)-", + "from_node": "fiber (Honolulu → Los_Angeles)-", "to_node": "roadm Los_Angeles" }, { "from_node": "roadm Los_Angeles", - "to_node": "fiber (Los_Angeles \u2192 San_Diego)-" + "to_node": "fiber (Los_Angeles → San_Diego)-" }, { - "from_node": "fiber (San_Diego \u2192 Los_Angeles)-", + "from_node": "fiber (San_Diego → Los_Angeles)-", "to_node": "roadm Los_Angeles" }, { "from_node": "roadm Los_Angeles", - "to_node": "fiber (Los_Angeles \u2192 Santa_Barbara)-" + "to_node": "fiber (Los_Angeles → Santa_Barbara)-" }, { - "from_node": "fiber (Santa_Barbara \u2192 Los_Angeles)-", + "from_node": "fiber (Santa_Barbara → Los_Angeles)-", "to_node": "roadm Los_Angeles" }, { "from_node": "roadm Louisville", - "to_node": "fiber (Louisville \u2192 Cincinnati)-" + "to_node": "fiber (Louisville → Cincinnati)-" }, { - "from_node": "fiber (Cincinnati \u2192 Louisville)-", + "from_node": "fiber (Cincinnati → Louisville)-", "to_node": "roadm Louisville" }, { "from_node": "roadm Louisville", - "to_node": "fiber (Louisville \u2192 Greensboro)-" + "to_node": "fiber (Louisville → Greensboro)-" }, { - "from_node": "fiber (Greensboro \u2192 Louisville)-", + "from_node": "fiber (Greensboro → Louisville)-", "to_node": "roadm Louisville" }, { "from_node": "roadm Louisville", - "to_node": "fiber (Louisville \u2192 Nashville)-" + "to_node": "fiber (Louisville → Nashville)-" }, { - "from_node": "fiber (Nashville \u2192 Louisville)-", + "from_node": "fiber (Nashville → Louisville)-", "to_node": "roadm Louisville" }, { "from_node": "roadm Louisville", - "to_node": "fiber (Louisville \u2192 St_Louis)-" + "to_node": "fiber (Louisville → St_Louis)-" }, { - "from_node": "fiber (St_Louis \u2192 Louisville)-", + "from_node": "fiber (St_Louis → Louisville)-", "to_node": "roadm Louisville" }, { - "from_node": "fiber (Little_Rock \u2192 Memphis)-", - "to_node": "fiber (Memphis \u2192 Nashville)-" + "from_node": "roadm Memphis", + "to_node": "fiber (Memphis → Little_Rock)-" }, { - "from_node": "fiber (Nashville \u2192 Memphis)-", - "to_node": "fiber (Memphis \u2192 Little_Rock)-" + "from_node": "fiber (Little_Rock → Memphis)-", + "to_node": "roadm Memphis" + }, + { + "from_node": "roadm Memphis", + "to_node": "fiber (Memphis → Nashville)-" + }, + { + "from_node": "fiber (Nashville → Memphis)-", + "to_node": "roadm Memphis" }, { "from_node": "roadm Miami", - "to_node": "fiber (Miami \u2192 Paris)-" + "to_node": "fiber (Miami → Paris)-" }, { - "from_node": "fiber (Paris \u2192 Miami)-", + "from_node": "fiber (Paris → Miami)-", "to_node": "roadm Miami" }, { "from_node": "roadm Miami", - "to_node": "fiber (Miami \u2192 Tampa)-" + "to_node": "fiber (Miami → Tampa)-" }, { - "from_node": "fiber (Tampa \u2192 Miami)-", + "from_node": "fiber (Tampa → Miami)-", "to_node": "roadm Miami" }, { "from_node": "roadm Miami", - "to_node": "fiber (Miami \u2192 West_Palm_Beach)-" + "to_node": "fiber (Miami → West_Palm_Beach)-" }, { - "from_node": "fiber (West_Palm_Beach \u2192 Miami)-", + "from_node": "fiber (West_Palm_Beach → Miami)-", "to_node": "roadm Miami" }, { - "from_node": "fiber (Chicago \u2192 Milwaukee)-", - "to_node": "fiber (Milwaukee \u2192 Minneapolis)-" + "from_node": "roadm Milwaukee", + "to_node": "fiber (Milwaukee → Chicago)-" }, { - "from_node": "fiber (Minneapolis \u2192 Milwaukee)-", - "to_node": "fiber (Milwaukee \u2192 Chicago)-" + "from_node": "fiber (Chicago → Milwaukee)-", + "to_node": "roadm Milwaukee" + }, + { + "from_node": "roadm Milwaukee", + "to_node": "fiber (Milwaukee → Minneapolis)-" + }, + { + "from_node": "fiber (Minneapolis → Milwaukee)-", + "to_node": "roadm Milwaukee" }, { "from_node": "roadm Minneapolis", - "to_node": "fiber (Minneapolis \u2192 Bismarck)-" + "to_node": "fiber (Minneapolis → Bismarck)-" }, { - "from_node": "fiber (Bismarck \u2192 Minneapolis)-", + "from_node": "fiber (Bismarck → Minneapolis)-", "to_node": "roadm Minneapolis" }, { "from_node": "roadm Minneapolis", - "to_node": "fiber (Minneapolis \u2192 Milwaukee)-" + "to_node": "fiber (Minneapolis → Milwaukee)-" }, { - "from_node": "fiber (Milwaukee \u2192 Minneapolis)-", + "from_node": "fiber (Milwaukee → Minneapolis)-", "to_node": "roadm Minneapolis" }, { "from_node": "roadm Minneapolis", - "to_node": "fiber (Minneapolis \u2192 Omaha)-" + "to_node": "fiber (Minneapolis → Omaha)-" }, { - "from_node": "fiber (Omaha \u2192 Minneapolis)-", + "from_node": "fiber (Omaha → Minneapolis)-", "to_node": "roadm Minneapolis" }, { "from_node": "roadm Nashville", - "to_node": "fiber (Nashville \u2192 Birmingham)-" + "to_node": "fiber (Nashville → Birmingham)-" }, { - "from_node": "fiber (Birmingham \u2192 Nashville)-", + "from_node": "fiber (Birmingham → Nashville)-", "to_node": "roadm Nashville" }, { "from_node": "roadm Nashville", - "to_node": "fiber (Nashville \u2192 Louisville)-" + "to_node": "fiber (Nashville → Louisville)-" }, { - "from_node": "fiber (Louisville \u2192 Nashville)-", + "from_node": "fiber (Louisville → Nashville)-", "to_node": "roadm Nashville" }, { "from_node": "roadm Nashville", - "to_node": "fiber (Nashville \u2192 Memphis)-" + "to_node": "fiber (Nashville → Memphis)-" }, { - "from_node": "fiber (Memphis \u2192 Nashville)-", + "from_node": "fiber (Memphis → Nashville)-", "to_node": "roadm Nashville" }, { "from_node": "roadm New_Orleans", - "to_node": "fiber (New_Orleans \u2192 Baton_Rouge)-" + "to_node": "fiber (New_Orleans → Baton_Rouge)-" }, { - "from_node": "fiber (Baton_Rouge \u2192 New_Orleans)-", + "from_node": "fiber (Baton_Rouge → New_Orleans)-", "to_node": "roadm New_Orleans" }, { "from_node": "roadm New_Orleans", - "to_node": "fiber (New_Orleans \u2192 Birmingham)-" + "to_node": "fiber (New_Orleans → Birmingham)-" }, { - "from_node": "fiber (Birmingham \u2192 New_Orleans)-", + "from_node": "fiber (Birmingham → New_Orleans)-", "to_node": "roadm New_Orleans" }, { "from_node": "roadm New_Orleans", - "to_node": "fiber (New_Orleans \u2192 Tallahassee)-" + "to_node": "fiber (New_Orleans → Tallahassee)-" }, { - "from_node": "fiber (Tallahassee \u2192 New_Orleans)-", + "from_node": "fiber (Tallahassee → New_Orleans)-", "to_node": "roadm New_Orleans" }, { "from_node": "roadm New_York", - "to_node": "fiber (New_York \u2192 Amsterdam)-" + "to_node": "fiber (New_York → Amsterdam)-" }, { - "from_node": "fiber (Amsterdam \u2192 New_York)-", + "from_node": "fiber (Amsterdam → New_York)-", "to_node": "roadm New_York" }, { "from_node": "roadm New_York", - "to_node": "fiber (New_York \u2192 Long_Island)-" + "to_node": "fiber (New_York → Long_Island)-" }, { - "from_node": "fiber (Long_Island \u2192 New_York)-", + "from_node": "fiber (Long_Island → New_York)-", "to_node": "roadm New_York" }, { "from_node": "roadm New_York", - "to_node": "fiber (New_York \u2192 Newark)-" + "to_node": "fiber (New_York → Newark)-" }, { - "from_node": "fiber (Newark \u2192 New_York)-", + "from_node": "fiber (Newark → New_York)-", "to_node": "roadm New_York" }, { "from_node": "roadm New_York", - "to_node": "fiber (New_York \u2192 Scranton)-" + "to_node": "fiber (New_York → Scranton)-" }, { - "from_node": "fiber (Scranton \u2192 New_York)-", + "from_node": "fiber (Scranton → New_York)-", "to_node": "roadm New_York" }, { "from_node": "roadm New_York", - "to_node": "fiber (New_York \u2192 Wilmington)-" + "to_node": "fiber (New_York → Wilmington)-" }, { - "from_node": "fiber (Wilmington \u2192 New_York)-", + "from_node": "fiber (Wilmington → New_York)-", "to_node": "roadm New_York" }, { - "from_node": "fiber (New_York \u2192 Newark)-", - "to_node": "fiber (Newark \u2192 Philadelphia)-" + "from_node": "roadm Newark", + "to_node": "fiber (Newark → New_York)-" }, { - "from_node": "fiber (Philadelphia \u2192 Newark)-", - "to_node": "fiber (Newark \u2192 New_York)-" + "from_node": "fiber (New_York → Newark)-", + "to_node": "roadm Newark" }, { - "from_node": "fiber (Raleigh \u2192 Norfolk)-", - "to_node": "fiber (Norfolk \u2192 Wilmington)-" + "from_node": "roadm Newark", + "to_node": "fiber (Newark → Philadelphia)-" }, { - "from_node": "fiber (Wilmington \u2192 Norfolk)-", - "to_node": "fiber (Norfolk \u2192 Raleigh)-" + "from_node": "fiber (Philadelphia → Newark)-", + "to_node": "roadm Newark" + }, + { + "from_node": "roadm Norfolk", + "to_node": "fiber (Norfolk → Raleigh)-" + }, + { + "from_node": "fiber (Raleigh → Norfolk)-", + "to_node": "roadm Norfolk" + }, + { + "from_node": "roadm Norfolk", + "to_node": "fiber (Norfolk → Wilmington)-" + }, + { + "from_node": "fiber (Wilmington → Norfolk)-", + "to_node": "roadm Norfolk" }, { "from_node": "roadm Oakland", - "to_node": "fiber (Oakland \u2192 Fresno)-" + "to_node": "fiber (Oakland → Fresno)-" }, { - "from_node": "fiber (Fresno \u2192 Oakland)-", + "from_node": "fiber (Fresno → Oakland)-", "to_node": "roadm Oakland" }, { "from_node": "roadm Oakland", - "to_node": "fiber (Oakland \u2192 Sacramento)-" + "to_node": "fiber (Oakland → Sacramento)-" }, { - "from_node": "fiber (Sacramento \u2192 Oakland)-", + "from_node": "fiber (Sacramento → Oakland)-", "to_node": "roadm Oakland" }, { "from_node": "roadm Oakland", - "to_node": "fiber (Oakland \u2192 Salt_Lake_City)-" + "to_node": "fiber (Oakland → Salt_Lake_City)-" }, { - "from_node": "fiber (Salt_Lake_City \u2192 Oakland)-", + "from_node": "fiber (Salt_Lake_City → Oakland)-", "to_node": "roadm Oakland" }, { "from_node": "roadm Oakland", - "to_node": "fiber (Oakland \u2192 San_Francisco)-" + "to_node": "fiber (Oakland → San_Francisco)-" }, { - "from_node": "fiber (San_Francisco \u2192 Oakland)-", + "from_node": "fiber (San_Francisco → Oakland)-", "to_node": "roadm Oakland" }, { "from_node": "roadm Oakland", - "to_node": "fiber (Oakland \u2192 Taipei)-" + "to_node": "fiber (Oakland → Taipei)-" }, { - "from_node": "fiber (Taipei \u2192 Oakland)-", + "from_node": "fiber (Taipei → Oakland)-", "to_node": "roadm Oakland" }, { - "from_node": "fiber (Dallas \u2192 Oklahoma_City)-", - "to_node": "fiber (Oklahoma_City \u2192 Tulsa)-" + "from_node": "roadm Oklahoma_City", + "to_node": "fiber (Oklahoma_City → Dallas)-" }, { - "from_node": "fiber (Tulsa \u2192 Oklahoma_City)-", - "to_node": "fiber (Oklahoma_City \u2192 Dallas)-" + "from_node": "fiber (Dallas → Oklahoma_City)-", + "to_node": "roadm Oklahoma_City" + }, + { + "from_node": "roadm Oklahoma_City", + "to_node": "fiber (Oklahoma_City → Tulsa)-" + }, + { + "from_node": "fiber (Tulsa → Oklahoma_City)-", + "to_node": "roadm Oklahoma_City" }, { "from_node": "roadm Omaha", - "to_node": "fiber (Omaha \u2192 Denver)-" + "to_node": "fiber (Omaha → Denver)-" }, { - "from_node": "fiber (Denver \u2192 Omaha)-", + "from_node": "fiber (Denver → Omaha)-", "to_node": "roadm Omaha" }, { "from_node": "roadm Omaha", - "to_node": "fiber (Omaha \u2192 Kansas_City)-" + "to_node": "fiber (Omaha → Kansas_City)-" }, { - "from_node": "fiber (Kansas_City \u2192 Omaha)-", + "from_node": "fiber (Kansas_City → Omaha)-", "to_node": "roadm Omaha" }, { "from_node": "roadm Omaha", - "to_node": "fiber (Omaha \u2192 Minneapolis)-" + "to_node": "fiber (Omaha → Minneapolis)-" }, { - "from_node": "fiber (Minneapolis \u2192 Omaha)-", + "from_node": "fiber (Minneapolis → Omaha)-", "to_node": "roadm Omaha" }, { - "from_node": "fiber (Jacksonville \u2192 Orlando)-", - "to_node": "fiber (Orlando \u2192 West_Palm_Beach)-" + "from_node": "roadm Orlando", + "to_node": "fiber (Orlando → Jacksonville)-" }, { - "from_node": "fiber (West_Palm_Beach \u2192 Orlando)-", - "to_node": "fiber (Orlando \u2192 Jacksonville)-" + "from_node": "fiber (Jacksonville → Orlando)-", + "to_node": "roadm Orlando" + }, + { + "from_node": "roadm Orlando", + "to_node": "fiber (Orlando → West_Palm_Beach)-" + }, + { + "from_node": "fiber (West_Palm_Beach → Orlando)-", + "to_node": "roadm Orlando" }, { "from_node": "roadm Philadelphia", - "to_node": "fiber (Philadelphia \u2192 Baltimore)-" + "to_node": "fiber (Philadelphia → Baltimore)-" }, { - "from_node": "fiber (Baltimore \u2192 Philadelphia)-", + "from_node": "fiber (Baltimore → Philadelphia)-", "to_node": "roadm Philadelphia" }, { "from_node": "roadm Philadelphia", - "to_node": "fiber (Philadelphia \u2192 Newark)-" + "to_node": "fiber (Philadelphia → Newark)-" }, { - "from_node": "fiber (Newark \u2192 Philadelphia)-", + "from_node": "fiber (Newark → Philadelphia)-", "to_node": "roadm Philadelphia" }, { "from_node": "roadm Philadelphia", - "to_node": "fiber (Philadelphia \u2192 Scranton)-" + "to_node": "fiber (Philadelphia → Scranton)-" }, { - "from_node": "fiber (Scranton \u2192 Philadelphia)-", + "from_node": "fiber (Scranton → Philadelphia)-", "to_node": "roadm Philadelphia" }, { "from_node": "roadm Phoenix", - "to_node": "fiber (Phoenix \u2192 Las_Vegas)-" + "to_node": "fiber (Phoenix → Las_Vegas)-" }, { - "from_node": "fiber (Las_Vegas \u2192 Phoenix)-", + "from_node": "fiber (Las_Vegas → Phoenix)-", "to_node": "roadm Phoenix" }, { "from_node": "roadm Phoenix", - "to_node": "fiber (Phoenix \u2192 San_Diego)-" + "to_node": "fiber (Phoenix → San_Diego)-" }, { - "from_node": "fiber (San_Diego \u2192 Phoenix)-", + "from_node": "fiber (San_Diego → Phoenix)-", "to_node": "roadm Phoenix" }, { "from_node": "roadm Phoenix", - "to_node": "fiber (Phoenix \u2192 Tucson)-" + "to_node": "fiber (Phoenix → Tucson)-" }, { - "from_node": "fiber (Tucson \u2192 Phoenix)-", + "from_node": "fiber (Tucson → Phoenix)-", "to_node": "roadm Phoenix" }, { "from_node": "roadm Pittsburgh", - "to_node": "fiber (Pittsburgh \u2192 Baltimore)-" + "to_node": "fiber (Pittsburgh → Baltimore)-" }, { - "from_node": "fiber (Baltimore \u2192 Pittsburgh)-", + "from_node": "fiber (Baltimore → Pittsburgh)-", "to_node": "roadm Pittsburgh" }, { "from_node": "roadm Pittsburgh", - "to_node": "fiber (Pittsburgh \u2192 Columbus)-" + "to_node": "fiber (Pittsburgh → Columbus)-" }, { - "from_node": "fiber (Columbus \u2192 Pittsburgh)-", + "from_node": "fiber (Columbus → Pittsburgh)-", "to_node": "roadm Pittsburgh" }, { "from_node": "roadm Pittsburgh", - "to_node": "fiber (Pittsburgh \u2192 Scranton)-" + "to_node": "fiber (Pittsburgh → Scranton)-" }, { - "from_node": "fiber (Scranton \u2192 Pittsburgh)-", + "from_node": "fiber (Scranton → Pittsburgh)-", "to_node": "roadm Pittsburgh" }, { "from_node": "roadm Portland", - "to_node": "fiber (Portland \u2192 Sacramento)-" + "to_node": "fiber (Portland → Sacramento)-" }, { - "from_node": "fiber (Sacramento \u2192 Portland)-", + "from_node": "fiber (Sacramento → Portland)-", "to_node": "roadm Portland" }, { "from_node": "roadm Portland", - "to_node": "fiber (Portland \u2192 Salt_Lake_City)-" + "to_node": "fiber (Portland → Salt_Lake_City)-" }, { - "from_node": "fiber (Salt_Lake_City \u2192 Portland)-", + "from_node": "fiber (Salt_Lake_City → Portland)-", "to_node": "roadm Portland" }, { "from_node": "roadm Portland", - "to_node": "fiber (Portland \u2192 Seattle)-" + "to_node": "fiber (Portland → Seattle)-" }, { - "from_node": "fiber (Seattle \u2192 Portland)-", + "from_node": "fiber (Seattle → Portland)-", "to_node": "roadm Portland" }, { "from_node": "roadm Portland", - "to_node": "fiber (Portland \u2192 Tokyo)-" + "to_node": "fiber (Portland → Tokyo)-" }, { - "from_node": "fiber (Tokyo \u2192 Portland)-", + "from_node": "fiber (Tokyo → Portland)-", "to_node": "roadm Portland" }, { - "from_node": "fiber (Boston \u2192 Providence)-", - "to_node": "fiber (Providence \u2192 Hartford)-" + "from_node": "roadm Providence", + "to_node": "fiber (Providence → Boston)-" }, { - "from_node": "fiber (Hartford \u2192 Providence)-", - "to_node": "fiber (Providence \u2192 Boston)-" + "from_node": "fiber (Boston → Providence)-", + "to_node": "roadm Providence" + }, + { + "from_node": "roadm Providence", + "to_node": "fiber (Providence → Hartford)-" + }, + { + "from_node": "fiber (Hartford → Providence)-", + "to_node": "roadm Providence" }, { "from_node": "roadm Raleigh", - "to_node": "fiber (Raleigh \u2192 Charleston)-" + "to_node": "fiber (Raleigh → Charleston)-" }, { - "from_node": "fiber (Charleston \u2192 Raleigh)-", + "from_node": "fiber (Charleston → Raleigh)-", "to_node": "roadm Raleigh" }, { "from_node": "roadm Raleigh", - "to_node": "fiber (Raleigh \u2192 Greensboro)-" + "to_node": "fiber (Raleigh → Greensboro)-" }, { - "from_node": "fiber (Greensboro \u2192 Raleigh)-", + "from_node": "fiber (Greensboro → Raleigh)-", "to_node": "roadm Raleigh" }, { "from_node": "roadm Raleigh", - "to_node": "fiber (Raleigh \u2192 Norfolk)-" + "to_node": "fiber (Raleigh → Norfolk)-" }, { - "from_node": "fiber (Norfolk \u2192 Raleigh)-", + "from_node": "fiber (Norfolk → Raleigh)-", "to_node": "roadm Raleigh" }, { - "from_node": "fiber (Greensboro \u2192 Richmond)-", - "to_node": "fiber (Richmond \u2192 Washington_DC)-" + "from_node": "roadm Richmond", + "to_node": "fiber (Richmond → Greensboro)-" }, { - "from_node": "fiber (Washington_DC \u2192 Richmond)-", - "to_node": "fiber (Richmond \u2192 Greensboro)-" + "from_node": "fiber (Greensboro → Richmond)-", + "to_node": "roadm Richmond" }, { - "from_node": "fiber (Buffalo \u2192 Rochester)-", - "to_node": "fiber (Rochester \u2192 Syracuse)-" + "from_node": "roadm Richmond", + "to_node": "fiber (Richmond → Washington_DC)-" }, { - "from_node": "fiber (Syracuse \u2192 Rochester)-", - "to_node": "fiber (Rochester \u2192 Buffalo)-" + "from_node": "fiber (Washington_DC → Richmond)-", + "to_node": "roadm Richmond" }, { - "from_node": "fiber (Oakland \u2192 Sacramento)-", - "to_node": "fiber (Sacramento \u2192 Portland)-" + "from_node": "roadm Rochester", + "to_node": "fiber (Rochester → Buffalo)-" }, { - "from_node": "fiber (Portland \u2192 Sacramento)-", - "to_node": "fiber (Sacramento \u2192 Oakland)-" + "from_node": "fiber (Buffalo → Rochester)-", + "to_node": "roadm Rochester" + }, + { + "from_node": "roadm Rochester", + "to_node": "fiber (Rochester → Syracuse)-" + }, + { + "from_node": "fiber (Syracuse → Rochester)-", + "to_node": "roadm Rochester" + }, + { + "from_node": "roadm Sacramento", + "to_node": "fiber (Sacramento → Oakland)-" + }, + { + "from_node": "fiber (Oakland → Sacramento)-", + "to_node": "roadm Sacramento" + }, + { + "from_node": "roadm Sacramento", + "to_node": "fiber (Sacramento → Portland)-" + }, + { + "from_node": "fiber (Portland → Sacramento)-", + "to_node": "roadm Sacramento" }, { "from_node": "roadm Salt_Lake_City", - "to_node": "fiber (Salt_Lake_City \u2192 Denver)-" + "to_node": "fiber (Salt_Lake_City → Denver)-" }, { - "from_node": "fiber (Denver \u2192 Salt_Lake_City)-", + "from_node": "fiber (Denver → Salt_Lake_City)-", "to_node": "roadm Salt_Lake_City" }, { "from_node": "roadm Salt_Lake_City", - "to_node": "fiber (Salt_Lake_City \u2192 Las_Vegas)-" + "to_node": "fiber (Salt_Lake_City → Las_Vegas)-" }, { - "from_node": "fiber (Las_Vegas \u2192 Salt_Lake_City)-", + "from_node": "fiber (Las_Vegas → Salt_Lake_City)-", "to_node": "roadm Salt_Lake_City" }, { "from_node": "roadm Salt_Lake_City", - "to_node": "fiber (Salt_Lake_City \u2192 Oakland)-" + "to_node": "fiber (Salt_Lake_City → Oakland)-" }, { - "from_node": "fiber (Oakland \u2192 Salt_Lake_City)-", + "from_node": "fiber (Oakland → Salt_Lake_City)-", "to_node": "roadm Salt_Lake_City" }, { "from_node": "roadm Salt_Lake_City", - "to_node": "fiber (Salt_Lake_City \u2192 Portland)-" + "to_node": "fiber (Salt_Lake_City → Portland)-" }, { - "from_node": "fiber (Portland \u2192 Salt_Lake_City)-", + "from_node": "fiber (Portland → Salt_Lake_City)-", "to_node": "roadm Salt_Lake_City" }, { - "from_node": "fiber (Austin \u2192 San_Antonio)-", - "to_node": "fiber (San_Antonio \u2192 El_Paso)-" + "from_node": "roadm San_Antonio", + "to_node": "fiber (San_Antonio → Austin)-" }, { - "from_node": "fiber (El_Paso \u2192 San_Antonio)-", - "to_node": "fiber (San_Antonio \u2192 Austin)-" + "from_node": "fiber (Austin → San_Antonio)-", + "to_node": "roadm San_Antonio" }, { - "from_node": "fiber (Los_Angeles \u2192 San_Diego)-", - "to_node": "fiber (San_Diego \u2192 Phoenix)-" + "from_node": "roadm San_Antonio", + "to_node": "fiber (San_Antonio → El_Paso)-" }, { - "from_node": "fiber (Phoenix \u2192 San_Diego)-", - "to_node": "fiber (San_Diego \u2192 Los_Angeles)-" + "from_node": "fiber (El_Paso → San_Antonio)-", + "to_node": "roadm San_Antonio" }, { - "from_node": "fiber (Oakland \u2192 San_Francisco)-", - "to_node": "fiber (San_Francisco \u2192 San_Jose)-" + "from_node": "roadm San_Diego", + "to_node": "fiber (San_Diego → Los_Angeles)-" }, { - "from_node": "fiber (San_Jose \u2192 San_Francisco)-", - "to_node": "fiber (San_Francisco \u2192 Oakland)-" + "from_node": "fiber (Los_Angeles → San_Diego)-", + "to_node": "roadm San_Diego" }, { - "from_node": "fiber (San_Francisco \u2192 San_Jose)-", - "to_node": "fiber (San_Jose \u2192 Santa_Barbara)-" + "from_node": "roadm San_Diego", + "to_node": "fiber (San_Diego → Phoenix)-" }, { - "from_node": "fiber (Santa_Barbara \u2192 San_Jose)-", - "to_node": "fiber (San_Jose \u2192 San_Francisco)-" + "from_node": "fiber (Phoenix → San_Diego)-", + "to_node": "roadm San_Diego" }, { - "from_node": "fiber (Los_Angeles \u2192 Santa_Barbara)-", - "to_node": "fiber (Santa_Barbara \u2192 San_Jose)-" + "from_node": "roadm San_Francisco", + "to_node": "fiber (San_Francisco → Oakland)-" }, { - "from_node": "fiber (San_Jose \u2192 Santa_Barbara)-", - "to_node": "fiber (Santa_Barbara \u2192 Los_Angeles)-" + "from_node": "fiber (Oakland → San_Francisco)-", + "to_node": "roadm San_Francisco" + }, + { + "from_node": "roadm San_Francisco", + "to_node": "fiber (San_Francisco → San_Jose)-" + }, + { + "from_node": "fiber (San_Jose → San_Francisco)-", + "to_node": "roadm San_Francisco" + }, + { + "from_node": "roadm San_Jose", + "to_node": "fiber (San_Jose → San_Francisco)-" + }, + { + "from_node": "fiber (San_Francisco → San_Jose)-", + "to_node": "roadm San_Jose" + }, + { + "from_node": "roadm San_Jose", + "to_node": "fiber (San_Jose → Santa_Barbara)-" + }, + { + "from_node": "fiber (Santa_Barbara → San_Jose)-", + "to_node": "roadm San_Jose" + }, + { + "from_node": "roadm Santa_Barbara", + "to_node": "fiber (Santa_Barbara → Los_Angeles)-" + }, + { + "from_node": "fiber (Los_Angeles → Santa_Barbara)-", + "to_node": "roadm Santa_Barbara" + }, + { + "from_node": "roadm Santa_Barbara", + "to_node": "fiber (Santa_Barbara → San_Jose)-" + }, + { + "from_node": "fiber (San_Jose → Santa_Barbara)-", + "to_node": "roadm Santa_Barbara" }, { "from_node": "roadm Scranton", - "to_node": "fiber (Scranton \u2192 New_York)-" + "to_node": "fiber (Scranton → New_York)-" }, { - "from_node": "fiber (New_York \u2192 Scranton)-", + "from_node": "fiber (New_York → Scranton)-", "to_node": "roadm Scranton" }, { "from_node": "roadm Scranton", - "to_node": "fiber (Scranton \u2192 Philadelphia)-" + "to_node": "fiber (Scranton → Philadelphia)-" }, { - "from_node": "fiber (Philadelphia \u2192 Scranton)-", + "from_node": "fiber (Philadelphia → Scranton)-", "to_node": "roadm Scranton" }, { "from_node": "roadm Scranton", - "to_node": "fiber (Scranton \u2192 Pittsburgh)-" + "to_node": "fiber (Scranton → Pittsburgh)-" }, { - "from_node": "fiber (Pittsburgh \u2192 Scranton)-", + "from_node": "fiber (Pittsburgh → Scranton)-", "to_node": "roadm Scranton" }, { "from_node": "roadm Scranton", - "to_node": "fiber (Scranton \u2192 Syracuse)-" + "to_node": "fiber (Scranton → Syracuse)-" }, { - "from_node": "fiber (Syracuse \u2192 Scranton)-", + "from_node": "fiber (Syracuse → Scranton)-", "to_node": "roadm Scranton" }, { - "from_node": "fiber (Portland \u2192 Seattle)-", - "to_node": "fiber (Seattle \u2192 Spokane)-" + "from_node": "roadm Seattle", + "to_node": "fiber (Seattle → Portland)-" }, { - "from_node": "fiber (Spokane \u2192 Seattle)-", - "to_node": "fiber (Seattle \u2192 Portland)-" + "from_node": "fiber (Portland → Seattle)-", + "to_node": "roadm Seattle" }, { - "from_node": "fiber (Billings \u2192 Spokane)-", - "to_node": "fiber (Spokane \u2192 Seattle)-" + "from_node": "roadm Seattle", + "to_node": "fiber (Seattle → Spokane)-" }, { - "from_node": "fiber (Seattle \u2192 Spokane)-", - "to_node": "fiber (Spokane \u2192 Billings)-" + "from_node": "fiber (Spokane → Seattle)-", + "to_node": "roadm Seattle" }, { - "from_node": "fiber (Chicago \u2192 Springfield)-", - "to_node": "fiber (Springfield \u2192 St_Louis)-" + "from_node": "roadm Spokane", + "to_node": "fiber (Spokane → Billings)-" }, { - "from_node": "fiber (St_Louis \u2192 Springfield)-", - "to_node": "fiber (Springfield \u2192 Chicago)-" + "from_node": "fiber (Billings → Spokane)-", + "to_node": "roadm Spokane" + }, + { + "from_node": "roadm Spokane", + "to_node": "fiber (Spokane → Seattle)-" + }, + { + "from_node": "fiber (Seattle → Spokane)-", + "to_node": "roadm Spokane" + }, + { + "from_node": "roadm Springfield", + "to_node": "fiber (Springfield → Chicago)-" + }, + { + "from_node": "fiber (Chicago → Springfield)-", + "to_node": "roadm Springfield" + }, + { + "from_node": "roadm Springfield", + "to_node": "fiber (Springfield → St_Louis)-" + }, + { + "from_node": "fiber (St_Louis → Springfield)-", + "to_node": "roadm Springfield" }, { "from_node": "roadm St_Louis", - "to_node": "fiber (St_Louis \u2192 Kansas_City)-" + "to_node": "fiber (St_Louis → Kansas_City)-" }, { - "from_node": "fiber (Kansas_City \u2192 St_Louis)-", + "from_node": "fiber (Kansas_City → St_Louis)-", "to_node": "roadm St_Louis" }, { "from_node": "roadm St_Louis", - "to_node": "fiber (St_Louis \u2192 Louisville)-" + "to_node": "fiber (St_Louis → Louisville)-" }, { - "from_node": "fiber (Louisville \u2192 St_Louis)-", + "from_node": "fiber (Louisville → St_Louis)-", "to_node": "roadm St_Louis" }, { "from_node": "roadm St_Louis", - "to_node": "fiber (St_Louis \u2192 Springfield)-" + "to_node": "fiber (St_Louis → Springfield)-" }, { - "from_node": "fiber (Springfield \u2192 St_Louis)-", + "from_node": "fiber (Springfield → St_Louis)-", "to_node": "roadm St_Louis" }, { "from_node": "roadm Syracuse", - "to_node": "fiber (Syracuse \u2192 Albany)-" + "to_node": "fiber (Syracuse → Albany)-" }, { - "from_node": "fiber (Albany \u2192 Syracuse)-", + "from_node": "fiber (Albany → Syracuse)-", "to_node": "roadm Syracuse" }, { "from_node": "roadm Syracuse", - "to_node": "fiber (Syracuse \u2192 Rochester)-" + "to_node": "fiber (Syracuse → Rochester)-" }, { - "from_node": "fiber (Rochester \u2192 Syracuse)-", + "from_node": "fiber (Rochester → Syracuse)-", "to_node": "roadm Syracuse" }, { "from_node": "roadm Syracuse", - "to_node": "fiber (Syracuse \u2192 Scranton)-" + "to_node": "fiber (Syracuse → Scranton)-" }, { - "from_node": "fiber (Scranton \u2192 Syracuse)-", + "from_node": "fiber (Scranton → Syracuse)-", "to_node": "roadm Syracuse" }, { - "from_node": "fiber (New_Orleans \u2192 Tallahassee)-", - "to_node": "fiber (Tallahassee \u2192 Tampa)-" + "from_node": "roadm Tallahassee", + "to_node": "fiber (Tallahassee → New_Orleans)-" }, { - "from_node": "fiber (Tampa \u2192 Tallahassee)-", - "to_node": "fiber (Tallahassee \u2192 New_Orleans)-" + "from_node": "fiber (New_Orleans → Tallahassee)-", + "to_node": "roadm Tallahassee" }, { - "from_node": "fiber (Miami \u2192 Tampa)-", - "to_node": "fiber (Tampa \u2192 Tallahassee)-" + "from_node": "roadm Tallahassee", + "to_node": "fiber (Tallahassee → Tampa)-" }, { - "from_node": "fiber (Tallahassee \u2192 Tampa)-", - "to_node": "fiber (Tampa \u2192 Miami)-" + "from_node": "fiber (Tampa → Tallahassee)-", + "to_node": "roadm Tallahassee" }, { - "from_node": "fiber (Cleveland \u2192 Toledo)-", - "to_node": "fiber (Toledo \u2192 Detroit)-" + "from_node": "roadm Tampa", + "to_node": "fiber (Tampa → Miami)-" }, { - "from_node": "fiber (Detroit \u2192 Toledo)-", - "to_node": "fiber (Toledo \u2192 Cleveland)-" + "from_node": "fiber (Miami → Tampa)-", + "to_node": "roadm Tampa" }, { - "from_node": "fiber (El_Paso \u2192 Tucson)-", - "to_node": "fiber (Tucson \u2192 Phoenix)-" + "from_node": "roadm Tampa", + "to_node": "fiber (Tampa → Tallahassee)-" }, { - "from_node": "fiber (Phoenix \u2192 Tucson)-", - "to_node": "fiber (Tucson \u2192 El_Paso)-" + "from_node": "fiber (Tallahassee → Tampa)-", + "to_node": "roadm Tampa" }, { - "from_node": "fiber (Kansas_City \u2192 Tulsa)-", - "to_node": "fiber (Tulsa \u2192 Oklahoma_City)-" + "from_node": "roadm Toledo", + "to_node": "fiber (Toledo → Cleveland)-" }, { - "from_node": "fiber (Oklahoma_City \u2192 Tulsa)-", - "to_node": "fiber (Tulsa \u2192 Kansas_City)-" + "from_node": "fiber (Cleveland → Toledo)-", + "to_node": "roadm Toledo" + }, + { + "from_node": "roadm Toledo", + "to_node": "fiber (Toledo → Detroit)-" + }, + { + "from_node": "fiber (Detroit → Toledo)-", + "to_node": "roadm Toledo" + }, + { + "from_node": "roadm Tucson", + "to_node": "fiber (Tucson → El_Paso)-" + }, + { + "from_node": "fiber (El_Paso → Tucson)-", + "to_node": "roadm Tucson" + }, + { + "from_node": "roadm Tucson", + "to_node": "fiber (Tucson → Phoenix)-" + }, + { + "from_node": "fiber (Phoenix → Tucson)-", + "to_node": "roadm Tucson" + }, + { + "from_node": "roadm Tulsa", + "to_node": "fiber (Tulsa → Kansas_City)-" + }, + { + "from_node": "fiber (Kansas_City → Tulsa)-", + "to_node": "roadm Tulsa" + }, + { + "from_node": "roadm Tulsa", + "to_node": "fiber (Tulsa → Oklahoma_City)-" + }, + { + "from_node": "fiber (Oklahoma_City → Tulsa)-", + "to_node": "roadm Tulsa" }, { "from_node": "roadm Washington_DC", - "to_node": "fiber (Washington_DC \u2192 Baltimore)-" + "to_node": "fiber (Washington_DC → Baltimore)-" }, { - "from_node": "fiber (Baltimore \u2192 Washington_DC)-", + "from_node": "fiber (Baltimore → Washington_DC)-", "to_node": "roadm Washington_DC" }, { "from_node": "roadm Washington_DC", - "to_node": "fiber (Washington_DC \u2192 Cincinnati)-" + "to_node": "fiber (Washington_DC → Cincinnati)-" }, { - "from_node": "fiber (Cincinnati \u2192 Washington_DC)-", + "from_node": "fiber (Cincinnati → Washington_DC)-", "to_node": "roadm Washington_DC" }, { "from_node": "roadm Washington_DC", - "to_node": "fiber (Washington_DC \u2192 London)-" + "to_node": "fiber (Washington_DC → London)-" }, { - "from_node": "fiber (London \u2192 Washington_DC)-", + "from_node": "fiber (London → Washington_DC)-", "to_node": "roadm Washington_DC" }, { "from_node": "roadm Washington_DC", - "to_node": "fiber (Washington_DC \u2192 Richmond)-" + "to_node": "fiber (Washington_DC → Richmond)-" }, { - "from_node": "fiber (Richmond \u2192 Washington_DC)-", + "from_node": "fiber (Richmond → Washington_DC)-", "to_node": "roadm Washington_DC" }, { - "from_node": "fiber (Miami \u2192 West_Palm_Beach)-", - "to_node": "fiber (West_Palm_Beach \u2192 Orlando)-" + "from_node": "roadm West_Palm_Beach", + "to_node": "fiber (West_Palm_Beach → Miami)-" }, { - "from_node": "fiber (Orlando \u2192 West_Palm_Beach)-", - "to_node": "fiber (West_Palm_Beach \u2192 Miami)-" + "from_node": "fiber (Miami → West_Palm_Beach)-", + "to_node": "roadm West_Palm_Beach" }, { - "from_node": "fiber (New_York \u2192 Wilmington)-", - "to_node": "fiber (Wilmington \u2192 Norfolk)-" + "from_node": "roadm West_Palm_Beach", + "to_node": "fiber (West_Palm_Beach → Orlando)-" }, { - "from_node": "fiber (Norfolk \u2192 Wilmington)-", - "to_node": "fiber (Wilmington \u2192 New_York)-" + "from_node": "fiber (Orlando → West_Palm_Beach)-", + "to_node": "roadm West_Palm_Beach" + }, + { + "from_node": "roadm Wilmington", + "to_node": "fiber (Wilmington → New_York)-" + }, + { + "from_node": "fiber (New_York → Wilmington)-", + "to_node": "roadm Wilmington" + }, + { + "from_node": "roadm Wilmington", + "to_node": "fiber (Wilmington → Norfolk)-" + }, + { + "from_node": "fiber (Norfolk → Wilmington)-", + "to_node": "roadm Wilmington" }, { "from_node": "roadm Amsterdam", - "to_node": "fiber (Amsterdam \u2192 Berlin)-" + "to_node": "fiber (Amsterdam → Berlin)-" }, { - "from_node": "fiber (Berlin \u2192 Amsterdam)-", + "from_node": "fiber (Berlin → Amsterdam)-", "to_node": "roadm Amsterdam" }, { "from_node": "roadm Amsterdam", - "to_node": "fiber (Amsterdam \u2192 Brussels)-" + "to_node": "fiber (Amsterdam → Brussels)-" }, { - "from_node": "fiber (Brussels \u2192 Amsterdam)-", + "from_node": "fiber (Brussels → Amsterdam)-", "to_node": "roadm Amsterdam" }, { "from_node": "roadm Amsterdam", - "to_node": "fiber (Amsterdam \u2192 Frankfurt)-" + "to_node": "fiber (Amsterdam → Frankfurt)-" }, { - "from_node": "fiber (Frankfurt \u2192 Amsterdam)-", + "from_node": "fiber (Frankfurt → Amsterdam)-", "to_node": "roadm Amsterdam" }, { "from_node": "roadm Amsterdam", - "to_node": "fiber (Amsterdam \u2192 New_York)-" + "to_node": "fiber (Amsterdam → New_York)-" }, { - "from_node": "fiber (New_York \u2192 Amsterdam)-", + "from_node": "fiber (New_York → Amsterdam)-", "to_node": "roadm Amsterdam" }, { - "from_node": "fiber (Amsterdam \u2192 Berlin)-", - "to_node": "fiber (Berlin \u2192 Warsaw)-" + "from_node": "roadm Berlin", + "to_node": "fiber (Berlin → Amsterdam)-" }, { - "from_node": "fiber (Warsaw \u2192 Berlin)-", - "to_node": "fiber (Berlin \u2192 Amsterdam)-" + "from_node": "fiber (Amsterdam → Berlin)-", + "to_node": "roadm Berlin" }, { - "from_node": "fiber (Amsterdam \u2192 Brussels)-", - "to_node": "fiber (Brussels \u2192 London)-" + "from_node": "roadm Berlin", + "to_node": "fiber (Berlin → Warsaw)-" }, { - "from_node": "fiber (London \u2192 Brussels)-", - "to_node": "fiber (Brussels \u2192 Amsterdam)-" + "from_node": "fiber (Warsaw → Berlin)-", + "to_node": "roadm Berlin" }, { - "from_node": "fiber (Istanbul \u2192 Bucharest)-", - "to_node": "fiber (Bucharest \u2192 Warsaw)-" + "from_node": "roadm Brussels", + "to_node": "fiber (Brussels → Amsterdam)-" }, { - "from_node": "fiber (Warsaw \u2192 Bucharest)-", - "to_node": "fiber (Bucharest \u2192 Istanbul)-" + "from_node": "fiber (Amsterdam → Brussels)-", + "to_node": "roadm Brussels" }, { - "from_node": "fiber (Amsterdam \u2192 Frankfurt)-", - "to_node": "fiber (Frankfurt \u2192 Vienna)-" + "from_node": "roadm Brussels", + "to_node": "fiber (Brussels → London)-" }, { - "from_node": "fiber (Vienna \u2192 Frankfurt)-", - "to_node": "fiber (Frankfurt \u2192 Amsterdam)-" + "from_node": "fiber (London → Brussels)-", + "to_node": "roadm Brussels" + }, + { + "from_node": "roadm Bucharest", + "to_node": "fiber (Bucharest → Istanbul)-" + }, + { + "from_node": "fiber (Istanbul → Bucharest)-", + "to_node": "roadm Bucharest" + }, + { + "from_node": "roadm Bucharest", + "to_node": "fiber (Bucharest → Warsaw)-" + }, + { + "from_node": "fiber (Warsaw → Bucharest)-", + "to_node": "roadm Bucharest" + }, + { + "from_node": "roadm Frankfurt", + "to_node": "fiber (Frankfurt → Amsterdam)-" + }, + { + "from_node": "fiber (Amsterdam → Frankfurt)-", + "to_node": "roadm Frankfurt" + }, + { + "from_node": "roadm Frankfurt", + "to_node": "fiber (Frankfurt → Vienna)-" + }, + { + "from_node": "fiber (Vienna → Frankfurt)-", + "to_node": "roadm Frankfurt" }, { "from_node": "roadm Istanbul", - "to_node": "fiber (Istanbul \u2192 Bucharest)-" + "to_node": "fiber (Istanbul → Bucharest)-" }, { - "from_node": "fiber (Bucharest \u2192 Istanbul)-", + "from_node": "fiber (Bucharest → Istanbul)-", "to_node": "roadm Istanbul" }, { "from_node": "roadm Istanbul", - "to_node": "fiber (Istanbul \u2192 Delhi)-" + "to_node": "fiber (Istanbul → Delhi)-" }, { - "from_node": "fiber (Delhi \u2192 Istanbul)-", + "from_node": "fiber (Delhi → Istanbul)-", "to_node": "roadm Istanbul" }, { "from_node": "roadm Istanbul", - "to_node": "fiber (Istanbul \u2192 Rome)-" + "to_node": "fiber (Istanbul → Rome)-" }, { - "from_node": "fiber (Rome \u2192 Istanbul)-", + "from_node": "fiber (Rome → Istanbul)-", "to_node": "roadm Istanbul" }, { "from_node": "roadm London", - "to_node": "fiber (London \u2192 Brussels)-" + "to_node": "fiber (London → Brussels)-" }, { - "from_node": "fiber (Brussels \u2192 London)-", + "from_node": "fiber (Brussels → London)-", "to_node": "roadm London" }, { "from_node": "roadm London", - "to_node": "fiber (London \u2192 Paris)-" + "to_node": "fiber (London → Paris)-" }, { - "from_node": "fiber (Paris \u2192 London)-", + "from_node": "fiber (Paris → London)-", "to_node": "roadm London" }, { "from_node": "roadm London", - "to_node": "fiber (London \u2192 Washington_DC)-" + "to_node": "fiber (London → Washington_DC)-" }, { - "from_node": "fiber (Washington_DC \u2192 London)-", + "from_node": "fiber (Washington_DC → London)-", "to_node": "roadm London" }, { - "from_node": "fiber (Paris \u2192 Madrid)-", - "to_node": "fiber (Madrid \u2192 Zurich)-" + "from_node": "roadm Madrid", + "to_node": "fiber (Madrid → Paris)-" }, { - "from_node": "fiber (Zurich \u2192 Madrid)-", - "to_node": "fiber (Madrid \u2192 Paris)-" + "from_node": "fiber (Paris → Madrid)-", + "to_node": "roadm Madrid" + }, + { + "from_node": "roadm Madrid", + "to_node": "fiber (Madrid → Zurich)-" + }, + { + "from_node": "fiber (Zurich → Madrid)-", + "to_node": "roadm Madrid" }, { "from_node": "roadm Paris", - "to_node": "fiber (Paris \u2192 London)-" + "to_node": "fiber (Paris → London)-" }, { - "from_node": "fiber (London \u2192 Paris)-", + "from_node": "fiber (London → Paris)-", "to_node": "roadm Paris" }, { "from_node": "roadm Paris", - "to_node": "fiber (Paris \u2192 Madrid)-" + "to_node": "fiber (Paris → Madrid)-" }, { - "from_node": "fiber (Madrid \u2192 Paris)-", + "from_node": "fiber (Madrid → Paris)-", "to_node": "roadm Paris" }, { "from_node": "roadm Paris", - "to_node": "fiber (Paris \u2192 Miami)-" + "to_node": "fiber (Paris → Miami)-" }, { - "from_node": "fiber (Miami \u2192 Paris)-", + "from_node": "fiber (Miami → Paris)-", "to_node": "roadm Paris" }, { "from_node": "roadm Rome", - "to_node": "fiber (Rome \u2192 Istanbul)-" + "to_node": "fiber (Rome → Istanbul)-" }, { - "from_node": "fiber (Istanbul \u2192 Rome)-", + "from_node": "fiber (Istanbul → Rome)-", "to_node": "roadm Rome" }, { "from_node": "roadm Rome", - "to_node": "fiber (Rome \u2192 Mumbai)-" + "to_node": "fiber (Rome → Mumbai)-" }, { - "from_node": "fiber (Mumbai \u2192 Rome)-", + "from_node": "fiber (Mumbai → Rome)-", "to_node": "roadm Rome" }, { "from_node": "roadm Rome", - "to_node": "fiber (Rome \u2192 Vienna)-" + "to_node": "fiber (Rome → Vienna)-" }, { - "from_node": "fiber (Vienna \u2192 Rome)-", + "from_node": "fiber (Vienna → Rome)-", "to_node": "roadm Rome" }, { "from_node": "roadm Rome", - "to_node": "fiber (Rome \u2192 Zurich)-" + "to_node": "fiber (Rome → Zurich)-" }, { - "from_node": "fiber (Zurich \u2192 Rome)-", + "from_node": "fiber (Zurich → Rome)-", "to_node": "roadm Rome" }, { "from_node": "roadm Vienna", - "to_node": "fiber (Vienna \u2192 Frankfurt)-" + "to_node": "fiber (Vienna → Frankfurt)-" }, { - "from_node": "fiber (Frankfurt \u2192 Vienna)-", + "from_node": "fiber (Frankfurt → Vienna)-", "to_node": "roadm Vienna" }, { "from_node": "roadm Vienna", - "to_node": "fiber (Vienna \u2192 Rome)-" + "to_node": "fiber (Vienna → Rome)-" }, { - "from_node": "fiber (Rome \u2192 Vienna)-", + "from_node": "fiber (Rome → Vienna)-", "to_node": "roadm Vienna" }, { "from_node": "roadm Vienna", - "to_node": "fiber (Vienna \u2192 Warsaw)-" + "to_node": "fiber (Vienna → Warsaw)-" }, { - "from_node": "fiber (Warsaw \u2192 Vienna)-", + "from_node": "fiber (Warsaw → Vienna)-", "to_node": "roadm Vienna" }, { "from_node": "roadm Warsaw", - "to_node": "fiber (Warsaw \u2192 Berlin)-" + "to_node": "fiber (Warsaw → Berlin)-" }, { - "from_node": "fiber (Berlin \u2192 Warsaw)-", + "from_node": "fiber (Berlin → Warsaw)-", "to_node": "roadm Warsaw" }, { "from_node": "roadm Warsaw", - "to_node": "fiber (Warsaw \u2192 Bucharest)-" + "to_node": "fiber (Warsaw → Bucharest)-" }, { - "from_node": "fiber (Bucharest \u2192 Warsaw)-", + "from_node": "fiber (Bucharest → Warsaw)-", "to_node": "roadm Warsaw" }, { "from_node": "roadm Warsaw", - "to_node": "fiber (Warsaw \u2192 Vienna)-" + "to_node": "fiber (Warsaw → Vienna)-" }, { - "from_node": "fiber (Vienna \u2192 Warsaw)-", + "from_node": "fiber (Vienna → Warsaw)-", "to_node": "roadm Warsaw" }, { - "from_node": "fiber (Madrid \u2192 Zurich)-", - "to_node": "fiber (Zurich \u2192 Rome)-" + "from_node": "roadm Zurich", + "to_node": "fiber (Zurich → Madrid)-" }, { - "from_node": "fiber (Rome \u2192 Zurich)-", - "to_node": "fiber (Zurich \u2192 Madrid)-" + "from_node": "fiber (Madrid → Zurich)-", + "to_node": "roadm Zurich" }, { - "from_node": "fiber (Delhi \u2192 Bangkok)-", - "to_node": "fiber (Bangkok \u2192 Hong_Kong)-" + "from_node": "roadm Zurich", + "to_node": "fiber (Zurich → Rome)-" }, { - "from_node": "fiber (Hong_Kong \u2192 Bangkok)-", - "to_node": "fiber (Bangkok \u2192 Delhi)-" + "from_node": "fiber (Rome → Zurich)-", + "to_node": "roadm Zurich" }, { - "from_node": "fiber (Seoul \u2192 Beijing)-", - "to_node": "fiber (Beijing \u2192 Shanghai)-" + "from_node": "roadm Bangkok", + "to_node": "fiber (Bangkok → Delhi)-" }, { - "from_node": "fiber (Shanghai \u2192 Beijing)-", - "to_node": "fiber (Beijing \u2192 Seoul)-" + "from_node": "fiber (Delhi → Bangkok)-", + "to_node": "roadm Bangkok" + }, + { + "from_node": "roadm Bangkok", + "to_node": "fiber (Bangkok → Hong_Kong)-" + }, + { + "from_node": "fiber (Hong_Kong → Bangkok)-", + "to_node": "roadm Bangkok" + }, + { + "from_node": "roadm Beijing", + "to_node": "fiber (Beijing → Seoul)-" + }, + { + "from_node": "fiber (Seoul → Beijing)-", + "to_node": "roadm Beijing" + }, + { + "from_node": "roadm Beijing", + "to_node": "fiber (Beijing → Shanghai)-" + }, + { + "from_node": "fiber (Shanghai → Beijing)-", + "to_node": "roadm Beijing" }, { "from_node": "roadm Delhi", - "to_node": "fiber (Delhi \u2192 Bangkok)-" + "to_node": "fiber (Delhi → Bangkok)-" }, { - "from_node": "fiber (Bangkok \u2192 Delhi)-", + "from_node": "fiber (Bangkok → Delhi)-", "to_node": "roadm Delhi" }, { "from_node": "roadm Delhi", - "to_node": "fiber (Delhi \u2192 Istanbul)-" + "to_node": "fiber (Delhi → Istanbul)-" }, { - "from_node": "fiber (Istanbul \u2192 Delhi)-", + "from_node": "fiber (Istanbul → Delhi)-", "to_node": "roadm Delhi" }, { "from_node": "roadm Delhi", - "to_node": "fiber (Delhi \u2192 Mumbai)-" + "to_node": "fiber (Delhi → Mumbai)-" }, { - "from_node": "fiber (Mumbai \u2192 Delhi)-", + "from_node": "fiber (Mumbai → Delhi)-", "to_node": "roadm Delhi" }, { "from_node": "roadm Hong_Kong", - "to_node": "fiber (Hong_Kong \u2192 Bangkok)-" + "to_node": "fiber (Hong_Kong → Bangkok)-" }, { - "from_node": "fiber (Bangkok \u2192 Hong_Kong)-", + "from_node": "fiber (Bangkok → Hong_Kong)-", "to_node": "roadm Hong_Kong" }, { "from_node": "roadm Hong_Kong", - "to_node": "fiber (Hong_Kong \u2192 Shanghai)-" + "to_node": "fiber (Hong_Kong → Shanghai)-" }, { - "from_node": "fiber (Shanghai \u2192 Hong_Kong)-", + "from_node": "fiber (Shanghai → Hong_Kong)-", "to_node": "roadm Hong_Kong" }, { "from_node": "roadm Hong_Kong", - "to_node": "fiber (Hong_Kong \u2192 Sydney)-" + "to_node": "fiber (Hong_Kong → Sydney)-" }, { - "from_node": "fiber (Sydney \u2192 Hong_Kong)-", + "from_node": "fiber (Sydney → Hong_Kong)-", "to_node": "roadm Hong_Kong" }, { "from_node": "roadm Hong_Kong", - "to_node": "fiber (Hong_Kong \u2192 Taipei)-" + "to_node": "fiber (Hong_Kong → Taipei)-" }, { - "from_node": "fiber (Taipei \u2192 Hong_Kong)-", + "from_node": "fiber (Taipei → Hong_Kong)-", "to_node": "roadm Hong_Kong" }, { "from_node": "roadm Honolulu", - "to_node": "fiber (Honolulu \u2192 Los_Angeles)-" + "to_node": "fiber (Honolulu → Los_Angeles)-" }, { - "from_node": "fiber (Los_Angeles \u2192 Honolulu)-", + "from_node": "fiber (Los_Angeles → Honolulu)-", "to_node": "roadm Honolulu" }, { "from_node": "roadm Honolulu", - "to_node": "fiber (Honolulu \u2192 Sydney)-" + "to_node": "fiber (Honolulu → Sydney)-" }, { - "from_node": "fiber (Sydney \u2192 Honolulu)-", + "from_node": "fiber (Sydney → Honolulu)-", "to_node": "roadm Honolulu" }, { "from_node": "roadm Honolulu", - "to_node": "fiber (Honolulu \u2192 Taipei)-" + "to_node": "fiber (Honolulu → Taipei)-" }, { - "from_node": "fiber (Taipei \u2192 Honolulu)-", + "from_node": "fiber (Taipei → Honolulu)-", "to_node": "roadm Honolulu" }, { "from_node": "roadm Mumbai", - "to_node": "fiber (Mumbai \u2192 Delhi)-" + "to_node": "fiber (Mumbai → Delhi)-" }, { - "from_node": "fiber (Delhi \u2192 Mumbai)-", + "from_node": "fiber (Delhi → Mumbai)-", "to_node": "roadm Mumbai" }, { "from_node": "roadm Mumbai", - "to_node": "fiber (Mumbai \u2192 Rome)-" + "to_node": "fiber (Mumbai → Rome)-" }, { - "from_node": "fiber (Rome \u2192 Mumbai)-", + "from_node": "fiber (Rome → Mumbai)-", "to_node": "roadm Mumbai" }, { "from_node": "roadm Mumbai", - "to_node": "fiber (Mumbai \u2192 Singapore)-" + "to_node": "fiber (Mumbai → Singapore)-" }, { - "from_node": "fiber (Singapore \u2192 Mumbai)-", + "from_node": "fiber (Singapore → Mumbai)-", "to_node": "roadm Mumbai" }, { - "from_node": "fiber (Beijing \u2192 Seoul)-", - "to_node": "fiber (Seoul \u2192 Tokyo)-" + "from_node": "roadm Seoul", + "to_node": "fiber (Seoul → Beijing)-" }, { - "from_node": "fiber (Tokyo \u2192 Seoul)-", - "to_node": "fiber (Seoul \u2192 Beijing)-" + "from_node": "fiber (Beijing → Seoul)-", + "to_node": "roadm Seoul" }, { - "from_node": "fiber (Beijing \u2192 Shanghai)-", - "to_node": "fiber (Shanghai \u2192 Hong_Kong)-" + "from_node": "roadm Seoul", + "to_node": "fiber (Seoul → Tokyo)-" }, { - "from_node": "fiber (Hong_Kong \u2192 Shanghai)-", - "to_node": "fiber (Shanghai \u2192 Beijing)-" + "from_node": "fiber (Tokyo → Seoul)-", + "to_node": "roadm Seoul" }, { - "from_node": "fiber (Mumbai \u2192 Singapore)-", - "to_node": "fiber (Singapore \u2192 Sydney)-" + "from_node": "roadm Shanghai", + "to_node": "fiber (Shanghai → Beijing)-" }, { - "from_node": "fiber (Sydney \u2192 Singapore)-", - "to_node": "fiber (Singapore \u2192 Mumbai)-" + "from_node": "fiber (Beijing → Shanghai)-", + "to_node": "roadm Shanghai" + }, + { + "from_node": "roadm Shanghai", + "to_node": "fiber (Shanghai → Hong_Kong)-" + }, + { + "from_node": "fiber (Hong_Kong → Shanghai)-", + "to_node": "roadm Shanghai" + }, + { + "from_node": "roadm Singapore", + "to_node": "fiber (Singapore → Mumbai)-" + }, + { + "from_node": "fiber (Mumbai → Singapore)-", + "to_node": "roadm Singapore" + }, + { + "from_node": "roadm Singapore", + "to_node": "fiber (Singapore → Sydney)-" + }, + { + "from_node": "fiber (Sydney → Singapore)-", + "to_node": "roadm Singapore" }, { "from_node": "roadm Sydney", - "to_node": "fiber (Sydney \u2192 Hong_Kong)-" + "to_node": "fiber (Sydney → Hong_Kong)-" }, { - "from_node": "fiber (Hong_Kong \u2192 Sydney)-", + "from_node": "fiber (Hong_Kong → Sydney)-", "to_node": "roadm Sydney" }, { "from_node": "roadm Sydney", - "to_node": "fiber (Sydney \u2192 Honolulu)-" + "to_node": "fiber (Sydney → Honolulu)-" }, { - "from_node": "fiber (Honolulu \u2192 Sydney)-", + "from_node": "fiber (Honolulu → Sydney)-", "to_node": "roadm Sydney" }, { "from_node": "roadm Sydney", - "to_node": "fiber (Sydney \u2192 Singapore)-" + "to_node": "fiber (Sydney → Singapore)-" }, { - "from_node": "fiber (Singapore \u2192 Sydney)-", + "from_node": "fiber (Singapore → Sydney)-", "to_node": "roadm Sydney" }, { "from_node": "roadm Taipei", - "to_node": "fiber (Taipei \u2192 Hong_Kong)-" + "to_node": "fiber (Taipei → Hong_Kong)-" }, { - "from_node": "fiber (Hong_Kong \u2192 Taipei)-", + "from_node": "fiber (Hong_Kong → Taipei)-", "to_node": "roadm Taipei" }, { "from_node": "roadm Taipei", - "to_node": "fiber (Taipei \u2192 Honolulu)-" + "to_node": "fiber (Taipei → Honolulu)-" }, { - "from_node": "fiber (Honolulu \u2192 Taipei)-", + "from_node": "fiber (Honolulu → Taipei)-", "to_node": "roadm Taipei" }, { "from_node": "roadm Taipei", - "to_node": "fiber (Taipei \u2192 Oakland)-" + "to_node": "fiber (Taipei → Oakland)-" }, { - "from_node": "fiber (Oakland \u2192 Taipei)-", + "from_node": "fiber (Oakland → Taipei)-", "to_node": "roadm Taipei" }, { "from_node": "roadm Taipei", - "to_node": "fiber (Taipei \u2192 Tokyo)-" + "to_node": "fiber (Taipei → Tokyo)-" }, { - "from_node": "fiber (Tokyo \u2192 Taipei)-", + "from_node": "fiber (Tokyo → Taipei)-", "to_node": "roadm Taipei" }, { "from_node": "roadm Tokyo", - "to_node": "fiber (Tokyo \u2192 Portland)-" + "to_node": "fiber (Tokyo → Portland)-" }, { - "from_node": "fiber (Portland \u2192 Tokyo)-", + "from_node": "fiber (Portland → Tokyo)-", "to_node": "roadm Tokyo" }, { "from_node": "roadm Tokyo", - "to_node": "fiber (Tokyo \u2192 Seoul)-" + "to_node": "fiber (Tokyo → Seoul)-" }, { - "from_node": "fiber (Seoul \u2192 Tokyo)-", + "from_node": "fiber (Seoul → Tokyo)-", "to_node": "roadm Tokyo" }, { "from_node": "roadm Tokyo", - "to_node": "fiber (Tokyo \u2192 Taipei)-" + "to_node": "fiber (Tokyo → Taipei)-" }, { - "from_node": "fiber (Taipei \u2192 Tokyo)-", + "from_node": "fiber (Taipei → Tokyo)-", "to_node": "roadm Tokyo" }, + { + "from_node": "trx Abilene", + "to_node": "roadm Abilene" + }, + { + "from_node": "roadm Abilene", + "to_node": "trx Abilene" + }, + { + "from_node": "trx Albany", + "to_node": "roadm Albany" + }, + { + "from_node": "roadm Albany", + "to_node": "trx Albany" + }, { "from_node": "trx Albuquerque", "to_node": "roadm Albuquerque" @@ -7922,6 +9506,14 @@ "from_node": "roadm Atlanta", "to_node": "trx Atlanta" }, + { + "from_node": "trx Austin", + "to_node": "roadm Austin" + }, + { + "from_node": "roadm Austin", + "to_node": "trx Austin" + }, { "from_node": "trx Baltimore", "to_node": "roadm Baltimore" @@ -7930,6 +9522,14 @@ "from_node": "roadm Baltimore", "to_node": "trx Baltimore" }, + { + "from_node": "trx Baton_Rouge", + "to_node": "roadm Baton_Rouge" + }, + { + "from_node": "roadm Baton_Rouge", + "to_node": "trx Baton_Rouge" + }, { "from_node": "trx Billings", "to_node": "roadm Billings" @@ -7946,6 +9546,46 @@ "from_node": "roadm Birmingham", "to_node": "trx Birmingham" }, + { + "from_node": "trx Bismarck", + "to_node": "roadm Bismarck" + }, + { + "from_node": "roadm Bismarck", + "to_node": "trx Bismarck" + }, + { + "from_node": "trx Boston", + "to_node": "roadm Boston" + }, + { + "from_node": "roadm Boston", + "to_node": "trx Boston" + }, + { + "from_node": "trx Buffalo", + "to_node": "roadm Buffalo" + }, + { + "from_node": "roadm Buffalo", + "to_node": "trx Buffalo" + }, + { + "from_node": "trx Charleston", + "to_node": "roadm Charleston" + }, + { + "from_node": "roadm Charleston", + "to_node": "trx Charleston" + }, + { + "from_node": "trx Charlotte", + "to_node": "roadm Charlotte" + }, + { + "from_node": "roadm Charlotte", + "to_node": "trx Charlotte" + }, { "from_node": "trx Chicago", "to_node": "roadm Chicago" @@ -7994,6 +9634,14 @@ "from_node": "roadm Denver", "to_node": "trx Denver" }, + { + "from_node": "trx Detroit", + "to_node": "roadm Detroit" + }, + { + "from_node": "roadm Detroit", + "to_node": "trx Detroit" + }, { "from_node": "trx El_Paso", "to_node": "roadm El_Paso" @@ -8018,6 +9666,14 @@ "from_node": "roadm Greensboro", "to_node": "trx Greensboro" }, + { + "from_node": "trx Hartford", + "to_node": "roadm Hartford" + }, + { + "from_node": "roadm Hartford", + "to_node": "trx Hartford" + }, { "from_node": "trx Houston", "to_node": "roadm Houston" @@ -8050,6 +9706,22 @@ "from_node": "roadm Las_Vegas", "to_node": "trx Las_Vegas" }, + { + "from_node": "trx Little_Rock", + "to_node": "roadm Little_Rock" + }, + { + "from_node": "roadm Little_Rock", + "to_node": "trx Little_Rock" + }, + { + "from_node": "trx Long_Island", + "to_node": "roadm Long_Island" + }, + { + "from_node": "roadm Long_Island", + "to_node": "trx Long_Island" + }, { "from_node": "trx Los_Angeles", "to_node": "roadm Los_Angeles" @@ -8066,6 +9738,14 @@ "from_node": "roadm Louisville", "to_node": "trx Louisville" }, + { + "from_node": "trx Memphis", + "to_node": "roadm Memphis" + }, + { + "from_node": "roadm Memphis", + "to_node": "trx Memphis" + }, { "from_node": "trx Miami", "to_node": "roadm Miami" @@ -8074,6 +9754,14 @@ "from_node": "roadm Miami", "to_node": "trx Miami" }, + { + "from_node": "trx Milwaukee", + "to_node": "roadm Milwaukee" + }, + { + "from_node": "roadm Milwaukee", + "to_node": "trx Milwaukee" + }, { "from_node": "trx Minneapolis", "to_node": "roadm Minneapolis" @@ -8106,6 +9794,22 @@ "from_node": "roadm New_York", "to_node": "trx New_York" }, + { + "from_node": "trx Newark", + "to_node": "roadm Newark" + }, + { + "from_node": "roadm Newark", + "to_node": "trx Newark" + }, + { + "from_node": "trx Norfolk", + "to_node": "roadm Norfolk" + }, + { + "from_node": "roadm Norfolk", + "to_node": "trx Norfolk" + }, { "from_node": "trx Oakland", "to_node": "roadm Oakland" @@ -8114,6 +9818,14 @@ "from_node": "roadm Oakland", "to_node": "trx Oakland" }, + { + "from_node": "trx Oklahoma_City", + "to_node": "roadm Oklahoma_City" + }, + { + "from_node": "roadm Oklahoma_City", + "to_node": "trx Oklahoma_City" + }, { "from_node": "trx Omaha", "to_node": "roadm Omaha" @@ -8122,6 +9834,14 @@ "from_node": "roadm Omaha", "to_node": "trx Omaha" }, + { + "from_node": "trx Orlando", + "to_node": "roadm Orlando" + }, + { + "from_node": "roadm Orlando", + "to_node": "trx Orlando" + }, { "from_node": "trx Philadelphia", "to_node": "roadm Philadelphia" @@ -8154,6 +9874,14 @@ "from_node": "roadm Portland", "to_node": "trx Portland" }, + { + "from_node": "trx Providence", + "to_node": "roadm Providence" + }, + { + "from_node": "roadm Providence", + "to_node": "trx Providence" + }, { "from_node": "trx Raleigh", "to_node": "roadm Raleigh" @@ -8162,6 +9890,30 @@ "from_node": "roadm Raleigh", "to_node": "trx Raleigh" }, + { + "from_node": "trx Richmond", + "to_node": "roadm Richmond" + }, + { + "from_node": "roadm Richmond", + "to_node": "trx Richmond" + }, + { + "from_node": "trx Rochester", + "to_node": "roadm Rochester" + }, + { + "from_node": "roadm Rochester", + "to_node": "trx Rochester" + }, + { + "from_node": "trx Sacramento", + "to_node": "roadm Sacramento" + }, + { + "from_node": "roadm Sacramento", + "to_node": "trx Sacramento" + }, { "from_node": "trx Salt_Lake_City", "to_node": "roadm Salt_Lake_City" @@ -8170,6 +9922,46 @@ "from_node": "roadm Salt_Lake_City", "to_node": "trx Salt_Lake_City" }, + { + "from_node": "trx San_Antonio", + "to_node": "roadm San_Antonio" + }, + { + "from_node": "roadm San_Antonio", + "to_node": "trx San_Antonio" + }, + { + "from_node": "trx San_Diego", + "to_node": "roadm San_Diego" + }, + { + "from_node": "roadm San_Diego", + "to_node": "trx San_Diego" + }, + { + "from_node": "trx San_Francisco", + "to_node": "roadm San_Francisco" + }, + { + "from_node": "roadm San_Francisco", + "to_node": "trx San_Francisco" + }, + { + "from_node": "trx San_Jose", + "to_node": "roadm San_Jose" + }, + { + "from_node": "roadm San_Jose", + "to_node": "trx San_Jose" + }, + { + "from_node": "trx Santa_Barbara", + "to_node": "roadm Santa_Barbara" + }, + { + "from_node": "roadm Santa_Barbara", + "to_node": "trx Santa_Barbara" + }, { "from_node": "trx Scranton", "to_node": "roadm Scranton" @@ -8178,6 +9970,30 @@ "from_node": "roadm Scranton", "to_node": "trx Scranton" }, + { + "from_node": "trx Seattle", + "to_node": "roadm Seattle" + }, + { + "from_node": "roadm Seattle", + "to_node": "trx Seattle" + }, + { + "from_node": "trx Spokane", + "to_node": "roadm Spokane" + }, + { + "from_node": "roadm Spokane", + "to_node": "trx Spokane" + }, + { + "from_node": "trx Springfield", + "to_node": "roadm Springfield" + }, + { + "from_node": "roadm Springfield", + "to_node": "trx Springfield" + }, { "from_node": "trx St_Louis", "to_node": "roadm St_Louis" @@ -8194,6 +10010,46 @@ "from_node": "roadm Syracuse", "to_node": "trx Syracuse" }, + { + "from_node": "trx Tallahassee", + "to_node": "roadm Tallahassee" + }, + { + "from_node": "roadm Tallahassee", + "to_node": "trx Tallahassee" + }, + { + "from_node": "trx Tampa", + "to_node": "roadm Tampa" + }, + { + "from_node": "roadm Tampa", + "to_node": "trx Tampa" + }, + { + "from_node": "trx Toledo", + "to_node": "roadm Toledo" + }, + { + "from_node": "roadm Toledo", + "to_node": "trx Toledo" + }, + { + "from_node": "trx Tucson", + "to_node": "roadm Tucson" + }, + { + "from_node": "roadm Tucson", + "to_node": "trx Tucson" + }, + { + "from_node": "trx Tulsa", + "to_node": "roadm Tulsa" + }, + { + "from_node": "roadm Tulsa", + "to_node": "trx Tulsa" + }, { "from_node": "trx Washington_DC", "to_node": "roadm Washington_DC" @@ -8202,6 +10058,22 @@ "from_node": "roadm Washington_DC", "to_node": "trx Washington_DC" }, + { + "from_node": "trx West_Palm_Beach", + "to_node": "roadm West_Palm_Beach" + }, + { + "from_node": "roadm West_Palm_Beach", + "to_node": "trx West_Palm_Beach" + }, + { + "from_node": "trx Wilmington", + "to_node": "roadm Wilmington" + }, + { + "from_node": "roadm Wilmington", + "to_node": "trx Wilmington" + }, { "from_node": "trx Amsterdam", "to_node": "roadm Amsterdam" @@ -8210,6 +10082,38 @@ "from_node": "roadm Amsterdam", "to_node": "trx Amsterdam" }, + { + "from_node": "trx Berlin", + "to_node": "roadm Berlin" + }, + { + "from_node": "roadm Berlin", + "to_node": "trx Berlin" + }, + { + "from_node": "trx Brussels", + "to_node": "roadm Brussels" + }, + { + "from_node": "roadm Brussels", + "to_node": "trx Brussels" + }, + { + "from_node": "trx Bucharest", + "to_node": "roadm Bucharest" + }, + { + "from_node": "roadm Bucharest", + "to_node": "trx Bucharest" + }, + { + "from_node": "trx Frankfurt", + "to_node": "roadm Frankfurt" + }, + { + "from_node": "roadm Frankfurt", + "to_node": "trx Frankfurt" + }, { "from_node": "trx Istanbul", "to_node": "roadm Istanbul" @@ -8226,6 +10130,14 @@ "from_node": "roadm London", "to_node": "trx London" }, + { + "from_node": "trx Madrid", + "to_node": "roadm Madrid" + }, + { + "from_node": "roadm Madrid", + "to_node": "trx Madrid" + }, { "from_node": "trx Paris", "to_node": "roadm Paris" @@ -8258,6 +10170,30 @@ "from_node": "roadm Warsaw", "to_node": "trx Warsaw" }, + { + "from_node": "trx Zurich", + "to_node": "roadm Zurich" + }, + { + "from_node": "roadm Zurich", + "to_node": "trx Zurich" + }, + { + "from_node": "trx Bangkok", + "to_node": "roadm Bangkok" + }, + { + "from_node": "roadm Bangkok", + "to_node": "trx Bangkok" + }, + { + "from_node": "trx Beijing", + "to_node": "roadm Beijing" + }, + { + "from_node": "roadm Beijing", + "to_node": "trx Beijing" + }, { "from_node": "trx Delhi", "to_node": "roadm Delhi" @@ -8290,6 +10226,30 @@ "from_node": "roadm Mumbai", "to_node": "trx Mumbai" }, + { + "from_node": "trx Seoul", + "to_node": "roadm Seoul" + }, + { + "from_node": "roadm Seoul", + "to_node": "trx Seoul" + }, + { + "from_node": "trx Shanghai", + "to_node": "roadm Shanghai" + }, + { + "from_node": "roadm Shanghai", + "to_node": "trx Shanghai" + }, + { + "from_node": "trx Singapore", + "to_node": "roadm Singapore" + }, + { + "from_node": "roadm Singapore", + "to_node": "trx Singapore" + }, { "from_node": "trx Sydney", "to_node": "roadm Sydney" diff --git a/tests/data/eqpt_config.json b/tests/data/eqpt_config.json index b58362de..0877d6d2 100644 --- a/tests/data/eqpt_config.json +++ b/tests/data/eqpt_config.json @@ -66,7 +66,8 @@ ], "Roadms":[{ "gain_mode_default_loss": 20, - "power_mode_pref": -20 + "power_mode_pout_target": -20, + "add_drop_osnr": 100 }], "SI":[{ "f_min": 191.3e12, @@ -76,8 +77,8 @@ "power_dbm": 0, "power_range_db": [0,0.5,0.5], "roll_off": 0.15, - "OSNR": 15, - "bit_rate":100e9 + "tx_osnr": 100, + "sys_margins": 0 }], "Transceiver":[ { @@ -92,15 +93,41 @@ "baud_rate": 32e9, "OSNR": 11, "bit_rate": 100e9, - "roll_off": 0.15 + "roll_off": 0.15, + "tx_osnr": 100, + "min_spacing": 50e9, + "cost":1 }, { "format": "PS_SP64_2", "baud_rate": 64e9, "OSNR": 15, "bit_rate": 200e9, - "roll_off": 0.15 - } + "roll_off": 0.15, + "tx_osnr": 100, + "min_spacing": 75e9, + "cost":1 + }, + { + "format": "mode 1", + "baud_rate": 32e9, + "OSNR": 11, + "bit_rate": 100e9, + "roll_off": 0.15, + "tx_osnr": 100, + "min_spacing": 50e9, + "cost":1 + }, + { + "format": "mode 2", + "baud_rate": 64e9, + "OSNR": 15, + "bit_rate": 200e9, + "roll_off": 0.15, + "tx_osnr": 100, + "min_spacing": 75e9, + "cost":1 + } ] }, { @@ -115,7 +142,69 @@ "baud_rate": 32e9, "OSNR": 19, "bit_rate": 200e9, - "roll_off": 0.15 + "roll_off": 0.15, + "tx_osnr": 100, + "min_spacing": 50e9, + "cost":1 + } + ] + }, + { + "type_variety": "Voyager", + "frequency":{ + "min": 191.35e12, + "max": 196.1e12 + }, + "mode":[ + { + "format": "mode 1", + "baud_rate": 32e9, + "OSNR": 12, + "bit_rate": 100e9, + "roll_off": 0.15, + "tx_osnr": 45, + "min_spacing": 50e9, + "cost":1 + }, + { + "format": "mode 3", + "baud_rate": 44e9, + "OSNR": 18, + "bit_rate": 300e9, + "roll_off": 0.15, + "tx_osnr": 45, + "min_spacing": 62.5e9, + "cost":1 + }, + { + "format": "mode 2", + "baud_rate": 66e9, + "OSNR": 21, + "bit_rate": 400e9, + "roll_off": 0.15, + "tx_osnr": 45, + "min_spacing": 75e9, + "cost":1 + }, + { + "format": "mode 2 - fake", + "baud_rate": 66e9, + "OSNR": 21, + "bit_rate": 400e9, + "roll_off": 0.15, + "tx_osnr": 45, + "min_spacing": 75e9, + "cost":1 + }, + { + "format": "mode 4", + "baud_rate": 66e9, + "OSNR": 16, + "bit_rate": 200e9, + "roll_off": 0.15, + "tx_osnr": 45, + "min_spacing": 75e9, + "cost":1 } ] } diff --git a/tests/data/excelTestFile.xls b/tests/data/excelTestFile.xls index 7e168f39..68de98c3 100644 Binary files a/tests/data/excelTestFile.xls and b/tests/data/excelTestFile.xls differ diff --git a/tests/data/excelTestFile_expected.json b/tests/data/excelTestFile_expected.json index 8e68b3a4..73993834 100644 --- a/tests/data/excelTestFile_expected.json +++ b/tests/data/excelTestFile_expected.json @@ -121,7 +121,7 @@ "type": "Roadm" }, { - "uid": "ingress fused spans in Corlay", + "uid": "west fused spans in Corlay", "metadata": { "location": { "city": "Corlay", @@ -133,7 +133,7 @@ "type": "Fused" }, { - "uid": "ingress fused spans in Loudeac", + "uid": "west fused spans in Loudeac", "metadata": { "location": { "city": "Loudeac", @@ -145,7 +145,7 @@ "type": "Fused" }, { - "uid": "egress fused spans in Corlay", + "uid": "east fused spans in Corlay", "metadata": { "location": { "city": "Corlay", @@ -157,7 +157,7 @@ "type": "Fused" }, { - "uid": "egress fused spans in Loudeac", + "uid": "east fused spans in Loudeac", "metadata": { "location": { "city": "Loudeac", @@ -169,7 +169,7 @@ "type": "Fused" }, { - "uid": "fiber (Lannion_CAS \u2192 Corlay)-", + "uid": "fiber (Lannion_CAS → Corlay)-", "metadata": { "location": { "latitude": 0.0, @@ -187,7 +187,7 @@ } }, { - "uid": "fiber (Corlay \u2192 Loudeac)-", + "uid": "fiber (Corlay → Loudeac)-", "metadata": { "location": { "latitude": 0.0, @@ -205,7 +205,7 @@ } }, { - "uid": "fiber (Loudeac \u2192 Lorient_KMA)-", + "uid": "fiber (Loudeac → Lorient_KMA)-", "metadata": { "location": { "latitude": 0.0, @@ -223,7 +223,7 @@ } }, { - "uid": "fiber (Lorient_KMA \u2192 Vannes_KBE)-F01", + "uid": "fiber (Lorient_KMA → Vannes_KBE)-F01", "metadata": { "location": { "latitude": 0.0, @@ -241,7 +241,7 @@ } }, { - "uid": "fiber (Lannion_CAS \u2192 Stbrieuc)-", + "uid": "fiber (Lannion_CAS → Stbrieuc)-", "metadata": { "location": { "latitude": 0.0, @@ -259,7 +259,7 @@ } }, { - "uid": "fiber (Stbrieuc \u2192 Rennes_STA)-", + "uid": "fiber (Stbrieuc → Rennes_STA)-", "metadata": { "location": { "latitude": 0.0, @@ -277,7 +277,7 @@ } }, { - "uid": "fiber (Lannion_CAS \u2192 Morlaix)-", + "uid": "fiber (Lannion_CAS → Morlaix)-", "metadata": { "location": { "latitude": 0.0, @@ -295,7 +295,7 @@ } }, { - "uid": "fiber (Morlaix \u2192 Brest_KLA)-", + "uid": "fiber (Morlaix → Brest_KLA)-", "metadata": { "location": { "latitude": 0.0, @@ -313,7 +313,7 @@ } }, { - "uid": "fiber (Corlay \u2192 Lannion_CAS)-", + "uid": "fiber (Corlay → Lannion_CAS)-", "metadata": { "location": { "latitude": 0.0, @@ -331,7 +331,7 @@ } }, { - "uid": "fiber (Loudeac \u2192 Corlay)-", + "uid": "fiber (Loudeac → Corlay)-", "metadata": { "location": { "latitude": 0.0, @@ -349,7 +349,7 @@ } }, { - "uid": "fiber (Lorient_KMA \u2192 Loudeac)-", + "uid": "fiber (Lorient_KMA → Loudeac)-", "metadata": { "location": { "latitude": 0.0, @@ -367,7 +367,7 @@ } }, { - "uid": "fiber (Vannes_KBE \u2192 Lorient_KMA)-F01", + "uid": "fiber (Vannes_KBE → Lorient_KMA)-F01", "metadata": { "location": { "latitude": 0.0, @@ -385,7 +385,7 @@ } }, { - "uid": "fiber (Stbrieuc \u2192 Lannion_CAS)-", + "uid": "fiber (Stbrieuc → Lannion_CAS)-", "metadata": { "location": { "latitude": 0.0, @@ -403,7 +403,7 @@ } }, { - "uid": "fiber (Rennes_STA \u2192 Stbrieuc)-", + "uid": "fiber (Rennes_STA → Stbrieuc)-", "metadata": { "location": { "latitude": 0.0, @@ -421,7 +421,7 @@ } }, { - "uid": "fiber (Morlaix \u2192 Lannion_CAS)-", + "uid": "fiber (Morlaix → Lannion_CAS)-", "metadata": { "location": { "latitude": 0.0, @@ -439,7 +439,7 @@ } }, { - "uid": "fiber (Brest_KLA \u2192 Morlaix)-", + "uid": "fiber (Brest_KLA → Morlaix)-", "metadata": { "location": { "latitude": 0.0, @@ -457,7 +457,7 @@ } }, { - "uid": "egress edfa in Lannion_CAS to Morlaix", + "uid": "east edfa in Lannion_CAS to Morlaix", "metadata": { "location": { "city": "Lannion_CAS", @@ -470,11 +470,12 @@ "type_variety": "test", "operational": { "gain_target": 0, - "tilt_target": 0 + "tilt_target": 0, + "out_voa": 0 } }, { - "uid": "egress edfa in Lannion_CAS to Corlay", + "uid": "east edfa in Lannion_CAS to Corlay", "metadata": { "location": { "city": "Lannion_CAS", @@ -487,11 +488,12 @@ "type_variety": "test", "operational": { "gain_target": 0, - "tilt_target": 0 + "tilt_target": 0, + "out_voa": 0 } }, { - "uid": "egress edfa in Lannion_CAS to Stbrieuc", + "uid": "east edfa in Lannion_CAS to Stbrieuc", "metadata": { "location": { "city": "Lannion_CAS", @@ -504,11 +506,12 @@ "type_variety": "test", "operational": { "gain_target": 0, - "tilt_target": 0 + "tilt_target": 0, + "out_voa": 0 } }, { - "uid": "egress edfa in Corlay to Loudeac", + "uid": "east edfa in Corlay to Loudeac", "metadata": { "location": { "city": "Corlay", @@ -521,133 +524,134 @@ "type_variety": "test", "operational": { "gain_target": 0, - "tilt_target": 0 + "tilt_target": 0, + "out_voa": 0 } } ], "connections": [ { "from_node": "roadm Lannion_CAS", - "to_node": "egress edfa in Lannion_CAS to Corlay" + "to_node": "east edfa in Lannion_CAS to Corlay" }, { - "from_node": "egress edfa in Lannion_CAS to Corlay", - "to_node": "fiber (Lannion_CAS \u2192 Corlay)-" + "from_node": "east edfa in Lannion_CAS to Corlay", + "to_node": "fiber (Lannion_CAS → Corlay)-" }, { - "from_node": "fiber (Corlay \u2192 Lannion_CAS)-", + "from_node": "fiber (Corlay → Lannion_CAS)-", "to_node": "roadm Lannion_CAS" }, { "from_node": "roadm Lannion_CAS", - "to_node": "egress edfa in Lannion_CAS to Stbrieuc" + "to_node": "east edfa in Lannion_CAS to Stbrieuc" }, { - "from_node": "egress edfa in Lannion_CAS to Stbrieuc", - "to_node": "fiber (Lannion_CAS \u2192 Stbrieuc)-" + "from_node": "east edfa in Lannion_CAS to Stbrieuc", + "to_node": "fiber (Lannion_CAS → Stbrieuc)-" }, { - "from_node": "fiber (Stbrieuc \u2192 Lannion_CAS)-", + "from_node": "fiber (Stbrieuc → Lannion_CAS)-", "to_node": "roadm Lannion_CAS" }, { "from_node": "roadm Lannion_CAS", - "to_node": "egress edfa in Lannion_CAS to Morlaix" + "to_node": "east edfa in Lannion_CAS to Morlaix" }, { - "from_node": "egress edfa in Lannion_CAS to Morlaix", - "to_node": "fiber (Lannion_CAS \u2192 Morlaix)-" + "from_node": "east edfa in Lannion_CAS to Morlaix", + "to_node": "fiber (Lannion_CAS → Morlaix)-" }, { - "from_node": "fiber (Morlaix \u2192 Lannion_CAS)-", + "from_node": "fiber (Morlaix → Lannion_CAS)-", "to_node": "roadm Lannion_CAS" }, { - "from_node": "fiber (Lannion_CAS \u2192 Corlay)-", - "to_node": "ingress fused spans in Corlay" + "from_node": "fiber (Lannion_CAS → Corlay)-", + "to_node": "west fused spans in Corlay" }, { - "from_node": "ingress fused spans in Corlay", - "to_node": "fiber (Corlay \u2192 Loudeac)-" + "from_node": "west fused spans in Corlay", + "to_node": "fiber (Corlay → Loudeac)-" }, { - "from_node": "fiber (Loudeac \u2192 Corlay)-", - "to_node": "egress fused spans in Corlay" + "from_node": "fiber (Loudeac → Corlay)-", + "to_node": "east fused spans in Corlay" }, { - "from_node": "egress fused spans in Corlay", - "to_node": "fiber (Corlay \u2192 Lannion_CAS)-" + "from_node": "east fused spans in Corlay", + "to_node": "fiber (Corlay → Lannion_CAS)-" }, { - "from_node": "fiber (Corlay \u2192 Loudeac)-", - "to_node": "ingress fused spans in Loudeac" + "from_node": "fiber (Corlay → Loudeac)-", + "to_node": "west fused spans in Loudeac" }, { - "from_node": "ingress fused spans in Loudeac", - "to_node": "fiber (Loudeac \u2192 Lorient_KMA)-" + "from_node": "west fused spans in Loudeac", + "to_node": "fiber (Loudeac → Lorient_KMA)-" }, { - "from_node": "fiber (Lorient_KMA \u2192 Loudeac)-", - "to_node": "egress fused spans in Loudeac" + "from_node": "fiber (Lorient_KMA → Loudeac)-", + "to_node": "east fused spans in Loudeac" }, { - "from_node": "egress fused spans in Loudeac", - "to_node": "fiber (Loudeac \u2192 Corlay)-" + "from_node": "east fused spans in Loudeac", + "to_node": "fiber (Loudeac → Corlay)-" }, { "from_node": "roadm Lorient_KMA", - "to_node": "fiber (Lorient_KMA \u2192 Loudeac)-" + "to_node": "fiber (Lorient_KMA → Loudeac)-" }, { - "from_node": "fiber (Loudeac \u2192 Lorient_KMA)-", + "from_node": "fiber (Loudeac → Lorient_KMA)-", "to_node": "roadm Lorient_KMA" }, { "from_node": "roadm Lorient_KMA", - "to_node": "fiber (Lorient_KMA \u2192 Vannes_KBE)-F01" + "to_node": "fiber (Lorient_KMA → Vannes_KBE)-F01" }, { - "from_node": "fiber (Vannes_KBE \u2192 Lorient_KMA)-F01", + "from_node": "fiber (Vannes_KBE → Lorient_KMA)-F01", "to_node": "roadm Lorient_KMA" }, { "from_node": "roadm Vannes_KBE", - "to_node": "fiber (Vannes_KBE \u2192 Lorient_KMA)-F01" + "to_node": "fiber (Vannes_KBE → Lorient_KMA)-F01" }, { - "from_node": "fiber (Lorient_KMA \u2192 Vannes_KBE)-F01", + "from_node": "fiber (Lorient_KMA → Vannes_KBE)-F01", "to_node": "roadm Vannes_KBE" }, { - "from_node": "fiber (Lannion_CAS \u2192 Stbrieuc)-", - "to_node": "fiber (Stbrieuc \u2192 Rennes_STA)-" + "from_node": "fiber (Lannion_CAS → Stbrieuc)-", + "to_node": "fiber (Stbrieuc → Rennes_STA)-" }, { - "from_node": "fiber (Rennes_STA \u2192 Stbrieuc)-", - "to_node": "fiber (Stbrieuc \u2192 Lannion_CAS)-" + "from_node": "fiber (Rennes_STA → Stbrieuc)-", + "to_node": "fiber (Stbrieuc → Lannion_CAS)-" }, { "from_node": "roadm Rennes_STA", - "to_node": "fiber (Rennes_STA \u2192 Stbrieuc)-" + "to_node": "fiber (Rennes_STA → Stbrieuc)-" }, { - "from_node": "fiber (Stbrieuc \u2192 Rennes_STA)-", + "from_node": "fiber (Stbrieuc → Rennes_STA)-", "to_node": "roadm Rennes_STA" }, { - "from_node": "fiber (Lannion_CAS \u2192 Morlaix)-", - "to_node": "fiber (Morlaix \u2192 Brest_KLA)-" + "from_node": "fiber (Lannion_CAS → Morlaix)-", + "to_node": "fiber (Morlaix → Brest_KLA)-" }, { - "from_node": "fiber (Brest_KLA \u2192 Morlaix)-", - "to_node": "fiber (Morlaix \u2192 Lannion_CAS)-" + "from_node": "fiber (Brest_KLA → Morlaix)-", + "to_node": "fiber (Morlaix → Lannion_CAS)-" }, { "from_node": "roadm Brest_KLA", - "to_node": "fiber (Brest_KLA \u2192 Morlaix)-" + "to_node": "fiber (Brest_KLA → Morlaix)-" }, { - "from_node": "fiber (Morlaix \u2192 Brest_KLA)-", + "from_node": "fiber (Morlaix → Brest_KLA)-", "to_node": "roadm Brest_KLA" }, { diff --git a/tests/data/excelTestFile_services_expected.json b/tests/data/excelTestFile_services_expected.json index 14a23abd..8537b2ba 100644 --- a/tests/data/excelTestFile_services_expected.json +++ b/tests/data/excelTestFile_services_expected.json @@ -19,7 +19,8 @@ ], "spacing": 50000000000.0, "max-nb-of-channel": 80, - "output-power": 0.001 + "output-power": 0.001, + "path_bandwidth": 0 } }, "optimizations": { @@ -45,7 +46,8 @@ ], "spacing": 50000000000.0, "max-nb-of-channel": 80, - "output-power": 0.001 + "output-power": 0.001, + "path_bandwidth": 0 } }, "optimizations": { @@ -53,9 +55,9 @@ } } ], - "synchronisation": [ + "synchronization": [ { - "synchonization-id": "0", + "synchronization-id": "0", "svec": { "relaxable": "False", "link-diverse": "True", @@ -67,7 +69,7 @@ } }, { - "synchonization-id": "1", + "synchronization-id": "1", "svec": { "relaxable": "False", "link-diverse": "True", @@ -79,4 +81,4 @@ } } ] -} \ No newline at end of file +} diff --git a/tests/data/meshTopologyExampleV2.xls b/tests/data/meshTopologyExampleV2.xls index ce9d54fa..71459d8b 100644 Binary files a/tests/data/meshTopologyExampleV2.xls and b/tests/data/meshTopologyExampleV2.xls differ diff --git a/tests/data/meshTopologyExampleV2Eqpt.xls b/tests/data/meshTopologyExampleV2Eqpt.xls index 28e7a062..fad442da 100644 Binary files a/tests/data/meshTopologyExampleV2Eqpt.xls and b/tests/data/meshTopologyExampleV2Eqpt.xls differ diff --git a/tests/data/meshTopologyExampleV2Eqpt_expected.json b/tests/data/meshTopologyExampleV2Eqpt_expected.json index 61ececd6..b452711d 100644 --- a/tests/data/meshTopologyExampleV2Eqpt_expected.json +++ b/tests/data/meshTopologyExampleV2Eqpt_expected.json @@ -169,7 +169,7 @@ "type": "Roadm" }, { - "uid": "ingress fused spans in Corlay", + "uid": "west fused spans in Corlay", "metadata": { "location": { "city": "Corlay", @@ -181,7 +181,7 @@ "type": "Fused" }, { - "uid": "ingress fused spans in Loudeac", + "uid": "west fused spans in Loudeac", "metadata": { "location": { "city": "Loudeac", @@ -193,7 +193,7 @@ "type": "Fused" }, { - "uid": "ingress fused spans in Morlaix", + "uid": "west fused spans in Morlaix", "metadata": { "location": { "city": "Morlaix", @@ -205,7 +205,7 @@ "type": "Fused" }, { - "uid": "egress fused spans in Corlay", + "uid": "east fused spans in Corlay", "metadata": { "location": { "city": "Corlay", @@ -217,7 +217,7 @@ "type": "Fused" }, { - "uid": "egress fused spans in Loudeac", + "uid": "east fused spans in Loudeac", "metadata": { "location": { "city": "Loudeac", @@ -229,7 +229,7 @@ "type": "Fused" }, { - "uid": "egress fused spans in Morlaix", + "uid": "east fused spans in Morlaix", "metadata": { "location": { "city": "Morlaix", @@ -241,7 +241,7 @@ "type": "Fused" }, { - "uid": "fiber (Lannion_CAS \u2192 Corlay)-F061", + "uid": "fiber (Lannion_CAS → Corlay)-F061", "metadata": { "location": { "latitude": 2.0, @@ -259,7 +259,7 @@ } }, { - "uid": "fiber (Corlay \u2192 Loudeac)-F010", + "uid": "fiber (Corlay → Loudeac)-F010", "metadata": { "location": { "latitude": 2.0, @@ -277,7 +277,7 @@ } }, { - "uid": "fiber (Loudeac \u2192 Lorient_KMA)-F054", + "uid": "fiber (Loudeac → Lorient_KMA)-F054", "metadata": { "location": { "latitude": 2.0, @@ -295,7 +295,7 @@ } }, { - "uid": "fiber (Lorient_KMA \u2192 Vannes_KBE)-F055", + "uid": "fiber (Lorient_KMA → Vannes_KBE)-F055", "metadata": { "location": { "latitude": 2.0, @@ -313,7 +313,7 @@ } }, { - "uid": "fiber (Lannion_CAS \u2192 Stbrieuc)-F056", + "uid": "fiber (Lannion_CAS → Stbrieuc)-F056", "metadata": { "location": { "latitude": 1.5, @@ -331,7 +331,7 @@ } }, { - "uid": "fiber (Stbrieuc \u2192 Rennes_STA)-F057", + "uid": "fiber (Stbrieuc → Rennes_STA)-F057", "metadata": { "location": { "latitude": 0.5, @@ -349,7 +349,7 @@ } }, { - "uid": "fiber (Lannion_CAS \u2192 Morlaix)-F059", + "uid": "fiber (Lannion_CAS → Morlaix)-F059", "metadata": { "location": { "latitude": 2.5, @@ -367,7 +367,7 @@ } }, { - "uid": "fiber (Morlaix \u2192 Brest_KLA)-F060", + "uid": "fiber (Morlaix → Brest_KLA)-F060", "metadata": { "location": { "latitude": 3.5, @@ -385,7 +385,7 @@ } }, { - "uid": "fiber (toto \u2192 tata)-", + "uid": "fiber (toto → tata)-", "metadata": { "location": { "latitude": 6.5, @@ -403,7 +403,7 @@ } }, { - "uid": "fiber (Corlay \u2192 Lannion_CAS)-F061", + "uid": "fiber (Corlay → Lannion_CAS)-F061", "metadata": { "location": { "latitude": 2.0, @@ -421,7 +421,7 @@ } }, { - "uid": "fiber (Loudeac \u2192 Corlay)-F010", + "uid": "fiber (Loudeac → Corlay)-F010", "metadata": { "location": { "latitude": 2.0, @@ -439,7 +439,7 @@ } }, { - "uid": "fiber (Lorient_KMA \u2192 Loudeac)-F054", + "uid": "fiber (Lorient_KMA → Loudeac)-F054", "metadata": { "location": { "latitude": 2.0, @@ -457,7 +457,7 @@ } }, { - "uid": "fiber (Vannes_KBE \u2192 Lorient_KMA)-F055", + "uid": "fiber (Vannes_KBE → Lorient_KMA)-F055", "metadata": { "location": { "latitude": 2.0, @@ -475,7 +475,7 @@ } }, { - "uid": "fiber (Stbrieuc \u2192 Lannion_CAS)-F056", + "uid": "fiber (Stbrieuc → Lannion_CAS)-F056", "metadata": { "location": { "latitude": 1.5, @@ -493,7 +493,7 @@ } }, { - "uid": "fiber (Rennes_STA \u2192 Stbrieuc)-F057", + "uid": "fiber (Rennes_STA → Stbrieuc)-F057", "metadata": { "location": { "latitude": 0.5, @@ -511,7 +511,7 @@ } }, { - "uid": "fiber (Morlaix \u2192 Lannion_CAS)-F059", + "uid": "fiber (Morlaix → Lannion_CAS)-F059", "metadata": { "location": { "latitude": 2.5, @@ -529,7 +529,7 @@ } }, { - "uid": "fiber (Brest_KLA \u2192 Morlaix)-F060", + "uid": "fiber (Brest_KLA → Morlaix)-F060", "metadata": { "location": { "latitude": 3.5, @@ -547,7 +547,7 @@ } }, { - "uid": "fiber (tata \u2192 toto)-", + "uid": "fiber (tata → toto)-", "metadata": { "location": { "latitude": 6.5, @@ -565,7 +565,7 @@ } }, { - "uid": "egress edfa in Lannion_CAS to Corlay", + "uid": "east edfa in Lannion_CAS to Corlay", "metadata": { "location": { "city": "Lannion_CAS", @@ -578,11 +578,12 @@ "type_variety": "test", "operational": { "gain_target": 0, - "tilt_target": 0 + "tilt_target": 0, + "out_voa": 0 } }, { - "uid": "egress edfa in Lorient_KMA to Loudeac", + "uid": "east edfa in Lorient_KMA to Loudeac", "metadata": { "location": { "city": "Lorient_KMA", @@ -595,153 +596,154 @@ "type_variety": "test", "operational": { "gain_target": 0, - "tilt_target": 0 + "tilt_target": 0, + "out_voa": 0 } } ], "connections": [ { "from_node": "roadm Lannion_CAS", - "to_node": "egress edfa in Lannion_CAS to Corlay" + "to_node": "east edfa in Lannion_CAS to Corlay" }, { - "from_node": "egress edfa in Lannion_CAS to Corlay", - "to_node": "fiber (Lannion_CAS \u2192 Corlay)-F061" + "from_node": "east edfa in Lannion_CAS to Corlay", + "to_node": "fiber (Lannion_CAS → Corlay)-F061" }, { - "from_node": "fiber (Corlay \u2192 Lannion_CAS)-F061", + "from_node": "fiber (Corlay → Lannion_CAS)-F061", "to_node": "roadm Lannion_CAS" }, { "from_node": "roadm Lannion_CAS", - "to_node": "fiber (Lannion_CAS \u2192 Stbrieuc)-F056" + "to_node": "fiber (Lannion_CAS → Stbrieuc)-F056" }, { - "from_node": "fiber (Stbrieuc \u2192 Lannion_CAS)-F056", + "from_node": "fiber (Stbrieuc → Lannion_CAS)-F056", "to_node": "roadm Lannion_CAS" }, { "from_node": "roadm Lannion_CAS", - "to_node": "fiber (Lannion_CAS \u2192 Morlaix)-F059" + "to_node": "fiber (Lannion_CAS → Morlaix)-F059" }, { - "from_node": "fiber (Morlaix \u2192 Lannion_CAS)-F059", + "from_node": "fiber (Morlaix → Lannion_CAS)-F059", "to_node": "roadm Lannion_CAS" }, { - "from_node": "fiber (Lannion_CAS \u2192 Corlay)-F061", - "to_node": "ingress fused spans in Corlay" + "from_node": "fiber (Lannion_CAS → Corlay)-F061", + "to_node": "west fused spans in Corlay" }, { - "from_node": "ingress fused spans in Corlay", - "to_node": "fiber (Corlay \u2192 Loudeac)-F010" + "from_node": "west fused spans in Corlay", + "to_node": "fiber (Corlay → Loudeac)-F010" }, { - "from_node": "fiber (Loudeac \u2192 Corlay)-F010", - "to_node": "egress fused spans in Corlay" + "from_node": "fiber (Loudeac → Corlay)-F010", + "to_node": "east fused spans in Corlay" }, { - "from_node": "egress fused spans in Corlay", - "to_node": "fiber (Corlay \u2192 Lannion_CAS)-F061" + "from_node": "east fused spans in Corlay", + "to_node": "fiber (Corlay → Lannion_CAS)-F061" }, { - "from_node": "fiber (Corlay \u2192 Loudeac)-F010", - "to_node": "ingress fused spans in Loudeac" + "from_node": "fiber (Corlay → Loudeac)-F010", + "to_node": "west fused spans in Loudeac" }, { - "from_node": "ingress fused spans in Loudeac", - "to_node": "fiber (Loudeac \u2192 Lorient_KMA)-F054" + "from_node": "west fused spans in Loudeac", + "to_node": "fiber (Loudeac → Lorient_KMA)-F054" }, { - "from_node": "fiber (Lorient_KMA \u2192 Loudeac)-F054", - "to_node": "egress fused spans in Loudeac" + "from_node": "fiber (Lorient_KMA → Loudeac)-F054", + "to_node": "east fused spans in Loudeac" }, { - "from_node": "egress fused spans in Loudeac", - "to_node": "fiber (Loudeac \u2192 Corlay)-F010" + "from_node": "east fused spans in Loudeac", + "to_node": "fiber (Loudeac → Corlay)-F010" }, { "from_node": "roadm Lorient_KMA", - "to_node": "egress edfa in Lorient_KMA to Loudeac" + "to_node": "east edfa in Lorient_KMA to Loudeac" }, { - "from_node": "egress edfa in Lorient_KMA to Loudeac", - "to_node": "fiber (Lorient_KMA \u2192 Loudeac)-F054" + "from_node": "east edfa in Lorient_KMA to Loudeac", + "to_node": "fiber (Lorient_KMA → Loudeac)-F054" }, { - "from_node": "fiber (Loudeac \u2192 Lorient_KMA)-F054", + "from_node": "fiber (Loudeac → Lorient_KMA)-F054", "to_node": "roadm Lorient_KMA" }, { "from_node": "roadm Lorient_KMA", - "to_node": "fiber (Lorient_KMA \u2192 Vannes_KBE)-F055" + "to_node": "fiber (Lorient_KMA → Vannes_KBE)-F055" }, { - "from_node": "fiber (Vannes_KBE \u2192 Lorient_KMA)-F055", + "from_node": "fiber (Vannes_KBE → Lorient_KMA)-F055", "to_node": "roadm Lorient_KMA" }, { "from_node": "roadm Vannes_KBE", - "to_node": "fiber (Vannes_KBE \u2192 Lorient_KMA)-F055" + "to_node": "fiber (Vannes_KBE → Lorient_KMA)-F055" }, { - "from_node": "fiber (Lorient_KMA \u2192 Vannes_KBE)-F055", + "from_node": "fiber (Lorient_KMA → Vannes_KBE)-F055", "to_node": "roadm Vannes_KBE" }, { - "from_node": "fiber (Lannion_CAS \u2192 Stbrieuc)-F056", - "to_node": "fiber (Stbrieuc \u2192 Rennes_STA)-F057" + "from_node": "fiber (Lannion_CAS → Stbrieuc)-F056", + "to_node": "fiber (Stbrieuc → Rennes_STA)-F057" }, { - "from_node": "fiber (Rennes_STA \u2192 Stbrieuc)-F057", - "to_node": "fiber (Stbrieuc \u2192 Lannion_CAS)-F056" + "from_node": "fiber (Rennes_STA → Stbrieuc)-F057", + "to_node": "fiber (Stbrieuc → Lannion_CAS)-F056" }, { "from_node": "roadm Rennes_STA", - "to_node": "fiber (Rennes_STA \u2192 Stbrieuc)-F057" + "to_node": "fiber (Rennes_STA → Stbrieuc)-F057" }, { - "from_node": "fiber (Stbrieuc \u2192 Rennes_STA)-F057", + "from_node": "fiber (Stbrieuc → Rennes_STA)-F057", "to_node": "roadm Rennes_STA" }, { - "from_node": "fiber (Lannion_CAS \u2192 Morlaix)-F059", - "to_node": "ingress fused spans in Morlaix" + "from_node": "fiber (Lannion_CAS → Morlaix)-F059", + "to_node": "west fused spans in Morlaix" }, { - "from_node": "ingress fused spans in Morlaix", - "to_node": "fiber (Morlaix \u2192 Brest_KLA)-F060" + "from_node": "west fused spans in Morlaix", + "to_node": "fiber (Morlaix → Brest_KLA)-F060" }, { - "from_node": "fiber (Brest_KLA \u2192 Morlaix)-F060", - "to_node": "egress fused spans in Morlaix" + "from_node": "fiber (Brest_KLA → Morlaix)-F060", + "to_node": "east fused spans in Morlaix" }, { - "from_node": "egress fused spans in Morlaix", - "to_node": "fiber (Morlaix \u2192 Lannion_CAS)-F059" + "from_node": "east fused spans in Morlaix", + "to_node": "fiber (Morlaix → Lannion_CAS)-F059" }, { "from_node": "roadm Brest_KLA", - "to_node": "fiber (Brest_KLA \u2192 Morlaix)-F060" + "to_node": "fiber (Brest_KLA → Morlaix)-F060" }, { - "from_node": "fiber (Morlaix \u2192 Brest_KLA)-F060", + "from_node": "fiber (Morlaix → Brest_KLA)-F060", "to_node": "roadm Brest_KLA" }, { "from_node": "roadm toto", - "to_node": "fiber (toto \u2192 tata)-" + "to_node": "fiber (toto → tata)-" }, { - "from_node": "fiber (tata \u2192 toto)-", + "from_node": "fiber (tata → toto)-", "to_node": "roadm toto" }, { "from_node": "roadm tata", - "to_node": "fiber (tata \u2192 toto)-" + "to_node": "fiber (tata → toto)-" }, { - "from_node": "fiber (toto \u2192 tata)-", + "from_node": "fiber (toto → tata)-", "to_node": "roadm tata" }, { diff --git a/tests/data/meshTopologyExampleV2Eqpt_services_expected.json b/tests/data/meshTopologyExampleV2Eqpt_services_expected.json index 19e405e8..43bd9b8e 100644 --- a/tests/data/meshTopologyExampleV2Eqpt_services_expected.json +++ b/tests/data/meshTopologyExampleV2Eqpt_services_expected.json @@ -19,7 +19,8 @@ ], "spacing": 50000000000.0, "max-nb-of-channel": 80, - "output-power": 0.0012589254117941673 + "output-power": 0.0012589254117941673, + "path_bandwidth": 0 } }, "optimizations": { @@ -45,7 +46,8 @@ ], "spacing": 50000000000.0, "max-nb-of-channel": 80, - "output-power": 0.0012589254117941673 + "output-power": 0.0012589254117941673, + "path_bandwidth": 0 } }, "optimizations": { @@ -102,7 +104,8 @@ ], "spacing": 50000000000.0, "max-nb-of-channel": 80, - "output-power": 0.0012589254117941673 + "output-power": 0.0012589254117941673, + "path_bandwidth": 0 } }, "optimizations": { @@ -128,7 +131,8 @@ ], "spacing": 75000000000.0, "max-nb-of-channel": 64, - "output-power": 0.0019952623149688794 + "output-power": 0.0019952623149688794, + "path_bandwidth": 0 } }, "optimizations": { @@ -154,7 +158,8 @@ ], "spacing": 50000000000.0, "max-nb-of-channel": 80, - "output-power": 0.0012589254117941673 + "output-power": 0.0012589254117941673, + "path_bandwidth": 0 } }, "optimizations": { @@ -178,9 +183,9 @@ } } ], - "synchronisation": [ + "synchronization": [ { - "synchonization-id": "0", + "synchronization-id": "0", "svec": { "relaxable": "False", "link-diverse": "True", @@ -192,7 +197,7 @@ } }, { - "synchonization-id": "3", + "synchronization-id": "3", "svec": { "relaxable": "False", "link-diverse": "True", @@ -204,7 +209,7 @@ } }, { - "synchonization-id": "5", + "synchronization-id": "5", "svec": { "relaxable": "False", "link-diverse": "True", @@ -216,4 +221,4 @@ } } ] -} \ No newline at end of file +} diff --git a/tests/data/meshTopologyExampleV2_expected.json b/tests/data/meshTopologyExampleV2_expected.json index 3bda3268..2bc65e99 100644 --- a/tests/data/meshTopologyExampleV2_expected.json +++ b/tests/data/meshTopologyExampleV2_expected.json @@ -169,7 +169,7 @@ "type": "Roadm" }, { - "uid": "ingress fused spans in Corlay", + "uid": "west fused spans in Corlay", "metadata": { "location": { "city": "Corlay", @@ -181,7 +181,7 @@ "type": "Fused" }, { - "uid": "ingress fused spans in Loudeac", + "uid": "west fused spans in Loudeac", "metadata": { "location": { "city": "Loudeac", @@ -193,7 +193,7 @@ "type": "Fused" }, { - "uid": "ingress fused spans in Morlaix", + "uid": "west fused spans in Morlaix", "metadata": { "location": { "city": "Morlaix", @@ -205,7 +205,7 @@ "type": "Fused" }, { - "uid": "egress fused spans in Corlay", + "uid": "east fused spans in Corlay", "metadata": { "location": { "city": "Corlay", @@ -217,7 +217,7 @@ "type": "Fused" }, { - "uid": "egress fused spans in Loudeac", + "uid": "east fused spans in Loudeac", "metadata": { "location": { "city": "Loudeac", @@ -229,7 +229,7 @@ "type": "Fused" }, { - "uid": "egress fused spans in Morlaix", + "uid": "east fused spans in Morlaix", "metadata": { "location": { "city": "Morlaix", @@ -241,7 +241,7 @@ "type": "Fused" }, { - "uid": "fiber (Lannion_CAS \u2192 Corlay)-F061", + "uid": "fiber (Lannion_CAS → Corlay)-F061", "metadata": { "location": { "latitude": 2.0, @@ -259,7 +259,7 @@ } }, { - "uid": "fiber (Corlay \u2192 Loudeac)-F010", + "uid": "fiber (Corlay → Loudeac)-F010", "metadata": { "location": { "latitude": 2.0, @@ -277,7 +277,7 @@ } }, { - "uid": "fiber (Loudeac \u2192 Lorient_KMA)-F054", + "uid": "fiber (Loudeac → Lorient_KMA)-F054", "metadata": { "location": { "latitude": 2.0, @@ -295,7 +295,7 @@ } }, { - "uid": "fiber (Lorient_KMA \u2192 Vannes_KBE)-F055", + "uid": "fiber (Lorient_KMA → Vannes_KBE)-F055", "metadata": { "location": { "latitude": 2.0, @@ -313,7 +313,7 @@ } }, { - "uid": "fiber (Lannion_CAS \u2192 Stbrieuc)-F056", + "uid": "fiber (Lannion_CAS → Stbrieuc)-F056", "metadata": { "location": { "latitude": 1.5, @@ -331,7 +331,7 @@ } }, { - "uid": "fiber (Stbrieuc \u2192 Rennes_STA)-F057", + "uid": "fiber (Stbrieuc → Rennes_STA)-F057", "metadata": { "location": { "latitude": 0.5, @@ -349,7 +349,7 @@ } }, { - "uid": "fiber (Lannion_CAS \u2192 Morlaix)-F059", + "uid": "fiber (Lannion_CAS → Morlaix)-F059", "metadata": { "location": { "latitude": 2.5, @@ -367,7 +367,7 @@ } }, { - "uid": "fiber (Morlaix \u2192 Brest_KLA)-F060", + "uid": "fiber (Morlaix → Brest_KLA)-F060", "metadata": { "location": { "latitude": 3.5, @@ -385,7 +385,7 @@ } }, { - "uid": "fiber (toto \u2192 tata)-", + "uid": "fiber (toto → tata)-", "metadata": { "location": { "latitude": 6.5, @@ -403,7 +403,7 @@ } }, { - "uid": "fiber (Corlay \u2192 Lannion_CAS)-F061", + "uid": "fiber (Corlay → Lannion_CAS)-F061", "metadata": { "location": { "latitude": 2.0, @@ -421,7 +421,7 @@ } }, { - "uid": "fiber (Loudeac \u2192 Corlay)-F010", + "uid": "fiber (Loudeac → Corlay)-F010", "metadata": { "location": { "latitude": 2.0, @@ -439,7 +439,7 @@ } }, { - "uid": "fiber (Lorient_KMA \u2192 Loudeac)-F054", + "uid": "fiber (Lorient_KMA → Loudeac)-F054", "metadata": { "location": { "latitude": 2.0, @@ -457,7 +457,7 @@ } }, { - "uid": "fiber (Vannes_KBE \u2192 Lorient_KMA)-F055", + "uid": "fiber (Vannes_KBE → Lorient_KMA)-F055", "metadata": { "location": { "latitude": 2.0, @@ -475,7 +475,7 @@ } }, { - "uid": "fiber (Stbrieuc \u2192 Lannion_CAS)-F056", + "uid": "fiber (Stbrieuc → Lannion_CAS)-F056", "metadata": { "location": { "latitude": 1.5, @@ -493,7 +493,7 @@ } }, { - "uid": "fiber (Rennes_STA \u2192 Stbrieuc)-F057", + "uid": "fiber (Rennes_STA → Stbrieuc)-F057", "metadata": { "location": { "latitude": 0.5, @@ -511,7 +511,7 @@ } }, { - "uid": "fiber (Morlaix \u2192 Lannion_CAS)-F059", + "uid": "fiber (Morlaix → Lannion_CAS)-F059", "metadata": { "location": { "latitude": 2.5, @@ -529,7 +529,7 @@ } }, { - "uid": "fiber (Brest_KLA \u2192 Morlaix)-F060", + "uid": "fiber (Brest_KLA → Morlaix)-F060", "metadata": { "location": { "latitude": 3.5, @@ -547,7 +547,7 @@ } }, { - "uid": "fiber (tata \u2192 toto)-", + "uid": "fiber (tata → toto)-", "metadata": { "location": { "latitude": 6.5, @@ -568,138 +568,138 @@ "connections": [ { "from_node": "roadm Lannion_CAS", - "to_node": "fiber (Lannion_CAS \u2192 Corlay)-F061" + "to_node": "fiber (Lannion_CAS → Corlay)-F061" }, { - "from_node": "fiber (Corlay \u2192 Lannion_CAS)-F061", + "from_node": "fiber (Corlay → Lannion_CAS)-F061", "to_node": "roadm Lannion_CAS" }, { "from_node": "roadm Lannion_CAS", - "to_node": "fiber (Lannion_CAS \u2192 Stbrieuc)-F056" + "to_node": "fiber (Lannion_CAS → Stbrieuc)-F056" }, { - "from_node": "fiber (Stbrieuc \u2192 Lannion_CAS)-F056", + "from_node": "fiber (Stbrieuc → Lannion_CAS)-F056", "to_node": "roadm Lannion_CAS" }, { "from_node": "roadm Lannion_CAS", - "to_node": "fiber (Lannion_CAS \u2192 Morlaix)-F059" + "to_node": "fiber (Lannion_CAS → Morlaix)-F059" }, { - "from_node": "fiber (Morlaix \u2192 Lannion_CAS)-F059", + "from_node": "fiber (Morlaix → Lannion_CAS)-F059", "to_node": "roadm Lannion_CAS" }, { - "from_node": "fiber (Lannion_CAS \u2192 Corlay)-F061", - "to_node": "ingress fused spans in Corlay" + "from_node": "fiber (Lannion_CAS → Corlay)-F061", + "to_node": "west fused spans in Corlay" }, { - "from_node": "ingress fused spans in Corlay", - "to_node": "fiber (Corlay \u2192 Loudeac)-F010" + "from_node": "west fused spans in Corlay", + "to_node": "fiber (Corlay → Loudeac)-F010" }, { - "from_node": "fiber (Loudeac \u2192 Corlay)-F010", - "to_node": "egress fused spans in Corlay" + "from_node": "fiber (Loudeac → Corlay)-F010", + "to_node": "east fused spans in Corlay" }, { - "from_node": "egress fused spans in Corlay", - "to_node": "fiber (Corlay \u2192 Lannion_CAS)-F061" + "from_node": "east fused spans in Corlay", + "to_node": "fiber (Corlay → Lannion_CAS)-F061" }, { - "from_node": "fiber (Corlay \u2192 Loudeac)-F010", - "to_node": "ingress fused spans in Loudeac" + "from_node": "fiber (Corlay → Loudeac)-F010", + "to_node": "west fused spans in Loudeac" }, { - "from_node": "ingress fused spans in Loudeac", - "to_node": "fiber (Loudeac \u2192 Lorient_KMA)-F054" + "from_node": "west fused spans in Loudeac", + "to_node": "fiber (Loudeac → Lorient_KMA)-F054" }, { - "from_node": "fiber (Lorient_KMA \u2192 Loudeac)-F054", - "to_node": "egress fused spans in Loudeac" + "from_node": "fiber (Lorient_KMA → Loudeac)-F054", + "to_node": "east fused spans in Loudeac" }, { - "from_node": "egress fused spans in Loudeac", - "to_node": "fiber (Loudeac \u2192 Corlay)-F010" + "from_node": "east fused spans in Loudeac", + "to_node": "fiber (Loudeac → Corlay)-F010" }, { "from_node": "roadm Lorient_KMA", - "to_node": "fiber (Lorient_KMA \u2192 Loudeac)-F054" + "to_node": "fiber (Lorient_KMA → Loudeac)-F054" }, { - "from_node": "fiber (Loudeac \u2192 Lorient_KMA)-F054", + "from_node": "fiber (Loudeac → Lorient_KMA)-F054", "to_node": "roadm Lorient_KMA" }, { "from_node": "roadm Lorient_KMA", - "to_node": "fiber (Lorient_KMA \u2192 Vannes_KBE)-F055" + "to_node": "fiber (Lorient_KMA → Vannes_KBE)-F055" }, { - "from_node": "fiber (Vannes_KBE \u2192 Lorient_KMA)-F055", + "from_node": "fiber (Vannes_KBE → Lorient_KMA)-F055", "to_node": "roadm Lorient_KMA" }, { "from_node": "roadm Vannes_KBE", - "to_node": "fiber (Vannes_KBE \u2192 Lorient_KMA)-F055" + "to_node": "fiber (Vannes_KBE → Lorient_KMA)-F055" }, { - "from_node": "fiber (Lorient_KMA \u2192 Vannes_KBE)-F055", + "from_node": "fiber (Lorient_KMA → Vannes_KBE)-F055", "to_node": "roadm Vannes_KBE" }, { - "from_node": "fiber (Lannion_CAS \u2192 Stbrieuc)-F056", - "to_node": "fiber (Stbrieuc \u2192 Rennes_STA)-F057" + "from_node": "fiber (Lannion_CAS → Stbrieuc)-F056", + "to_node": "fiber (Stbrieuc → Rennes_STA)-F057" }, { - "from_node": "fiber (Rennes_STA \u2192 Stbrieuc)-F057", - "to_node": "fiber (Stbrieuc \u2192 Lannion_CAS)-F056" + "from_node": "fiber (Rennes_STA → Stbrieuc)-F057", + "to_node": "fiber (Stbrieuc → Lannion_CAS)-F056" }, { "from_node": "roadm Rennes_STA", - "to_node": "fiber (Rennes_STA \u2192 Stbrieuc)-F057" + "to_node": "fiber (Rennes_STA → Stbrieuc)-F057" }, { - "from_node": "fiber (Stbrieuc \u2192 Rennes_STA)-F057", + "from_node": "fiber (Stbrieuc → Rennes_STA)-F057", "to_node": "roadm Rennes_STA" }, { - "from_node": "fiber (Lannion_CAS \u2192 Morlaix)-F059", - "to_node": "ingress fused spans in Morlaix" + "from_node": "fiber (Lannion_CAS → Morlaix)-F059", + "to_node": "west fused spans in Morlaix" }, { - "from_node": "ingress fused spans in Morlaix", - "to_node": "fiber (Morlaix \u2192 Brest_KLA)-F060" + "from_node": "west fused spans in Morlaix", + "to_node": "fiber (Morlaix → Brest_KLA)-F060" }, { - "from_node": "fiber (Brest_KLA \u2192 Morlaix)-F060", - "to_node": "egress fused spans in Morlaix" + "from_node": "fiber (Brest_KLA → Morlaix)-F060", + "to_node": "east fused spans in Morlaix" }, { - "from_node": "egress fused spans in Morlaix", - "to_node": "fiber (Morlaix \u2192 Lannion_CAS)-F059" + "from_node": "east fused spans in Morlaix", + "to_node": "fiber (Morlaix → Lannion_CAS)-F059" }, { "from_node": "roadm Brest_KLA", - "to_node": "fiber (Brest_KLA \u2192 Morlaix)-F060" + "to_node": "fiber (Brest_KLA → Morlaix)-F060" }, { - "from_node": "fiber (Morlaix \u2192 Brest_KLA)-F060", + "from_node": "fiber (Morlaix → Brest_KLA)-F060", "to_node": "roadm Brest_KLA" }, { "from_node": "roadm toto", - "to_node": "fiber (toto \u2192 tata)-" + "to_node": "fiber (toto → tata)-" }, { - "from_node": "fiber (tata \u2192 toto)-", + "from_node": "fiber (tata → toto)-", "to_node": "roadm toto" }, { "from_node": "roadm tata", - "to_node": "fiber (tata \u2192 toto)-" + "to_node": "fiber (tata → toto)-" }, { - "from_node": "fiber (toto \u2192 tata)-", + "from_node": "fiber (toto → tata)-", "to_node": "roadm tata" }, { diff --git a/tests/data/meshTopologyExampleV2_services_expected.json b/tests/data/meshTopologyExampleV2_services_expected.json index 19e405e8..43bd9b8e 100644 --- a/tests/data/meshTopologyExampleV2_services_expected.json +++ b/tests/data/meshTopologyExampleV2_services_expected.json @@ -19,7 +19,8 @@ ], "spacing": 50000000000.0, "max-nb-of-channel": 80, - "output-power": 0.0012589254117941673 + "output-power": 0.0012589254117941673, + "path_bandwidth": 0 } }, "optimizations": { @@ -45,7 +46,8 @@ ], "spacing": 50000000000.0, "max-nb-of-channel": 80, - "output-power": 0.0012589254117941673 + "output-power": 0.0012589254117941673, + "path_bandwidth": 0 } }, "optimizations": { @@ -102,7 +104,8 @@ ], "spacing": 50000000000.0, "max-nb-of-channel": 80, - "output-power": 0.0012589254117941673 + "output-power": 0.0012589254117941673, + "path_bandwidth": 0 } }, "optimizations": { @@ -128,7 +131,8 @@ ], "spacing": 75000000000.0, "max-nb-of-channel": 64, - "output-power": 0.0019952623149688794 + "output-power": 0.0019952623149688794, + "path_bandwidth": 0 } }, "optimizations": { @@ -154,7 +158,8 @@ ], "spacing": 50000000000.0, "max-nb-of-channel": 80, - "output-power": 0.0012589254117941673 + "output-power": 0.0012589254117941673, + "path_bandwidth": 0 } }, "optimizations": { @@ -178,9 +183,9 @@ } } ], - "synchronisation": [ + "synchronization": [ { - "synchonization-id": "0", + "synchronization-id": "0", "svec": { "relaxable": "False", "link-diverse": "True", @@ -192,7 +197,7 @@ } }, { - "synchonization-id": "3", + "synchronization-id": "3", "svec": { "relaxable": "False", "link-diverse": "True", @@ -204,7 +209,7 @@ } }, { - "synchonization-id": "5", + "synchronization-id": "5", "svec": { "relaxable": "False", "link-diverse": "True", @@ -216,4 +221,4 @@ } } ] -} \ No newline at end of file +} diff --git a/tests/data/meshTopologyToy.json b/tests/data/meshTopologyToy.json new file mode 100644 index 00000000..c1592f6b --- /dev/null +++ b/tests/data/meshTopologyToy.json @@ -0,0 +1,730 @@ +{ + "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" + } + ] +} \ No newline at end of file diff --git a/tests/data/meshTopologyToy_results_expected.json b/tests/data/meshTopologyToy_results_expected.json new file mode 100644 index 00000000..61177f56 --- /dev/null +++ b/tests/data/meshTopologyToy_results_expected.json @@ -0,0 +1,2884 @@ +{ + "path": [ + { + "path-id": "1", + "path-properties": { + "path-metric": [ + { + "metric-type": "SNR@bandwidth", + "accumulative-value": 18.0 + }, + { + "metric-type": "SNR@0.1nm", + "accumulative-value": 22.08 + }, + { + "metric-type": "OSNR@bandwidth", + "accumulative-value": 18.91 + }, + { + "metric-type": "OSNR@0.1nm", + "accumulative-value": 22.99 + }, + { + "metric-type": "reference_power", + "accumulative-value": 0.001 + } + ], + "path-srlgs": { + "usage": "not used yet", + "values": "not used yet" + }, + "path-route-objects": [ + { + "path-route-object": { + "index": 0, + "unnumbered-hop": { + "node-id": "trx a", + "link-tp-id": "trx a", + "hop-type": "Voyager - 16QAM", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 1, + "unnumbered-hop": { + "node-id": "roadm a", + "link-tp-id": "roadm a", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 2, + "unnumbered-hop": { + "node-id": "Edfa1_roadm a", + "link-tp-id": "Edfa1_roadm a", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 3, + "unnumbered-hop": { + "node-id": "fiber (a \u2192 c)-", + "link-tp-id": "fiber (a \u2192 c)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 4, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (a \u2192 c)-", + "link-tp-id": "Edfa0_fiber (a \u2192 c)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 5, + "unnumbered-hop": { + "node-id": "roadm c", + "link-tp-id": "roadm c", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 6, + "unnumbered-hop": { + "node-id": "Edfa1_roadm c", + "link-tp-id": "Edfa1_roadm c", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 7, + "unnumbered-hop": { + "node-id": "fiber (c \u2192 d)-", + "link-tp-id": "fiber (c \u2192 d)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 8, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (c \u2192 d)-", + "link-tp-id": "Edfa0_fiber (c \u2192 d)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 9, + "unnumbered-hop": { + "node-id": "roadm d", + "link-tp-id": "roadm d", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 10, + "unnumbered-hop": { + "node-id": "Edfa1_roadm d", + "link-tp-id": "Edfa1_roadm d", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 11, + "unnumbered-hop": { + "node-id": "fiber (d \u2192 e)-F057", + "link-tp-id": "fiber (d \u2192 e)-F057", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 12, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (d \u2192 e)-F057", + "link-tp-id": "Edfa0_fiber (d \u2192 e)-F057", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 13, + "unnumbered-hop": { + "node-id": "roadm e", + "link-tp-id": "roadm e", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 14, + "unnumbered-hop": { + "node-id": "Edfa1_roadm e", + "link-tp-id": "Edfa1_roadm e", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 15, + "unnumbered-hop": { + "node-id": "fiber (e \u2192 g)-", + "link-tp-id": "fiber (e \u2192 g)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 16, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (e \u2192 g)-", + "link-tp-id": "Edfa0_fiber (e \u2192 g)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 17, + "unnumbered-hop": { + "node-id": "roadm g", + "link-tp-id": "roadm g", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 18, + "unnumbered-hop": { + "node-id": "trx g", + "link-tp-id": "trx g", + "hop-type": "Voyager - 16QAM", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + } + ] + } + }, + { + "path-id": "2a", + "path-properties": { + "path-metric": [ + { + "metric-type": "SNR@bandwidth", + "accumulative-value": 19.88 + }, + { + "metric-type": "SNR@0.1nm", + "accumulative-value": 23.96 + }, + { + "metric-type": "OSNR@bandwidth", + "accumulative-value": 20.83 + }, + { + "metric-type": "OSNR@0.1nm", + "accumulative-value": 24.91 + }, + { + "metric-type": "reference_power", + "accumulative-value": 0.001 + } + ], + "path-srlgs": { + "usage": "not used yet", + "values": "not used yet" + }, + "path-route-objects": [ + { + "path-route-object": { + "index": 0, + "unnumbered-hop": { + "node-id": "trx a", + "link-tp-id": "trx a", + "hop-type": "vendorA_trx-type1 - mode 1", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 1, + "unnumbered-hop": { + "node-id": "roadm a", + "link-tp-id": "roadm a", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 2, + "unnumbered-hop": { + "node-id": "Edfa0_roadm a", + "link-tp-id": "Edfa0_roadm a", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 3, + "unnumbered-hop": { + "node-id": "fiber (a \u2192 b)-", + "link-tp-id": "fiber (a \u2192 b)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 4, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (a \u2192 b)-", + "link-tp-id": "Edfa0_fiber (a \u2192 b)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 5, + "unnumbered-hop": { + "node-id": "roadm b", + "link-tp-id": "roadm b", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 6, + "unnumbered-hop": { + "node-id": "Edfa1_roadm b", + "link-tp-id": "Edfa1_roadm b", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 7, + "unnumbered-hop": { + "node-id": "fiber (b \u2192 f)-", + "link-tp-id": "fiber (b \u2192 f)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 8, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (b \u2192 f)-", + "link-tp-id": "Edfa0_fiber (b \u2192 f)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 9, + "unnumbered-hop": { + "node-id": "roadm f", + "link-tp-id": "roadm f", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 10, + "unnumbered-hop": { + "node-id": "Edfa2_roadm f", + "link-tp-id": "Edfa2_roadm f", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 11, + "unnumbered-hop": { + "node-id": "fiber (f \u2192 h)-", + "link-tp-id": "fiber (f \u2192 h)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 12, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (f \u2192 h)-", + "link-tp-id": "Edfa0_fiber (f \u2192 h)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 13, + "unnumbered-hop": { + "node-id": "roadm h", + "link-tp-id": "roadm h", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 14, + "unnumbered-hop": { + "node-id": "trx h", + "link-tp-id": "trx h", + "hop-type": "vendorA_trx-type1 - mode 1", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + } + ] + } + }, + { + "path-id": "3", + "path-properties": { + "path-metric": [ + { + "metric-type": "SNR@bandwidth", + "accumulative-value": 24.83 + }, + { + "metric-type": "SNR@0.1nm", + "accumulative-value": 28.91 + }, + { + "metric-type": "OSNR@bandwidth", + "accumulative-value": 26.28 + }, + { + "metric-type": "OSNR@0.1nm", + "accumulative-value": 30.36 + }, + { + "metric-type": "reference_power", + "accumulative-value": 0.001 + } + ], + "path-srlgs": { + "usage": "not used yet", + "values": "not used yet" + }, + "path-route-objects": [ + { + "path-route-object": { + "index": 0, + "unnumbered-hop": { + "node-id": "trx f", + "link-tp-id": "trx f", + "hop-type": "vendorA_trx-type1 - mode 1", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 1, + "unnumbered-hop": { + "node-id": "roadm f", + "link-tp-id": "roadm f", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 2, + "unnumbered-hop": { + "node-id": "Edfa1_roadm f", + "link-tp-id": "Edfa1_roadm f", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 3, + "unnumbered-hop": { + "node-id": "fiber (f \u2192 b)-F056", + "link-tp-id": "fiber (f \u2192 b)-F056", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 4, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (f \u2192 b)-F056", + "link-tp-id": "Edfa0_fiber (f \u2192 b)-F056", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 5, + "unnumbered-hop": { + "node-id": "roadm b", + "link-tp-id": "roadm b", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 6, + "unnumbered-hop": { + "node-id": "trx b", + "link-tp-id": "trx b", + "hop-type": "vendorA_trx-type1 - mode 1", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + } + ] + } + }, + { + "path-id": "ee", + "path-properties": { + "path-metric": [ + { + "metric-type": "SNR@bandwidth", + "accumulative-value": 16.81 + }, + { + "metric-type": "SNR@0.1nm", + "accumulative-value": 20.89 + }, + { + "metric-type": "OSNR@bandwidth", + "accumulative-value": 17.94 + }, + { + "metric-type": "OSNR@0.1nm", + "accumulative-value": 22.02 + }, + { + "metric-type": "reference_power", + "accumulative-value": 0.001 + } + ], + "path-srlgs": { + "usage": "not used yet", + "values": "not used yet" + }, + "path-route-objects": [ + { + "path-route-object": { + "index": 0, + "unnumbered-hop": { + "node-id": "trx c", + "link-tp-id": "trx c", + "hop-type": "vendorA_trx-type1 - mode 1", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 1, + "unnumbered-hop": { + "node-id": "roadm c", + "link-tp-id": "roadm c", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 2, + "unnumbered-hop": { + "node-id": "Edfa1_roadm c", + "link-tp-id": "Edfa1_roadm c", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 3, + "unnumbered-hop": { + "node-id": "fiber (c \u2192 d)-", + "link-tp-id": "fiber (c \u2192 d)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 4, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (c \u2192 d)-", + "link-tp-id": "Edfa0_fiber (c \u2192 d)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 5, + "unnumbered-hop": { + "node-id": "roadm d", + "link-tp-id": "roadm d", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 6, + "unnumbered-hop": { + "node-id": "Edfa1_roadm d", + "link-tp-id": "Edfa1_roadm d", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 7, + "unnumbered-hop": { + "node-id": "fiber (d \u2192 e)-F057", + "link-tp-id": "fiber (d \u2192 e)-F057", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 8, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (d \u2192 e)-F057", + "link-tp-id": "Edfa0_fiber (d \u2192 e)-F057", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 9, + "unnumbered-hop": { + "node-id": "roadm e", + "link-tp-id": "roadm e", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 10, + "unnumbered-hop": { + "node-id": "Edfa1_roadm e", + "link-tp-id": "Edfa1_roadm e", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 11, + "unnumbered-hop": { + "node-id": "fiber (e \u2192 g)-", + "link-tp-id": "fiber (e \u2192 g)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 12, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (e \u2192 g)-", + "link-tp-id": "Edfa0_fiber (e \u2192 g)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 13, + "unnumbered-hop": { + "node-id": "roadm g", + "link-tp-id": "roadm g", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 14, + "unnumbered-hop": { + "node-id": "Edfa1_roadm g", + "link-tp-id": "Edfa1_roadm g", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 15, + "unnumbered-hop": { + "node-id": "fiber (g \u2192 h)-", + "link-tp-id": "fiber (g \u2192 h)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 16, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (g \u2192 h)-", + "link-tp-id": "Edfa0_fiber (g \u2192 h)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 17, + "unnumbered-hop": { + "node-id": "roadm h", + "link-tp-id": "roadm h", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 18, + "unnumbered-hop": { + "node-id": "Edfa0_roadm h", + "link-tp-id": "Edfa0_roadm h", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 19, + "unnumbered-hop": { + "node-id": "fiber (h \u2192 f)-F060", + "link-tp-id": "fiber (h \u2192 f)-F060", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 20, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (h \u2192 f)-F060", + "link-tp-id": "Edfa0_fiber (h \u2192 f)-F060", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 21, + "unnumbered-hop": { + "node-id": "roadm f", + "link-tp-id": "roadm f", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 22, + "unnumbered-hop": { + "node-id": "trx f", + "link-tp-id": "trx f", + "hop-type": "vendorA_trx-type1 - mode 1", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + } + ] + } + }, + { + "path-id": "ff", + "path-properties": { + "path-metric": [ + { + "metric-type": "SNR@bandwidth", + "accumulative-value": 16.81 + }, + { + "metric-type": "SNR@0.1nm", + "accumulative-value": 20.89 + }, + { + "metric-type": "OSNR@bandwidth", + "accumulative-value": 17.94 + }, + { + "metric-type": "OSNR@0.1nm", + "accumulative-value": 22.02 + }, + { + "metric-type": "reference_power", + "accumulative-value": 0.001 + } + ], + "path-srlgs": { + "usage": "not used yet", + "values": "not used yet" + }, + "path-route-objects": [ + { + "path-route-object": { + "index": 0, + "unnumbered-hop": { + "node-id": "trx c", + "link-tp-id": "trx c", + "hop-type": "vendorA_trx-type1 - mode 1", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 1, + "unnumbered-hop": { + "node-id": "roadm c", + "link-tp-id": "roadm c", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 2, + "unnumbered-hop": { + "node-id": "Edfa0_roadm c", + "link-tp-id": "Edfa0_roadm c", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 3, + "unnumbered-hop": { + "node-id": "fiber (c \u2192 a)-F010", + "link-tp-id": "fiber (c \u2192 a)-F010", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 4, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (c \u2192 a)-F010", + "link-tp-id": "Edfa0_fiber (c \u2192 a)-F010", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 5, + "unnumbered-hop": { + "node-id": "roadm a", + "link-tp-id": "roadm a", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 6, + "unnumbered-hop": { + "node-id": "Edfa0_roadm a", + "link-tp-id": "Edfa0_roadm a", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 7, + "unnumbered-hop": { + "node-id": "fiber (a \u2192 b)-", + "link-tp-id": "fiber (a \u2192 b)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 8, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (a \u2192 b)-", + "link-tp-id": "Edfa0_fiber (a \u2192 b)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 9, + "unnumbered-hop": { + "node-id": "roadm b", + "link-tp-id": "roadm b", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 10, + "unnumbered-hop": { + "node-id": "Edfa1_roadm b", + "link-tp-id": "Edfa1_roadm b", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 11, + "unnumbered-hop": { + "node-id": "fiber (b \u2192 f)-", + "link-tp-id": "fiber (b \u2192 f)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 12, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (b \u2192 f)-", + "link-tp-id": "Edfa0_fiber (b \u2192 f)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 13, + "unnumbered-hop": { + "node-id": "roadm f", + "link-tp-id": "roadm f", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 14, + "unnumbered-hop": { + "node-id": "trx f", + "link-tp-id": "trx f", + "hop-type": "vendorA_trx-type1 - mode 1", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + } + ] + } + }, + { + "path-id": "10", + "path-properties": { + "path-metric": [ + { + "metric-type": "SNR@bandwidth", + "accumulative-value": 18.0 + }, + { + "metric-type": "SNR@0.1nm", + "accumulative-value": 22.08 + }, + { + "metric-type": "OSNR@bandwidth", + "accumulative-value": 18.91 + }, + { + "metric-type": "OSNR@0.1nm", + "accumulative-value": 22.99 + }, + { + "metric-type": "reference_power", + "accumulative-value": 0.001 + } + ], + "path-srlgs": { + "usage": "not used yet", + "values": "not used yet" + }, + "path-route-objects": [ + { + "path-route-object": { + "index": 0, + "unnumbered-hop": { + "node-id": "trx a", + "link-tp-id": "trx a", + "hop-type": "Voyager - 16QAM", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 1, + "unnumbered-hop": { + "node-id": "roadm a", + "link-tp-id": "roadm a", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 2, + "unnumbered-hop": { + "node-id": "Edfa0_roadm a", + "link-tp-id": "Edfa0_roadm a", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 3, + "unnumbered-hop": { + "node-id": "fiber (a \u2192 b)-", + "link-tp-id": "fiber (a \u2192 b)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 4, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (a \u2192 b)-", + "link-tp-id": "Edfa0_fiber (a \u2192 b)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 5, + "unnumbered-hop": { + "node-id": "roadm b", + "link-tp-id": "roadm b", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 6, + "unnumbered-hop": { + "node-id": "Edfa1_roadm b", + "link-tp-id": "Edfa1_roadm b", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 7, + "unnumbered-hop": { + "node-id": "fiber (b \u2192 f)-", + "link-tp-id": "fiber (b \u2192 f)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 8, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (b \u2192 f)-", + "link-tp-id": "Edfa0_fiber (b \u2192 f)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 9, + "unnumbered-hop": { + "node-id": "roadm f", + "link-tp-id": "roadm f", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 10, + "unnumbered-hop": { + "node-id": "Edfa2_roadm f", + "link-tp-id": "Edfa2_roadm f", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 11, + "unnumbered-hop": { + "node-id": "fiber (f \u2192 h)-", + "link-tp-id": "fiber (f \u2192 h)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 12, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (f \u2192 h)-", + "link-tp-id": "Edfa0_fiber (f \u2192 h)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 13, + "unnumbered-hop": { + "node-id": "roadm h", + "link-tp-id": "roadm h", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 14, + "unnumbered-hop": { + "node-id": "Edfa1_roadm h", + "link-tp-id": "Edfa1_roadm h", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 15, + "unnumbered-hop": { + "node-id": "fiber (h \u2192 g)-", + "link-tp-id": "fiber (h \u2192 g)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 16, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (h \u2192 g)-", + "link-tp-id": "Edfa0_fiber (h \u2192 g)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 17, + "unnumbered-hop": { + "node-id": "roadm g", + "link-tp-id": "roadm g", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 18, + "unnumbered-hop": { + "node-id": "trx g", + "link-tp-id": "trx g", + "hop-type": "Voyager - 16QAM", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + } + ] + } + }, + { + "path-id": "2a", + "path-properties": { + "path-metric": [ + { + "metric-type": "SNR@bandwidth", + "accumulative-value": 19.88 + }, + { + "metric-type": "SNR@0.1nm", + "accumulative-value": 23.96 + }, + { + "metric-type": "OSNR@bandwidth", + "accumulative-value": 20.83 + }, + { + "metric-type": "OSNR@0.1nm", + "accumulative-value": 24.91 + }, + { + "metric-type": "reference_power", + "accumulative-value": 0.001 + } + ], + "path-srlgs": { + "usage": "not used yet", + "values": "not used yet" + }, + "path-route-objects": [ + { + "path-route-object": { + "index": 0, + "unnumbered-hop": { + "node-id": "trx a", + "link-tp-id": "trx a", + "hop-type": "vendorA_trx-type1 - mode 1", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 1, + "unnumbered-hop": { + "node-id": "roadm a", + "link-tp-id": "roadm a", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 2, + "unnumbered-hop": { + "node-id": "Edfa0_roadm a", + "link-tp-id": "Edfa0_roadm a", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 3, + "unnumbered-hop": { + "node-id": "fiber (a \u2192 b)-", + "link-tp-id": "fiber (a \u2192 b)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 4, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (a \u2192 b)-", + "link-tp-id": "Edfa0_fiber (a \u2192 b)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 5, + "unnumbered-hop": { + "node-id": "roadm b", + "link-tp-id": "roadm b", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 6, + "unnumbered-hop": { + "node-id": "Edfa1_roadm b", + "link-tp-id": "Edfa1_roadm b", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 7, + "unnumbered-hop": { + "node-id": "fiber (b \u2192 f)-", + "link-tp-id": "fiber (b \u2192 f)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 8, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (b \u2192 f)-", + "link-tp-id": "Edfa0_fiber (b \u2192 f)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 9, + "unnumbered-hop": { + "node-id": "roadm f", + "link-tp-id": "roadm f", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 10, + "unnumbered-hop": { + "node-id": "Edfa2_roadm f", + "link-tp-id": "Edfa2_roadm f", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 11, + "unnumbered-hop": { + "node-id": "fiber (f \u2192 h)-", + "link-tp-id": "fiber (f \u2192 h)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 12, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (f \u2192 h)-", + "link-tp-id": "Edfa0_fiber (f \u2192 h)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 13, + "unnumbered-hop": { + "node-id": "roadm h", + "link-tp-id": "roadm h", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 14, + "unnumbered-hop": { + "node-id": "trx h", + "link-tp-id": "trx h", + "hop-type": "vendorA_trx-type1 - mode 1", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + } + ] + } + }, + { + "path-id": "3", + "path-properties": { + "path-metric": [ + { + "metric-type": "SNR@bandwidth", + "accumulative-value": 24.83 + }, + { + "metric-type": "SNR@0.1nm", + "accumulative-value": 28.91 + }, + { + "metric-type": "OSNR@bandwidth", + "accumulative-value": 26.28 + }, + { + "metric-type": "OSNR@0.1nm", + "accumulative-value": 30.36 + }, + { + "metric-type": "reference_power", + "accumulative-value": 0.001 + } + ], + "path-srlgs": { + "usage": "not used yet", + "values": "not used yet" + }, + "path-route-objects": [ + { + "path-route-object": { + "index": 0, + "unnumbered-hop": { + "node-id": "trx f", + "link-tp-id": "trx f", + "hop-type": "vendorA_trx-type1 - mode 1", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 1, + "unnumbered-hop": { + "node-id": "roadm f", + "link-tp-id": "roadm f", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 2, + "unnumbered-hop": { + "node-id": "Edfa1_roadm f", + "link-tp-id": "Edfa1_roadm f", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 3, + "unnumbered-hop": { + "node-id": "fiber (f \u2192 b)-F056", + "link-tp-id": "fiber (f \u2192 b)-F056", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 4, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (f \u2192 b)-F056", + "link-tp-id": "Edfa0_fiber (f \u2192 b)-F056", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 5, + "unnumbered-hop": { + "node-id": "roadm b", + "link-tp-id": "roadm b", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 6, + "unnumbered-hop": { + "node-id": "trx b", + "link-tp-id": "trx b", + "hop-type": "vendorA_trx-type1 - mode 1", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + } + ] + } + }, + { + "path-id": "13", + "path-properties": { + "path-metric": [ + { + "metric-type": "SNR@bandwidth", + "accumulative-value": 16.81 + }, + { + "metric-type": "SNR@0.1nm", + "accumulative-value": 20.89 + }, + { + "metric-type": "OSNR@bandwidth", + "accumulative-value": 17.94 + }, + { + "metric-type": "OSNR@0.1nm", + "accumulative-value": 22.02 + }, + { + "metric-type": "reference_power", + "accumulative-value": 0.001 + } + ], + "path-srlgs": { + "usage": "not used yet", + "values": "not used yet" + }, + "path-route-objects": [ + { + "path-route-object": { + "index": 0, + "unnumbered-hop": { + "node-id": "trx c", + "link-tp-id": "trx c", + "hop-type": "vendorA_trx-type1 - mode 1", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 1, + "unnumbered-hop": { + "node-id": "roadm c", + "link-tp-id": "roadm c", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 2, + "unnumbered-hop": { + "node-id": "Edfa2_roadm c", + "link-tp-id": "Edfa2_roadm c", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 3, + "unnumbered-hop": { + "node-id": "fiber (c \u2192 f)-", + "link-tp-id": "fiber (c \u2192 f)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 4, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (c \u2192 f)-", + "link-tp-id": "Edfa0_fiber (c \u2192 f)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 5, + "unnumbered-hop": { + "node-id": "roadm f", + "link-tp-id": "roadm f", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 6, + "unnumbered-hop": { + "node-id": "trx f", + "link-tp-id": "trx f", + "hop-type": "vendorA_trx-type1 - mode 1", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + } + ] + } + }, + { + "path-id": "ee", + "path-properties": { + "path-metric": [ + { + "metric-type": "SNR@bandwidth", + "accumulative-value": 16.81 + }, + { + "metric-type": "SNR@0.1nm", + "accumulative-value": 20.89 + }, + { + "metric-type": "OSNR@bandwidth", + "accumulative-value": 17.94 + }, + { + "metric-type": "OSNR@0.1nm", + "accumulative-value": 22.02 + }, + { + "metric-type": "reference_power", + "accumulative-value": 0.001 + } + ], + "path-srlgs": { + "usage": "not used yet", + "values": "not used yet" + }, + "path-route-objects": [ + { + "path-route-object": { + "index": 0, + "unnumbered-hop": { + "node-id": "trx c", + "link-tp-id": "trx c", + "hop-type": "vendorA_trx-type1 - mode 1", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 1, + "unnumbered-hop": { + "node-id": "roadm c", + "link-tp-id": "roadm c", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 2, + "unnumbered-hop": { + "node-id": "Edfa1_roadm c", + "link-tp-id": "Edfa1_roadm c", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 3, + "unnumbered-hop": { + "node-id": "fiber (c \u2192 d)-", + "link-tp-id": "fiber (c \u2192 d)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 4, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (c \u2192 d)-", + "link-tp-id": "Edfa0_fiber (c \u2192 d)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 5, + "unnumbered-hop": { + "node-id": "roadm d", + "link-tp-id": "roadm d", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 6, + "unnumbered-hop": { + "node-id": "Edfa1_roadm d", + "link-tp-id": "Edfa1_roadm d", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 7, + "unnumbered-hop": { + "node-id": "fiber (d \u2192 e)-F057", + "link-tp-id": "fiber (d \u2192 e)-F057", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 8, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (d \u2192 e)-F057", + "link-tp-id": "Edfa0_fiber (d \u2192 e)-F057", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 9, + "unnumbered-hop": { + "node-id": "roadm e", + "link-tp-id": "roadm e", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 10, + "unnumbered-hop": { + "node-id": "Edfa1_roadm e", + "link-tp-id": "Edfa1_roadm e", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 11, + "unnumbered-hop": { + "node-id": "fiber (e \u2192 g)-", + "link-tp-id": "fiber (e \u2192 g)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 12, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (e \u2192 g)-", + "link-tp-id": "Edfa0_fiber (e \u2192 g)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 13, + "unnumbered-hop": { + "node-id": "roadm g", + "link-tp-id": "roadm g", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 14, + "unnumbered-hop": { + "node-id": "Edfa1_roadm g", + "link-tp-id": "Edfa1_roadm g", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 15, + "unnumbered-hop": { + "node-id": "fiber (g \u2192 h)-", + "link-tp-id": "fiber (g \u2192 h)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 16, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (g \u2192 h)-", + "link-tp-id": "Edfa0_fiber (g \u2192 h)-", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 17, + "unnumbered-hop": { + "node-id": "roadm h", + "link-tp-id": "roadm h", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 18, + "unnumbered-hop": { + "node-id": "Edfa0_roadm h", + "link-tp-id": "Edfa0_roadm h", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 19, + "unnumbered-hop": { + "node-id": "fiber (h \u2192 f)-F060", + "link-tp-id": "fiber (h \u2192 f)-F060", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 20, + "unnumbered-hop": { + "node-id": "Edfa0_fiber (h \u2192 f)-F060", + "link-tp-id": "Edfa0_fiber (h \u2192 f)-F060", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 21, + "unnumbered-hop": { + "node-id": "roadm f", + "link-tp-id": "roadm f", + "hop-type": "not recorded", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + }, + { + "path-route-object": { + "index": 22, + "unnumbered-hop": { + "node-id": "trx f", + "link-tp-id": "trx f", + "hop-type": "vendorA_trx-type1 - mode 1", + "direction": "not used" + }, + "label-hop": { + "te-label": { + "generic": "not used yet", + "direction": "not used yet" + } + } + } + } + ] + } + } + ] +} \ No newline at end of file diff --git a/tests/data/meshTopologyToy_services.json b/tests/data/meshTopologyToy_services.json new file mode 100644 index 00000000..83e5ae85 --- /dev/null +++ b/tests/data/meshTopologyToy_services.json @@ -0,0 +1,692 @@ +{ + "path-request": [ + { + "request-id": "1", + "source": "a", + "destination": "g", + "src-tp-id": "trx a", + "dst-tp-id": "trx g", + "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": 300000000000.0 + } + }, + "optimizations": { + "explicit-route-include-objects": [] + } + }, + { + "request-id": "2a", + "source": "a", + "destination": "h", + "src-tp-id": "trx a", + "dst-tp-id": "trx h", + "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.001, + "path_bandwidth": 300000000000.0 + } + }, + "optimizations": { + "explicit-route-include-objects": [] + } + }, + { + "request-id": "3", + "source": "f", + "destination": "b", + "src-tp-id": "trx f", + "dst-tp-id": "trx b", + "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.001, + "path_bandwidth": 300000000000.0 + } + }, + "optimizations": { + "explicit-route-include-objects": [] + } + }, + { + "request-id": "ee", + "source": "c", + "destination": "f", + "src-tp-id": "trx c", + "dst-tp-id": "trx f", + "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.001, + "path_bandwidth": 300000000000.0 + } + }, + "optimizations": { + "explicit-route-include-objects": [ + { + "index": 0, + "unnumbered-hop": { + "node-id": "roadm e", + "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": "roadm g", + "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": "ff", + "source": "c", + "destination": "f", + "src-tp-id": "trx c", + "dst-tp-id": "trx f", + "path-constraints": { + "te-bandwidth": { + "technology": "flexi-grid", + "trx_type": "Voyager", + "trx_mode": "mode 2 - fake", + "effective-freq-slot": [ + { + "n": "null", + "m": "null" + } + ], + "spacing": 75000000000.0, + "max-nb-of-channel": 63, + "output-power": 0.001, + "path_bandwidth": 300000000000.0 + } + }, + "optimizations": { + "explicit-route-include-objects": [] + } + }, + { + "request-id": "10", + "source": "a", + "destination": "g", + "src-tp-id": "trx a", + "dst-tp-id": "trx g", + "path-constraints": { + "te-bandwidth": { + "technology": "flexi-grid", + "trx_type": "Voyager", + "trx_mode": "mode 2", + "effective-freq-slot": [ + { + "n": "null", + "m": "null" + } + ], + "spacing": 75000000000.0, + "max-nb-of-channel": 63, + "output-power": 0.001, + "path_bandwidth": 300000000000.0 + } + }, + "optimizations": { + "explicit-route-include-objects": [] + } + }, + { + "request-id": "11", + "source": "a", + "destination": "h", + "src-tp-id": "trx a", + "dst-tp-id": "trx h", + "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.001, + "path_bandwidth": 300000000000.0 + } + }, + "optimizations": { + "explicit-route-include-objects": [ + { + "index": 0, + "unnumbered-hop": { + "node-id": "bb", + "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": "12", + "source": "f", + "destination": "b", + "src-tp-id": "trx f", + "dst-tp-id": "trx b", + "path-constraints": { + "te-bandwidth": { + "technology": "flexi-grid", + "trx_type": "Voyager", + "trx_mode": "mode 3", + "effective-freq-slot": [ + { + "n": "null", + "m": "null" + } + ], + "spacing": 62500000000.0, + "max-nb-of-channel": 76, + "output-power": 0.001, + "path_bandwidth": 300000000000.0 + } + }, + "optimizations": { + "explicit-route-include-objects": [ + { + "index": 0, + "unnumbered-hop": { + "node-id": "trx b", + "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": "13", + "source": "c", + "destination": "f", + "src-tp-id": "trx c", + "dst-tp-id": "trx f", + "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.001, + "path_bandwidth": 300000000000.0 + } + }, + "optimizations": { + "explicit-route-include-objects": [] + } + }, + { + "request-id": "14", + "source": "c", + "destination": "f", + "src-tp-id": "trx c", + "dst-tp-id": "trx f", + "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.001, + "path_bandwidth": 300000000000.0 + } + }, + "optimizations": { + "explicit-route-include-objects": [ + { + "index": 0, + "unnumbered-hop": { + "node-id": "roadm e", + "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": "roadm g", + "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": "e:1# /", + "source": "a", + "destination": "g", + "src-tp-id": "trx a", + "dst-tp-id": "trx g", + "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": null, + "path_bandwidth": 300000000000.0 + } + }, + "optimizations": { + "explicit-route-include-objects": [] + } + }, + { + "request-id": "b-2a", + "source": "a", + "destination": "h", + "src-tp-id": "trx a", + "dst-tp-id": "trx h", + "path-constraints": { + "te-bandwidth": { + "technology": "flexi-grid", + "trx_type": "Voyager", + "trx_mode": "mode 1", + "effective-freq-slot": [ + { + "n": "null", + "m": "null" + } + ], + "spacing": 50000000000.0, + "max-nb-of-channel": null, + "output-power": 0.001, + "path_bandwidth": 300000000000.0 + } + }, + "optimizations": { + "explicit-route-include-objects": [] + } + }, + { + "request-id": "3a;?", + "source": "f", + "destination": "b", + "src-tp-id": "trx f", + "dst-tp-id": "trx b", + "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": null, + "output-power": null, + "path_bandwidth": 300000000000.0 + } + }, + "optimizations": { + "explicit-route-include-objects": [] + } + }, + { + "request-id": "ee-s", + "source": "c", + "destination": "f", + "src-tp-id": "trx c", + "dst-tp-id": "trx f", + "path-constraints": { + "te-bandwidth": { + "technology": "flexi-grid", + "trx_type": "vendorA_trx-type1", + "trx_mode": null, + "effective-freq-slot": [ + { + "n": "null", + "m": "null" + } + ], + "spacing": 50000000000.0, + "max-nb-of-channel": 80, + "output-power": 0.001, + "path_bandwidth": 300000000000.0 + } + }, + "optimizations": { + "explicit-route-include-objects": [ + { + "index": 0, + "unnumbered-hop": { + "node-id": "roadm e", + "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": "roadm g", + "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": "ff-b", + "source": "c", + "destination": "f", + "src-tp-id": "trx c", + "dst-tp-id": "trx f", + "path-constraints": { + "te-bandwidth": { + "technology": "flexi-grid", + "trx_type": "Voyager", + "trx_mode": null, + "effective-freq-slot": [ + { + "n": "null", + "m": "null" + } + ], + "spacing": 50000000000.0, + "max-nb-of-channel": null, + "output-power": 0.001, + "path_bandwidth": 300000000000.0 + } + }, + "optimizations": { + "explicit-route-include-objects": [] + } + }, + { + "request-id": "10-z", + "source": "a", + "destination": "g", + "src-tp-id": "trx a", + "dst-tp-id": "trx g", + "path-constraints": { + "te-bandwidth": { + "technology": "flexi-grid", + "trx_type": "Voyager", + "trx_mode": null, + "effective-freq-slot": [ + { + "n": "null", + "m": "null" + } + ], + "spacing": 75000000000.0, + "max-nb-of-channel": 63, + "output-power": null, + "path_bandwidth": 300000000000.0 + } + }, + "optimizations": { + "explicit-route-include-objects": [] + } + }, + { + "request-id": "11 g", + "source": "a", + "destination": "h", + "src-tp-id": "trx a", + "dst-tp-id": "trx h", + "path-constraints": { + "te-bandwidth": { + "technology": "flexi-grid", + "trx_type": "Voyager", + "trx_mode": null, + "effective-freq-slot": [ + { + "n": "null", + "m": "null" + } + ], + "spacing": 50000000000.0, + "max-nb-of-channel": null, + "output-power": null, + "path_bandwidth": 300000000000.0 + } + }, + "optimizations": { + "explicit-route-include-objects": [] + } + }, + { + "request-id": "12<", + "source": "f", + "destination": "b", + "src-tp-id": "trx f", + "dst-tp-id": "trx b", + "path-constraints": { + "te-bandwidth": { + "technology": "flexi-grid", + "trx_type": "Voyager", + "trx_mode": null, + "effective-freq-slot": [ + { + "n": "null", + "m": "null" + } + ], + "spacing": 75000000000.0, + "max-nb-of-channel": null, + "output-power": null, + "path_bandwidth": null + } + }, + "optimizations": { + "explicit-route-include-objects": [] + } + }, + { + "request-id": "12>", + "source": "f", + "destination": "b", + "src-tp-id": "trx f", + "dst-tp-id": "trx b", + "path-constraints": { + "te-bandwidth": { + "technology": "flexi-grid", + "trx_type": "Voyager", + "trx_mode": null, + "effective-freq-slot": [ + { + "n": "null", + "m": "null" + } + ], + "spacing": 30000000000.0, + "max-nb-of-channel": null, + "output-power": null, + "path_bandwidth": null + } + }, + "optimizations": { + "explicit-route-include-objects": [] + } + } + ], + "synchronization": [ + { + "synchronization-id": "1", + "svec": { + "relaxable": "False", + "link-diverse": "True", + "node-diverse": "True", + "request-id-number": [ + "1", + "2a" + ] + } + }, + { + "synchronization-id": "3", + "svec": { + "relaxable": "False", + "link-diverse": "True", + "node-diverse": "True", + "request-id-number": [ + "3", + "1" + ] + } + }, + { + "synchronization-id": "ff", + "svec": { + "relaxable": "False", + "link-diverse": "True", + "node-diverse": "True", + "request-id-number": [ + "ff", + "13" + ] + } + }, + { + "synchronization-id": "13", + "svec": { + "relaxable": "False", + "link-diverse": "True", + "node-diverse": "True", + "request-id-number": [ + "13", + "14" + ] + } + } + ] +} diff --git a/tests/test_amplifier.py b/tests/test_amplifier.py index e6eceffb..dc0dac4f 100644 --- a/tests/test_amplifier.py +++ b/tests/test_amplifier.py @@ -5,11 +5,11 @@ from gnpy.core.elements import Edfa from numpy import zeros, array -from json import load, dumps +from json import load from gnpy.core.elements import Transceiver, Fiber, Edfa from gnpy.core.utils import lin2db, db2lin from gnpy.core.info import create_input_spectral_information, SpectralInformation, Channel, Power, Pref -from gnpy.core.equipment import load_equipment +from gnpy.core.equipment import load_equipment, automatic_fmax from gnpy.core.network import build_network, load_network, set_roadm_loss from pathlib import Path import pytest @@ -66,7 +66,9 @@ def setup_trx(): def si(nch_and_spacing, bw): """parametrize a channel comb with nb_channel, spacing and signal bw""" nb_channel, spacing = nch_and_spacing - return create_input_spectral_information(191.3e12, 0.15, bw, 1e-3, spacing, nb_channel) + f_min = 191.3e12 + f_max = automatic_fmax(f_min, spacing, nb_channel) + return create_input_spectral_information(f_min, f_max, 0.15, bw, 1e-3, spacing) @pytest.mark.parametrize("gain, nf_expected", [(10, 15), (15, 10), (25, 5.8)]) def test_variable_gain_nf(gain, nf_expected, setup_edfa_variable_gain, si): diff --git a/tests/test_automaticmodefeature.py b/tests/test_automaticmodefeature.py new file mode 100644 index 00000000..6f6fb9c6 --- /dev/null +++ b/tests/test_automaticmodefeature.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python3 +# TelecomInfraProject/gnpy/examples +# Module name : test_automaticmodefeature.py +# Version : +# License : BSD 3-Clause Licence +# Copyright (c) 2018, Telecom Infra Project + +""" +@author: esther.lerouzic +checks that empty info on mode, power, nbchannel in service file are supported + uses combination of [mode, pow, nb channel] filled or empty defined in meshTopologyToy_services.json + leading to feasible path or not, and check the propagate and propagate_and_optimize_mode + return the expected based on a reference toy example + +""" + +from pathlib import Path +import pytest +from gnpy.core.equipment import load_equipment, trx_mode_params, automatic_nch +from gnpy.core.network import load_network, build_network +from examples.path_requests_run import (requests_from_json , correct_route_list , + load_requests , disjunctions_from_json) +from gnpy.core.request import (compute_path_dsjctn, isdisjoint , find_reversed_path, + propagate,propagate_and_optimize_mode) +from gnpy.core.utils import db2lin, lin2db +from gnpy.core.elements import Roadm + +network_file_name = Path(__file__).parent.parent / 'tests/data/meshTopologyToy.json' +service_file_name = Path(__file__).parent.parent / 'tests/data/meshTopologyToy_services.json' +result_file_name = Path(__file__).parent.parent / 'tests/data/meshTopologyToy_results.json' +eqpt_library_name = Path(__file__).parent.parent / 'tests/data/eqpt_config.json' + +@pytest.mark.parametrize("net",[network_file_name]) +@pytest.mark.parametrize("eqpt", [eqpt_library_name]) +@pytest.mark.parametrize("serv",[service_file_name]) +@pytest.mark.parametrize("expected_mode",[['16QAM', 'PS_SP64_1', 'PS_SP64_1', 'PS_SP64_1', 'mode 2 - fake', 'mode 2', 'PS_SP64_1', 'mode 3', 'PS_SP64_1', 'PS_SP64_1', '16QAM', 'mode 1', 'PS_SP64_1', 'PS_SP64_1', 'mode 1', 'mode 2', 'mode 1', 'mode 2', 'nok']]) +def test_automaticmodefeature(net,eqpt,serv,expected_mode): + data = load_requests(serv,eqpt) + equipment = load_equipment(eqpt) + network = load_network(net,equipment) + + # Build the network once using the default power defined in SI in eqpt config + # power density : db2linp(ower_dbm": 0)/power_dbm": 0 * nb channels as defined by + # spacing, f_min and f_max + 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) + + rqs = requests_from_json(data, equipment) + rqs = correct_route_list(network, rqs) + dsjn = [] + pths = compute_path_dsjctn(network, equipment, rqs, dsjn) + path_res_list = [] + + for i,pathreq in enumerate(rqs): + + # use the power specified in requests but might be different from the one specified for design + # the power is an optional parameter for requests definition + # if optional, use the one defines in eqt_config.json + p_db = lin2db(pathreq.power*1e3) + p_total_db = p_db + lin2db(pathreq.nb_channel) + print(f'request {pathreq.request_id}') + print(f'Computing path from {pathreq.source} to {pathreq.destination}') + print(f'with path constraint: {[pathreq.source]+pathreq.nodes_list}') #adding first node to be clearer on the output + + total_path = pths[i] + print(f'Computed path (roadms):{[e.uid for e in total_path if isinstance(e, Roadm)]}\n') + # for debug + # print(f'{pathreq.baud_rate} {pathreq.power} {pathreq.spacing} {pathreq.nb_channel}') + if pathreq.baud_rate is not None: + print(pathreq.format) + path_res_list.append(pathreq.format) + total_path = propagate(total_path,pathreq,equipment, show=False) + else: + total_path,mode = propagate_and_optimize_mode(total_path,pathreq,equipment) + # if no baudrate satisfies spacing, no mode is returned and an empty path is returned + # a warning is shown in the propagate_and_optimize_mode + if mode is not None : + print (mode['format']) + path_res_list.append(mode['format']) + else : + print('nok') + path_res_list.append('nok') + print(path_res_list) + assert path_res_list==expected_mode + diff --git a/tests/test_disjunction.py b/tests/test_disjunction.py new file mode 100644 index 00000000..286851b4 --- /dev/null +++ b/tests/test_disjunction.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python3 +# TelecomInfraProject/gnpy/examples +# Module name : test_disjunction.py +# Version : +# License : BSD 3-Clause Licence +# Copyright (c) 2018, Telecom Infra Project + +""" +@author: esther.lerouzic +checks that computed paths are disjoint as specified in the json service file +""" + +from pathlib import Path +import pytest +from gnpy.core.equipment import load_equipment, trx_mode_params, automatic_nch +from gnpy.core.network import load_network, build_network +from examples.path_requests_run import (requests_from_json , correct_route_list , + load_requests , disjunctions_from_json) +from gnpy.core.request import compute_path_dsjctn, isdisjoint , find_reversed_path +from gnpy.core.utils import db2lin, lin2db +from gnpy.core.elements import Roadm + +network_file_name = Path(__file__).parent.parent / 'tests/data/meshTopologyToy.json' +service_file_name = Path(__file__).parent.parent / 'tests/data/meshTopologyToy_services.json' +result_file_name = Path(__file__).parent.parent / 'tests/data/meshTopologyToy_results.json' +eqpt_library_name = Path(__file__).parent.parent / 'tests/data/eqpt_config.json' + +@pytest.mark.parametrize("net",[network_file_name]) +@pytest.mark.parametrize("eqpt", [eqpt_library_name]) +@pytest.mark.parametrize("serv",[service_file_name]) +def test_disjunction(net,eqpt,serv): + data = load_requests(serv,eqpt) + equipment = load_equipment(eqpt) + network = load_network(net,equipment) + + # Build the network once using the default power defined in SI in eqpt config + # power density : db2linp(ower_dbm": 0)/power_dbm": 0 * nb channels as defined by + # spacing, f_min and f_max + 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) + + rqs = requests_from_json(data, equipment) + rqs = correct_route_list(network, rqs) + dsjn = disjunctions_from_json(data) + pths = compute_path_dsjctn(network, equipment, rqs, dsjn) + print(dsjn) + + dsjn_list = [d.disjunctions_req for d in dsjn ] + + # assumes only pairs in dsjn list + test = True + for e in dsjn_list: + rqs_id_list = [r.request_id for r in rqs] + p1 = pths[rqs_id_list.index(e[0])][1:-1] + p2 = pths[rqs_id_list.index(e[1])][1:-1] + if isdisjoint(p1,p2) + isdisjoint(p1,find_reversed_path(p2, network)) > 0: + test = False + print(f'Computed path (roadms):{[e.uid for e in p1 if isinstance(e, Roadm)]}\n') + print(f'Computed path (roadms):{[e.uid for e in p2 if isinstance(e, Roadm)]}\n') + break + print(dsjn_list) + assert test + +@pytest.mark.parametrize("net",[network_file_name]) +@pytest.mark.parametrize("eqpt", [eqpt_library_name]) +@pytest.mark.parametrize("serv",[service_file_name]) +def test_does_not_loop_back(net,eqpt,serv): + data = load_requests(serv,eqpt) + equipment = load_equipment(eqpt) + network = load_network(net,equipment) + + # Build the network once using the default power defined in SI in eqpt config + # power density : db2linp(ower_dbm": 0)/power_dbm": 0 * nb channels as defined by + # spacing, f_min and f_max + 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) + + rqs = requests_from_json(data, equipment) + rqs = correct_route_list(network, rqs) + dsjn = disjunctions_from_json(data) + pths = compute_path_dsjctn(network, equipment, rqs, dsjn) + + # check that computed paths do not loop back ie each element appears only once + test = True + for p in pths : + for el in p: + p.remove(el) + a = [e for e in p if e.uid == el.uid] + if a : + test = False + break + + assert test + + # TODO : test that identical requests are correctly agregated + # and reproduce disjunction vector as well as route constraints + # check that requests with different parameters are not aggregated + + # check that the total agregated bandwidth is the same after aggregation + + # \ No newline at end of file diff --git a/tests/test_parser.py b/tests/test_parser.py index dbfe94b9..a3c037a4 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -37,11 +37,11 @@ def test_excel_json_generation(xls_input, expected_json_output): convert_file(xls_input) actual_json_output = xls_input.with_suffix('.json') - with open(actual_json_output) as f: + with open(actual_json_output, encoding='utf-8') as f: actual = load(f) - unlink(actual_json_output) + #unlink(actual_json_output) - with open(expected_json_output) as f: + with open(expected_json_output, encoding='utf-8') as f: expected = load(f) results = compare_networks(expected, actual) @@ -65,11 +65,11 @@ def test_excel_service_json_generation(xls_input, expected_json_output): convert_service_sheet(xls_input, eqpt_filename) actual_json_output = f'{str(xls_input)[:-4]}_services.json' - with open(actual_json_output) as f: + with open(actual_json_output, encoding='utf-8') as f: actual = load(f) unlink(actual_json_output) - with open(expected_json_output) as f: + with open(expected_json_output, encoding='utf-8') as f: expected = load(f) results = compare_services(expected, actual) diff --git a/tests/test_propagation.py b/tests/test_propagation.py index 08400024..c2e77ec7 100644 --- a/tests/test_propagation.py +++ b/tests/test_propagation.py @@ -5,7 +5,7 @@ from gnpy.core.elements import Edfa import numpy as np -from json import load, dumps +from json import load import pytest from gnpy.core.elements import Transceiver, Fiber, Edfa from gnpy.core.utils import lin2db, db2lin