mirror of
				https://github.com/Telecominfraproject/oopt-gnpy.git
				synced 2025-10-31 18:18:00 +00:00 
			
		
		
		
	Compare commits
	
		
			41 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 99f44a597b | ||
|   | a21f3fe6ee | ||
|   | 0ccbb2960c | ||
|   | 87cc3dac00 | ||
|   | 89e28cc7be | ||
|   | 2ba29a78c5 | ||
|   | f990a6c1be | ||
|   | 424e5a4786 | ||
|   | 6a7a04ebb1 | ||
|   | 0366fc2956 | ||
|   | 48b7d71f02 | ||
|   | 715baf2a1c | ||
|   | e55cea776e | ||
|   | b388d143fd | ||
|   | c592c572d8 | ||
|   | dfa0a26a28 | ||
|   | 609cd94798 | ||
|   | 022f743db1 | ||
|   | 1957beb1b6 | ||
|   | 9ca72d6105 | ||
|   | e8e126a6ce | ||
|   | 7849782173 | ||
|   | 149a0da8c9 | ||
|   | 1e7c70a59b | ||
|   | c9d8282e7f | ||
|   | e7084a2c29 | ||
|   | d79d2e0724 | ||
|   | 402155c225 | ||
|   | e5ec669419 | ||
|   | 8f424e8c9d | ||
|   | fea2b84bb9 | ||
|   | 0c918940c4 | ||
|   | a63a6ac0ec | ||
|   | 9f58b914d2 | ||
|   | 029bac4b03 | ||
|   | a27ad57220 | ||
|   | 8d31d924f2 | ||
|   | 8c3b514f90 | ||
|   | 3df27fe315 | ||
|   | a6087ce354 | ||
|   | aae0382523 | 
| @@ -7,7 +7,7 @@ | ||||
| `gnpy`: mesh optical network route planning and optimization library | ||||
| ==================================================================== | ||||
|  | ||||
| |docs| |build| | ||||
| |docs| |build| |doi| | ||||
|  | ||||
| **`gnpy` is an open-source, community-developed library for building route | ||||
| planning and optimization tools in real-world mesh optical networks.** | ||||
| @@ -601,6 +601,11 @@ implementations. | ||||
|   :alt: Build Status | ||||
|   :scale: 100% | ||||
|  | ||||
| .. |doi| image:: https://zenodo.org/badge/96894149.svg | ||||
|   :target: https://zenodo.org/badge/latestdoi/96894149 | ||||
|   :alt: DOI | ||||
|   :scale: 100% | ||||
|  | ||||
| TIP OOPT/PSE & PSE WG Charter | ||||
| ----------------------------- | ||||
|  | ||||
|   | ||||
| @@ -2,8 +2,8 @@ | ||||
|   "path-request": [ | ||||
|     { | ||||
|       "request-id": "0", | ||||
|       "source": "Lorient_KMA", | ||||
|       "destination": "Vannes_KBE", | ||||
|       "source": "trx Lorient_KMA", | ||||
|       "destination": "trx Vannes_KBE", | ||||
|       "src-tp-id": "trx Lorient_KMA", | ||||
|       "dst-tp-id": "trx Vannes_KBE", | ||||
|       "path-constraints": { | ||||
| @@ -13,8 +13,8 @@ | ||||
|           "trx_mode": null, | ||||
|           "effective-freq-slot": [ | ||||
|             { | ||||
|               "n": "null", | ||||
|               "m": "null" | ||||
|               "N": "null", | ||||
|               "M": "null" | ||||
|             } | ||||
|           ], | ||||
|           "spacing": 50000000000.0, | ||||
| @@ -22,15 +22,12 @@ | ||||
|           "output-power": 0.0012589254117941673, | ||||
|           "path_bandwidth": 100000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "1", | ||||
|       "source": "Brest_KLA", | ||||
|       "destination": "Vannes_KBE", | ||||
|       "source": "trx Brest_KLA", | ||||
|       "destination": "trx Vannes_KBE", | ||||
|       "src-tp-id": "trx Brest_KLA", | ||||
|       "dst-tp-id": "trx Vannes_KBE", | ||||
|       "path-constraints": { | ||||
| @@ -40,8 +37,8 @@ | ||||
|           "trx_mode": "mode 1", | ||||
|           "effective-freq-slot": [ | ||||
|             { | ||||
|               "n": "null", | ||||
|               "m": "null" | ||||
|               "N": "null", | ||||
|               "M": "null" | ||||
|             } | ||||
|           ], | ||||
|           "spacing": 50000000000.0, | ||||
| @@ -50,66 +47,42 @@ | ||||
|           "path_bandwidth": 200000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [ | ||||
|       "explicit-route-objects": { | ||||
|         "route-object-include-exclude": [ | ||||
|           { | ||||
|             "explicit-route-usage": "route-include-ero", | ||||
|             "index": 0, | ||||
|             "unnumbered-hop": { | ||||
|             "num-unnum-hop": { | ||||
|               "node-id": "roadm Brest_KLA", | ||||
|               "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" | ||||
|               } | ||||
|               "hop-type": "LOOSE" | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "explicit-route-usage": "route-include-ero", | ||||
|             "index": 1, | ||||
|             "unnumbered-hop": { | ||||
|             "num-unnum-hop": { | ||||
|               "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" | ||||
|               } | ||||
|               "hop-type": "LOOSE" | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "explicit-route-usage": "route-include-ero", | ||||
|             "index": 2, | ||||
|             "unnumbered-hop": { | ||||
|             "num-unnum-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" | ||||
|               } | ||||
|               "hop-type": "LOOSE" | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "explicit-route-usage": "route-include-ero", | ||||
|             "index": 3, | ||||
|             "unnumbered-hop": { | ||||
|             "num-unnum-hop": { | ||||
|               "node-id": "roadm Vannes_KBE", | ||||
|               "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" | ||||
|               } | ||||
|               "hop-type": "LOOSE" | ||||
|             } | ||||
|           } | ||||
|         ] | ||||
| @@ -117,8 +90,8 @@ | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "3", | ||||
|       "source": "Lannion_CAS", | ||||
|       "destination": "Rennes_STA", | ||||
|       "source": "trx Lannion_CAS", | ||||
|       "destination": "trx Rennes_STA", | ||||
|       "src-tp-id": "trx Lannion_CAS", | ||||
|       "dst-tp-id": "trx Rennes_STA", | ||||
|       "path-constraints": { | ||||
| @@ -128,8 +101,8 @@ | ||||
|           "trx_mode": "mode 1", | ||||
|           "effective-freq-slot": [ | ||||
|             { | ||||
|               "n": "null", | ||||
|               "m": "null" | ||||
|               "N": "null", | ||||
|               "M": "null" | ||||
|             } | ||||
|           ], | ||||
|           "spacing": 50000000000.0, | ||||
| @@ -137,15 +110,12 @@ | ||||
|           "output-power": null, | ||||
|           "path_bandwidth": 60000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "4", | ||||
|       "source": "Rennes_STA", | ||||
|       "destination": "Lannion_CAS", | ||||
|       "source": "trx Rennes_STA", | ||||
|       "destination": "trx Lannion_CAS", | ||||
|       "src-tp-id": "trx Rennes_STA", | ||||
|       "dst-tp-id": "trx Lannion_CAS", | ||||
|       "path-constraints": { | ||||
| @@ -155,8 +125,8 @@ | ||||
|           "trx_mode": null, | ||||
|           "effective-freq-slot": [ | ||||
|             { | ||||
|               "n": "null", | ||||
|               "m": "null" | ||||
|               "N": "null", | ||||
|               "M": "null" | ||||
|             } | ||||
|           ], | ||||
|           "spacing": 75000000000.0, | ||||
| @@ -164,15 +134,12 @@ | ||||
|           "output-power": 0.0019952623149688794, | ||||
|           "path_bandwidth": 150000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "5", | ||||
|       "source": "Rennes_STA", | ||||
|       "destination": "Lannion_CAS", | ||||
|       "source": "trx Rennes_STA", | ||||
|       "destination": "trx Lannion_CAS", | ||||
|       "src-tp-id": "trx Rennes_STA", | ||||
|       "dst-tp-id": "trx Lannion_CAS", | ||||
|       "path-constraints": { | ||||
| @@ -182,8 +149,8 @@ | ||||
|           "trx_mode": "mode 2", | ||||
|           "effective-freq-slot": [ | ||||
|             { | ||||
|               "n": "null", | ||||
|               "m": "null" | ||||
|               "N": "null", | ||||
|               "M": "null" | ||||
|             } | ||||
|           ], | ||||
|           "spacing": 75000000000.0, | ||||
| @@ -191,15 +158,12 @@ | ||||
|           "output-power": 0.0019952623149688794, | ||||
|           "path_bandwidth": 20000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "6", | ||||
|       "source": "Lannion_CAS", | ||||
|       "destination": "Lorient_KMA", | ||||
|       "source": "trx Lannion_CAS", | ||||
|       "destination": "trx Lorient_KMA", | ||||
|       "src-tp-id": "trx Lannion_CAS", | ||||
|       "dst-tp-id": "trx Lorient_KMA", | ||||
|       "path-constraints": { | ||||
| @@ -209,8 +173,8 @@ | ||||
|           "trx_mode": "mode 1", | ||||
|           "effective-freq-slot": [ | ||||
|             { | ||||
|               "n": "null", | ||||
|               "m": "null" | ||||
|               "N": "null", | ||||
|               "M": "null" | ||||
|             } | ||||
|           ], | ||||
|           "spacing": 50000000000.0, | ||||
| @@ -218,15 +182,12 @@ | ||||
|           "output-power": 0.001, | ||||
|           "path_bandwidth": 300000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "7", | ||||
|       "source": "Lannion_CAS", | ||||
|       "destination": "Lorient_KMA", | ||||
|       "source": "trx Lannion_CAS", | ||||
|       "destination": "trx Lorient_KMA", | ||||
|       "src-tp-id": "trx Lannion_CAS", | ||||
|       "dst-tp-id": "trx Lorient_KMA", | ||||
|       "path-constraints": { | ||||
| @@ -236,8 +197,8 @@ | ||||
|           "trx_mode": "mode 1", | ||||
|           "effective-freq-slot": [ | ||||
|             { | ||||
|               "n": "null", | ||||
|               "m": "null" | ||||
|               "N": "null", | ||||
|               "M": "null" | ||||
|             } | ||||
|           ], | ||||
|           "spacing": 50000000000.0, | ||||
| @@ -245,15 +206,12 @@ | ||||
|           "output-power": 0.001, | ||||
|           "path_bandwidth": 400000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "7b", | ||||
|       "source": "Lannion_CAS", | ||||
|       "destination": "Lorient_KMA", | ||||
|       "source": "trx Lannion_CAS", | ||||
|       "destination": "trx Lorient_KMA", | ||||
|       "src-tp-id": "trx Lannion_CAS", | ||||
|       "dst-tp-id": "trx Lorient_KMA", | ||||
|       "path-constraints": { | ||||
| @@ -263,8 +221,8 @@ | ||||
|           "trx_mode": "mode 1", | ||||
|           "effective-freq-slot": [ | ||||
|             { | ||||
|               "n": "null", | ||||
|               "m": "null" | ||||
|               "N": "null", | ||||
|               "M": "null" | ||||
|             } | ||||
|           ], | ||||
|           "spacing": 75000000000.0, | ||||
| @@ -272,9 +230,6 @@ | ||||
|           "output-power": 0.001, | ||||
|           "path_bandwidth": 400000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [] | ||||
|       } | ||||
|     } | ||||
|   ], | ||||
| @@ -282,9 +237,8 @@ | ||||
|     { | ||||
|       "synchronization-id": "3", | ||||
|       "svec": { | ||||
|         "relaxable": "False", | ||||
|         "link-diverse": "True", | ||||
|         "node-diverse": "True", | ||||
|         "relaxable": "false", | ||||
|         "disjointness": "node link", | ||||
|         "request-id-number": [ | ||||
|           "3", | ||||
|           "1" | ||||
| @@ -294,9 +248,8 @@ | ||||
|     { | ||||
|       "synchronization-id": "4", | ||||
|       "svec": { | ||||
|         "relaxable": "False", | ||||
|         "link-diverse": "True", | ||||
|         "node-diverse": "True", | ||||
|         "relaxable": "false", | ||||
|         "disjointness": "node link", | ||||
|         "request-id-number": [ | ||||
|           "4", | ||||
|           "5" | ||||
|   | ||||
| @@ -55,16 +55,18 @@ def requests_from_json(json_data,equipment): | ||||
|         # init all params from request | ||||
|         params = {} | ||||
|         params['request_id'] = req['request-id'] | ||||
|         params['source'] = req['src-tp-id'] | ||||
|         params['destination'] = req['dst-tp-id'] | ||||
|         params['source'] = req['source'] | ||||
|         params['destination'] = req['destination'] | ||||
|         params['trx_type'] = req['path-constraints']['te-bandwidth']['trx_type'] | ||||
|         params['trx_mode'] = req['path-constraints']['te-bandwidth']['trx_mode'] | ||||
|         params['format'] = params['trx_mode'] | ||||
|         nd_list = req['optimizations']['explicit-route-include-objects'] | ||||
|         params['nodes_list'] = [n['unnumbered-hop']['node-id'] for n in nd_list] | ||||
|         params['loose_list'] = [n['unnumbered-hop']['hop-type'] for n in nd_list] | ||||
|         params['spacing'] = req['path-constraints']['te-bandwidth']['spacing'] | ||||
|  | ||||
|         try : | ||||
|             nd_list = req['explicit-route-objects']['route-object-include-exclude'] | ||||
|         except KeyError: | ||||
|             nd_list = [] | ||||
|         params['nodes_list'] = [n['num-unnum-hop']['node-id'] for n in nd_list] | ||||
|         params['loose_list'] = [n['num-unnum-hop']['hop-type'] for n in nd_list] | ||||
|         # 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 | ||||
| @@ -73,20 +75,24 @@ def requests_from_json(json_data,equipment): | ||||
|         # 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'] | ||||
|  | ||||
|         try: | ||||
|             if req['path-constraints']['te-bandwidth']['output-power']: | ||||
|                 params['power'] = req['path-constraints']['te-bandwidth']['output-power'] | ||||
|         except KeyError: | ||||
|             pass | ||||
|         # 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 : | ||||
|         try: | ||||
|             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']) | ||||
|         except KeyError: | ||||
|             params['nb_channel'] = automatic_nch(f_min,f_max_from_si,params['spacing']) | ||||
|  | ||||
|         consistency_check(params, f_max_from_si) | ||||
|  | ||||
|         try : | ||||
| @@ -122,15 +128,20 @@ def consistency_check(params, f_max_from_si): | ||||
|  | ||||
| def disjunctions_from_json(json_data): | ||||
|     disjunctions_list = [] | ||||
|     try: | ||||
|         temp_test = json_data['synchronization'] | ||||
|     except KeyError: | ||||
|         temp_test = [] | ||||
|     if temp_test: | ||||
|         for snc in json_data['synchronization']: | ||||
|             params = {} | ||||
|             params['disjunction_id'] = snc['synchronization-id'] | ||||
|             params['relaxable'] = snc['svec']['relaxable'] | ||||
|             params['link_diverse'] = 'link' in snc['svec']['disjointness'] | ||||
|             params['node_diverse'] = 'node' in snc['svec']['disjointness'] | ||||
|             params['disjunctions_req'] = snc['svec']['request-id-number'] | ||||
|             disjunctions_list.append(Disjunction(**params)) | ||||
|  | ||||
|     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 | ||||
|  | ||||
|  | ||||
| @@ -205,7 +216,7 @@ 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)] | ||||
|     anytype = [n.uid for n in network.nodes()] | ||||
|     # 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)] | ||||
| @@ -214,9 +225,11 @@ def correct_route_list(network, pathreqlist): | ||||
|             # replace possibly wrong name with a formated roadm name | ||||
|             # print(n_id) | ||||
|             if n_id not in anytype : | ||||
|                 # find nodes name that include constraint among all possible names except | ||||
|                 # transponders (not yet supported as constraints). | ||||
|                 nodes_suggestion = [uid for uid in anytype \ | ||||
|                     if n_id.lower() in uid.lower()] | ||||
|                 if pathreq.loose_list[i] == 'loose': | ||||
|                     if n_id.lower() in uid.lower() and uid not in transponders] | ||||
|                 if pathreq.loose_list[i] == 'LOOSE': | ||||
|                     if len(nodes_suggestion)>0 : | ||||
|                         new_n = nodes_suggestion[0] | ||||
|                         print(f'invalid route node specified:\ | ||||
| @@ -257,7 +270,7 @@ def correct_disjn(disjn): | ||||
|  | ||||
| def path_result_json(pathresult): | ||||
|     data = { | ||||
|         'path': [n.json for n in pathresult] | ||||
|         'response': [n.json for n in pathresult] | ||||
|     } | ||||
|     return data | ||||
|  | ||||
|   | ||||
| @@ -157,11 +157,13 @@ def main(network, equipment, source, destination, sim_params, req=None): | ||||
|         if len(power_range) == 1: | ||||
|             for elem in path: | ||||
|                 print(elem) | ||||
|         if power_mode: | ||||
|             print(f'\nTransmission result for input power = {lin2db(req.power*1e3):.2f} dBm:') | ||||
|             if power_mode: | ||||
|                 print(f'\nTransmission result for input power = {lin2db(req.power*1e3):.2f} dBm:') | ||||
|             else: | ||||
|                 print(f'\nTransmission results:') | ||||
|             print(f'  Final SNR total (0.1 nm): {ansi_escapes.cyan}{mean(destination.snr_01nm):.02f} dB{ansi_escapes.reset}') | ||||
|         else: | ||||
|             print(f'\nTransmission results:') | ||||
|         print(f'  Final SNR total (signal bw): {ansi_escapes.cyan}{mean(destination.snr):.02f} dB{ansi_escapes.reset}') | ||||
|             print(path[-1]) | ||||
|  | ||||
|         #print(f'\n !!!!!!!!!!!!!!!!!     TEST POINT         !!!!!!!!!!!!!!!!!!!!!') | ||||
|         #print(f'carriers ase output of {path[1]} =\n {list(path[1].carriers("out", "nli"))}') | ||||
|   | ||||
| @@ -25,7 +25,7 @@ from collections import namedtuple | ||||
|  | ||||
| from gnpy.core.node import Node | ||||
| from gnpy.core.units import UNITS | ||||
| from gnpy.core.utils import lin2db, db2lin, itufs, itufl, snr_sum | ||||
| from gnpy.core.utils import lin2db, db2lin, arrange_frequencies, snr_sum | ||||
| from gnpy.core.science_utils import propagate_raman_fiber, _psi | ||||
|  | ||||
| class Transceiver(Node): | ||||
| @@ -615,7 +615,7 @@ class Edfa(Node): | ||||
|                 self.channel_freq, self.nf, self.interpol_dgt and self.interpol_gain_ripple | ||||
|         """ | ||||
|         # TODO|jla: read amplifier actual frequencies from additional params in json | ||||
|         amplifier_freq = itufl(len(self.params.dgt), self.params.f_min, self.params.f_max) # Hz | ||||
|         amplifier_freq = arrange_frequencies(len(self.params.dgt), self.params.f_min, self.params.f_max) # Hz | ||||
|         self.channel_freq = frequencies | ||||
|         self.interpol_dgt = interp(self.channel_freq, amplifier_freq, self.params.dgt) | ||||
|  | ||||
|   | ||||
| @@ -81,9 +81,9 @@ class Path_request: | ||||
|                             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'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']) | ||||
| @@ -97,16 +97,16 @@ class Disjunction: | ||||
|         self.disjunctions_req = params.disjunctions_req | ||||
|          | ||||
|     def __str__(self): | ||||
|         return '\n\t'.join([f'relaxable:    {self.relaxable}', | ||||
|                             f'link-diverse:       {self.link_diverse}', | ||||
|         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'link-diverse: {self.link_diverse}', | ||||
|                             f'node-diverse: {self.node_diverse}', | ||||
|                             f'request-id-numbers: {self.disjunctions_req}' | ||||
|                             '\n']) | ||||
|  | ||||
| @@ -115,149 +115,77 @@ class Result_element(Element): | ||||
|         self.path_id = path_request.request_id | ||||
|         self.path_request = path_request | ||||
|         self.computed_path = computed_path | ||||
|         hop_type = [] | ||||
|         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 | ||||
|     def pathresult(self): | ||||
|         if not self.computed_path: | ||||
|             return { | ||||
|                    'path-id': self.path_id, | ||||
|                    'path-properties':{ | ||||
|                        'path-metric': [ | ||||
|                            { | ||||
|                            'metric-type': 'SNR@bandwidth', | ||||
|                            'accumulative-value': 'None' | ||||
|                            }, | ||||
|                            { | ||||
|                            'metric-type': 'SNR@0.1nm', | ||||
|                            'accumulative-value': 'None' | ||||
|                            }, | ||||
|                            { | ||||
|                            'metric-type': 'OSNR@bandwidth', | ||||
|                            'accumulative-value': 'None' | ||||
|                            }, | ||||
|                            { | ||||
|                            'metric-type': 'OSNR@0.1nm', | ||||
|                            'accumulative-value': 'None' | ||||
|                            }, | ||||
|                            { | ||||
|                            'metric-type': 'reference_power', | ||||
|                            'accumulative-value': self.path_request.power | ||||
|                            }, | ||||
|                            { | ||||
|                            'metric-type': 'path_bandwidth', | ||||
|                            'accumulative-value': self.path_request.path_bandwidth | ||||
|                            } | ||||
|                         ], | ||||
|                         'path-srlgs': { | ||||
|                             'usage': 'not used yet', | ||||
|                             'values': 'not used yet' | ||||
|                         }, | ||||
|                         'path-route-objects': [ | ||||
|                             { | ||||
|                             'path-route-object': { | ||||
|                                 'index': 0, | ||||
|                                 'unnumbered-hop': { | ||||
|                                     'node-id': self.path_request.source, | ||||
|                                     'link-tp-id': self.path_request.source, | ||||
|                                     'hop-type':  self.hop_type, | ||||
|                                     'direction': 'not used' | ||||
|                                 }, | ||||
|                                 'label-hop': { | ||||
|                                     'te-label': { | ||||
|                                         'generic': 'not used yet', | ||||
|                                         'direction': 'not used yet' | ||||
|                                         } | ||||
|                                     } | ||||
|                                 } | ||||
|                             }, | ||||
|                             { | ||||
|                             'path-route-object': { | ||||
|                                 'index': 1, | ||||
|                                 'unnumbered-hop': { | ||||
|                                     'node-id': self.path_request.destination, | ||||
|                                     'link-tp-id': self.path_request.destination, | ||||
|                                     'hop-type':  self.hop_type, | ||||
|                                     'direction': 'not used' | ||||
|                                 }, | ||||
|                                 'label-hop': { | ||||
|                                     'te-label': { | ||||
|                                         'generic': 'not used yet', | ||||
|                                         'direction': 'not used yet' | ||||
|                                         } | ||||
|                                     } | ||||
|                    'response-id': self.path_id, | ||||
|                    'no-path': "Response without path information, due to failure performing the path computation" | ||||
|                    } | ||||
|         else: | ||||
|             index = 0 | ||||
|             pro_list = [] | ||||
|             for element in self.computed_path: | ||||
|                 temp = { | ||||
|                     'path-route-object': { | ||||
|                         'index': index, | ||||
|                         'num-unnum-hop': { | ||||
|                             'node-id': element.uid, | ||||
|                             'link-tp-id': element.uid, | ||||
|                             # TODO change index in order to insert transponder attribute | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 pro_list.append(temp) | ||||
|                 index += 1 | ||||
|                 if isinstance(element, Transceiver): | ||||
|                     temp = { | ||||
|                         'path-route-object': { | ||||
|                             'index': index, | ||||
|                             'transponder' : { | ||||
|                                'transponder-type' : self.path_request.tsp, | ||||
|                                'transponder-mode' : self.path_request.tsp_mode, | ||||
|                                 } | ||||
|                             } | ||||
|                             ] | ||||
|                     } | ||||
|                 } | ||||
|         else: | ||||
|             return { | ||||
|                    'path-id': self.path_id, | ||||
|                    'path-properties':{ | ||||
|                        'path-metric': [ | ||||
|                            { | ||||
|                            'metric-type': 'SNR@bandwidth', | ||||
|                            'accumulative-value': round(mean(self.computed_path[-1].snr),2) | ||||
|                            }, | ||||
|                            { | ||||
|                            'metric-type': 'SNR@0.1nm', | ||||
|                            'accumulative-value': round(mean(self.computed_path[-1].snr+lin2db(self.path_request.baud_rate/12.5e9)),2) | ||||
|                            }, | ||||
|                            { | ||||
|                            'metric-type': 'OSNR@bandwidth', | ||||
|                            'accumulative-value': round(mean(self.computed_path[-1].osnr_ase),2) | ||||
|                            }, | ||||
|                            { | ||||
|                            'metric-type': 'OSNR@0.1nm', | ||||
|                            'accumulative-value': round(mean(self.computed_path[-1].osnr_ase_01nm),2) | ||||
|                            }, | ||||
|                            { | ||||
|                            'metric-type': 'reference_power', | ||||
|                            'accumulative-value': self.path_request.power | ||||
|                            }, | ||||
|                            { | ||||
|                            'metric-type': 'path_bandwidth', | ||||
|                            'accumulative-value': self.path_request.path_bandwidth | ||||
|                            } | ||||
|                         ], | ||||
|                         'path-srlgs': { | ||||
|                             'usage': 'not used yet', | ||||
|                             'values': 'not used yet' | ||||
|                         } | ||||
|                     pro_list.append(temp) | ||||
|                     index += 1 | ||||
|  | ||||
|             response = { | ||||
|                 'response-id': self.path_id, | ||||
|                 'path-properties':{ | ||||
|                     'path-metric': [ | ||||
|                         { | ||||
|                             'metric-type': 'SNR-bandwidth', | ||||
|                             'accumulative-value': round(mean(self.computed_path[-1].snr), 2) | ||||
|                         }, | ||||
|                         'path-route-objects': [ | ||||
|                             { | ||||
|                             'path-route-object': { | ||||
|                                 'index': self.computed_path.index(n), | ||||
|                                 'unnumbered-hop': { | ||||
|                                     'node-id': n.uid, | ||||
|                                     'link-tp-id': n.uid, | ||||
|                                     'hop-type': self.hop_type[self.computed_path.index(n)], | ||||
|                                     'direction': 'not used' | ||||
|                                 }, | ||||
|                                 'label-hop': { | ||||
|                                     'te-label': { | ||||
|                                         'generic': 'not used yet', | ||||
|                                         'direction': 'not used yet' | ||||
|                                         } | ||||
|                                     } | ||||
|                                 } | ||||
|                             } for n in self.computed_path | ||||
|                             ] | ||||
|                         { | ||||
|                             'metric-type': 'SNR-0.1nm', | ||||
|                             'accumulative-value': round(mean(self.computed_path[-1]. snr + \ | ||||
|                                                             lin2db(self.path_request.baud_rate/12.5e9)), 2) | ||||
|                         }, | ||||
|                         { | ||||
|                             'metric-type': 'OSNR-bandwidth', | ||||
|                             'accumulative-value': round(mean(self.computed_path[-1].osnr_ase), 2) | ||||
|                         }, | ||||
|                         { | ||||
|                             'metric-type': 'OSNR-0.1nm', | ||||
|                             'accumulative-value': round(mean(self.computed_path[-1].osnr_ase_01nm), 2) | ||||
|                         }, | ||||
|                         { | ||||
|                             'metric-type': 'reference_power', | ||||
|                             'accumulative-value': self.path_request.power | ||||
|                         }, | ||||
|                         { | ||||
|                             'metric-type': 'path_bandwidth', | ||||
|                             'accumulative-value': self.path_request.path_bandwidth | ||||
|                         } | ||||
|                         ], | ||||
|                     'path-route-objects': pro_list | ||||
|                     } | ||||
|                 } | ||||
|         return response | ||||
|  | ||||
|     @property | ||||
|     def json(self): | ||||
| @@ -319,12 +247,26 @@ def compute_constrained_path(network, req): | ||||
|             candidate.sort(key=lambda x: sum(network.get_edge_data(x[i],x[i+1])['weight'] for i in range(len(x)-2))) | ||||
|             total_path = candidate[0] | ||||
|         else: | ||||
|             if req.loose_list[req.nodes_list.index(n)] == 'loose': | ||||
|                 print(f'\x1b[1;33;40m'+f'Request {req.request_id} could not find a path crossing {nodes_list} in network topology'+ '\x1b[0m') | ||||
|             # TODO: better account for individual loose and strict node | ||||
|             # to ease: suppose that one strict makes the whole liste strict (except for the | ||||
|             # last node which is the transceiver) | ||||
|             # if all nodes i n node_list are LOOSE constraint, skip the constraints and find | ||||
|             # a path w/o constraints, else there is no possible path | ||||
|             if nodes_list[:-len("STRICT")]: | ||||
|                 print(f'\x1b[1;33;40m'+f'Request {req.request_id} could not find a path crossing ' +\ | ||||
|                       f'{[el.uid for el in nodes_list[:-len("STRICT")]]} in network topology'+ '\x1b[0m') | ||||
|             else: | ||||
|                 print(f'\x1b[1;33;40m'+f'User include_node constraints could not be applied ' +\ | ||||
|                       f'(invalid names specified)'+ '\x1b[0m') | ||||
|             if 'STRICT' not in req.loose_list[:-len('STRICT')]: | ||||
|                 msg = f'\x1b[1;33;40m'+f'Request {req.request_id} could not find a path with user_' +\ | ||||
|                       f'include node constraints' + '\x1b[0m' | ||||
|                 logger.info(msg) | ||||
|                 print(f'constraint ignored') | ||||
|                 total_path = dijkstra_path(network, source, destination, weight = 'weight') | ||||
|             else: | ||||
|                 msg = f'\x1b[1;33;40m'+f'Request {req.request_id} could not find a path crossing {nodes_list}.\nNo path computed'+ '\x1b[0m' | ||||
|                 msg = f'\x1b[1;33;40m'+f'Request {req.request_id} could not find a path with user ' +\ | ||||
|                       f'include node constraints.\nNo path computed'+ '\x1b[0m' | ||||
|                 logger.critical(msg) | ||||
|                 print(msg) | ||||
|                 total_path = [] | ||||
| @@ -468,65 +410,91 @@ def jsontocsv(json_data,equipment,fileout): | ||||
|     # and write results in an CSV file | ||||
|  | ||||
|     mywriter = writer(fileout) | ||||
|     mywriter.writerow(('path-id','source','destination','path_bandwidth','Pass?',\ | ||||
|     mywriter.writerow(('response-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)',\ | ||||
|         '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']: | ||||
|         path_id     = p['path-id'] | ||||
|         source      = p['path-properties']['path-route-objects'][0]\ | ||||
|         ['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']  | ||||
|                  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(' - ') | ||||
|     for pth_el in json_data['response']: | ||||
|         path_id = pth_el['response-id'] | ||||
|         try: | ||||
|              if pth_el['no-path'] : | ||||
|                 source = '' | ||||
|                 destination = '' | ||||
|                 tsp = '' | ||||
|                 mode = '' | ||||
|                 isok = False | ||||
|                 nb_tsp = 0 | ||||
|                 pthbdbw = '' | ||||
|                 rosnr = '' | ||||
|                 rsnr = '' | ||||
|                 rsnrb = '' | ||||
|                 br = '' | ||||
|                 pw = '' | ||||
|                 total_cost = '' | ||||
|                 pth = '' | ||||
|         except KeyError: | ||||
|  | ||||
|             source = pth_el['path-properties']['path-route-objects'][0]\ | ||||
|             ['path-route-object']['num-unnum-hop']['node-id'] | ||||
|             destination = pth_el['path-properties']['path-route-objects'][-2]\ | ||||
|             ['path-route-object']['num-unnum-hop']['node-id'] | ||||
|             # selects only roadm nodes | ||||
|             temp = [] | ||||
|             for e in pth_el['path-properties']['path-route-objects']: | ||||
|                 try : | ||||
|                     temp.append(e['path-route-object']['num-unnum-hop']['node-id']) | ||||
|                 except KeyError: | ||||
|                     pass | ||||
|             pth = ' | '.join(temp) | ||||
|  | ||||
|             temp_tsp = pth_el['path-properties']['path-route-objects'][1]\ | ||||
|             ['path-route-object']['transponder'] | ||||
|             tsp = temp_tsp['transponder-type'] | ||||
|             mode = temp_tsp['transponder-mode'] | ||||
|  | ||||
|             # find the min  acceptable OSNR, baud rate from the eqpt library based on tsp (tupe) and mode (format) | ||||
|             # 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) | ||||
|             # else: | ||||
|             #     [minosnr, baud_rate, bit_rate] = ['','','',''] | ||||
|             output_snr = next(e['accumulative-value']  | ||||
|                 for e in pth_el['path-properties']['path-metric'] if e['metric-type'] == 'SNR-0.1nm') | ||||
|             output_snrbandwidth = next(e['accumulative-value'] | ||||
|                 for e in pth_el['path-properties']['path-metric'] if e['metric-type'] == 'SNR-bandwidth') | ||||
|             output_osnr = next(e['accumulative-value'] | ||||
|                 for e in pth_el['path-properties']['path-metric'] if e['metric-type'] == 'OSNR-0.1nm') | ||||
|             output_osnrbandwidth = next(e['accumulative-value'] | ||||
|                 for e in pth_el['path-properties']['path-metric'] if e['metric-type'] == 'OSNR-bandwidth') | ||||
|             power = next(e['accumulative-value'] | ||||
|                 for e in pth_el['path-properties']['path-metric'] if e['metric-type'] == 'reference_power') | ||||
|             path_bandwidth = next(e['accumulative-value'] | ||||
|                 for e in pth_el['path-properties']['path-metric'] if e['metric-type'] == 'path_bandwidth') | ||||
|             if isinstance(output_snr, str): | ||||
|                 isok = False | ||||
|                 nb_tsp = 0 | ||||
|                 pthbdbw = round(path_bandwidth*1e-9,2) | ||||
|                 rosnr = '' | ||||
|                 rsnr = '' | ||||
|                 rsnrb = '' | ||||
|                 br = '' | ||||
|                 pw = '' | ||||
|                 total_cost = '' | ||||
|             else: | ||||
|                 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 | ||||
|  | ||||
|         # find the min  acceptable OSNR, baud rate from the eqpt library based on tsp (tupe) and mode (format) | ||||
|         # 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) | ||||
|         # 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') | ||||
|         output_osnr = next(e['accumulative-value'] | ||||
|             for e in p['path-properties']['path-metric'] if e['metric-type'] == 'OSNR@0.1nm') | ||||
|         output_osnrbandwidth = next(e['accumulative-value'] | ||||
|             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 = False | ||||
|             nb_tsp = 0 | ||||
|             pthbdbw = round(path_bandwidth*1e-9,2) | ||||
|             rosnr = '' | ||||
|             rsnr = '' | ||||
|             rsnrb = '' | ||||
|             br = '' | ||||
|             pw = '' | ||||
|             total_cost = '' | ||||
|         else: | ||||
|             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, | ||||
| @@ -759,9 +727,10 @@ def compute_path_dsjctn(network, equipment, pathreqlist, disjunctions_list): | ||||
|                             testispartok = False | ||||
|                             #break | ||||
|                         else: | ||||
|                             if 'loose' in allpaths[id(p)].req.loose_list: | ||||
|                             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}') | ||||
|                                             f'{allpaths[id(p)].req.nodes_list} on request' +\ | ||||
|                                             f' {allpaths[id(p)].req.request_id}') | ||||
|                             else : | ||||
|                                 logger.info(f'removing last solution from candidate paths\n{sol}') | ||||
|                                 testispartok = False | ||||
| @@ -798,7 +767,7 @@ def compute_path_dsjctn(network, equipment, pathreqlist, disjunctions_list): | ||||
|     for req in pathreqlist : | ||||
|         req.nodes_list.append(req.destination) | ||||
|         # we assume that the destination is a strict constraint | ||||
|         req.loose_list.append('strict') | ||||
|         req.loose_list.append('STRICT') | ||||
|         if req in pathreqlist_simple: | ||||
|             path_res_list.append(compute_constrained_path(network, req)) | ||||
|         else: | ||||
| @@ -890,19 +859,19 @@ def compare_reqs(req1,req2,disjlist) : | ||||
|         req1.format     == req2.format and \ | ||||
|         req1.OSNR       == req2.OSNR and \ | ||||
|         req1.roll_off   == req2.roll_off and \ | ||||
|         same_disj : | ||||
|         same_disj: | ||||
|         return True | ||||
|     else: | ||||
|         return False | ||||
|  | ||||
| def requests_aggregation(pathreqlist,disjlist) : | ||||
| 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 :  | ||||
|         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 | ||||
| @@ -912,12 +881,12 @@ def requests_aggregation(pathreqlist,disjlist) : | ||||
|                 local_list.remove(req) | ||||
|                 # todo change also disjunction req with new demand | ||||
|  | ||||
|                 for d in disjlist : | ||||
|                     if req.request_id in d.disjunctions_req : | ||||
|                 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 : | ||||
|                 for d in disjlist: | ||||
|                     if temp_r_id in d.disjunctions_req: | ||||
|                         disjlist.remove(d) | ||||
|                 break | ||||
|     return local_list, disjlist | ||||
|   | ||||
| @@ -48,8 +48,8 @@ class Request_element(Element): | ||||
|         # excel has automatic number formatting that adds .0 on integer values | ||||
|         # the next lines recover the pure int value, assuming this .0 is unwanted | ||||
|         self.request_id = correct_xlrd_int_to_str_reading(Request.request_id) | ||||
|         self.source = Request.source | ||||
|         self.destination = Request.destination | ||||
|         self.source = f'trx {Request.source}' | ||||
|         self.destination = f'trx {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}' | ||||
| @@ -120,9 +120,9 @@ class Request_element(Element): | ||||
|  | ||||
|         # 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' | ||||
|         self.loose = 'LOOSE' | ||||
|         if Request.is_loose == 'no' : | ||||
|             self.loose = 'strict' | ||||
|             self.loose = 'STRICT' | ||||
|         self.path_bandwidth = None | ||||
|         if Request.path_bandwidth is not None: | ||||
|             self.path_bandwidth = Request.path_bandwidth * 1e9 | ||||
| @@ -132,6 +132,7 @@ class Request_element(Element): | ||||
|     uid = property(lambda self: repr(self)) | ||||
|     @property | ||||
|     def pathrequest(self): | ||||
|  | ||||
|         req_dictionnary = { | ||||
|                     'request-id':self.request_id, | ||||
|                     'source':    self.source, | ||||
| @@ -143,35 +144,28 @@ class Request_element(Element): | ||||
|                             'technology': 'flexi-grid', | ||||
|                             'trx_type'  : self.trx_type, | ||||
|                             'trx_mode'  : self.mode, | ||||
|                             'effective-freq-slot':[{'n': 'null','m': 'null'}] , | ||||
|                             'effective-freq-slot':[{'N': 'null', 'M': 'null'}], | ||||
|                             'spacing'   : self.spacing, | ||||
|                             'max-nb-of-channel'  : self.nb_channel, | ||||
|                             'output-power'       : self.power | ||||
|                             # 'path_bandwidth'       : self.path_bandwidth  | ||||
|                         } | ||||
|                     }, | ||||
|                     'optimizations': { | ||||
|                         'explicit-route-include-objects': [ | ||||
|                         { | ||||
|                             'index': self.nodes_list.index(node), | ||||
|                             'unnumbered-hop':{ | ||||
|                                 'node-id': f'{node}', | ||||
|                                 'link-tp-id': 'link-tp-id is not used', | ||||
|                                 'hop-type': f'{self.loose}', | ||||
|                                 'direction': 'direction is not used' | ||||
|                             }, | ||||
|                             'label-hop':{ | ||||
|                                 'te-label': { | ||||
|                                     'generic': 'generic is not used', | ||||
|                                     'direction': 'direction is not used' | ||||
|                                 } | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|         if self.nodes_list: | ||||
|             req_dictionnary['explicit-route-objects'] = {} | ||||
|             temp = {'route-object-include-exclude' : [ | ||||
|                         {'explicit-route-usage': 'route-include-ero', | ||||
|                         'index': self.nodes_list.index(node), | ||||
|                         'num-unnum-hop': { | ||||
|                             'node-id': f'{node}', | ||||
|                             'link-tp-id': 'link-tp-id is not used', | ||||
|                             'hop-type': f'{self.loose}', | ||||
|                             } | ||||
|                         } | ||||
|                         for node in self.nodes_list | ||||
|                     ] | ||||
|  | ||||
|                 } | ||||
|             } | ||||
|                         for node in self.nodes_list] | ||||
|                    } | ||||
|             req_dictionnary['explicit-route-objects'] = temp | ||||
|         if self.path_bandwidth is not None: | ||||
|             req_dictionnary['path-constraints']['te-bandwidth']['path_bandwidth'] = self.path_bandwidth | ||||
|              | ||||
| @@ -181,12 +175,13 @@ class Request_element(Element): | ||||
|         if self.disjoint_from : | ||||
|             return {'synchronization-id':self.request_id, | ||||
|                 'svec': { | ||||
|                     'relaxable' : 'False', | ||||
|                     'link-diverse': 'True', | ||||
|                     'node-diverse': 'True', | ||||
|                     'relaxable' : 'false', | ||||
|                     'disjointness': 'node link', | ||||
|                     'request-id-number': [self.request_id]+ [n for n in self.disjoint_from] | ||||
|                 } | ||||
|             } | ||||
|         else: | ||||
|             return None | ||||
|         # TO-DO: avoid multiple entries with same synchronisation vectors | ||||
|     @property | ||||
|     def json(self): | ||||
| @@ -201,11 +196,17 @@ def convert_service_sheet(input_filename, eqpt_filename, output_filename='', fil | ||||
|         output_filename = f'{str(input_filename)[0:len(str(input_filename))-len(str(input_filename.suffixes[0]))]}_services.json' | ||||
|     # for debug | ||||
|     # print(json_filename) | ||||
|     data = { | ||||
|         'path-request': [n.json[0] for n in req], | ||||
|         'synchronization': [n.json[1] for n in req | ||||
|         if n.json[1] is not None] | ||||
|     } | ||||
|     # if there is no sync vector , do not write any synchronization | ||||
|     synchro = [n.json[1] for n in req if n.json[1] is not None] | ||||
|     if synchro: | ||||
|         data = { | ||||
|             'path-request': [n.json[0] for n in req], | ||||
|             'synchronization': synchro | ||||
|         } | ||||
|     else: | ||||
|         data = { | ||||
|             'path-request': [n.json[0] for n in req] | ||||
|             } | ||||
|     with open(output_filename, 'w', encoding='utf-8') as f: | ||||
|             f.write(dumps(data, indent=2, ensure_ascii=False)) | ||||
|     return data | ||||
|   | ||||
| @@ -73,35 +73,19 @@ def c(): | ||||
|     return constants.c | ||||
|  | ||||
|  | ||||
| def itufs(spacing, startf=191.35, stopf=196.10): | ||||
|     """Creates an array of frequencies whose default range is | ||||
|     191.35-196.10 THz | ||||
|  | ||||
|     :param spacing: Frequency spacing in THz | ||||
|     :param starf: Start frequency in THz | ||||
|     :param stopf: Stop frequency in THz | ||||
|     :type spacing: float | ||||
|     :type startf: float | ||||
|     :type stopf: float | ||||
|     :return an array of frequnecies determined by the spacing parameter | ||||
|     :rtype: numpy.ndarray | ||||
|     """ | ||||
|     return np.arange(startf, stopf + spacing / 2, spacing) | ||||
|  | ||||
| def itufl(length, startf=191.35, stopf=196.10): | ||||
|     """Creates an array of frequencies whose default range is | ||||
|     191.35-196.10 THz | ||||
| def arrange_frequencies(length, start, stop): | ||||
|     """Create an array of frequencies | ||||
|  | ||||
|     :param length: number of elements | ||||
|     :param starf: Start frequency in THz | ||||
|     :param stopf: Stop frequency in THz | ||||
|     :param star: Start frequency in THz | ||||
|     :param stop: Stop frequency in THz | ||||
|     :type length: integer | ||||
|     :type startf: float | ||||
|     :type stopf: float | ||||
|     :return an array of frequnecies determined by the spacing parameter | ||||
|     :type start: float | ||||
|     :type stop: float | ||||
|     :return an array of frequencies determined by the spacing parameter | ||||
|     :rtype: numpy.ndarray | ||||
|     """ | ||||
|     return np.linspace(startf, stopf, length) | ||||
|     return np.linspace(start, stop, length) | ||||
|  | ||||
| def h(): | ||||
|     """ | ||||
|   | ||||
| @@ -1,39 +1,63 @@ | ||||
| { | ||||
|   "paths": [ | ||||
|   "response": [ | ||||
|     { | ||||
|       "path": { | ||||
|         "path-id": null, | ||||
|         "path-properties": { | ||||
|           "path-metric": [ | ||||
|             { | ||||
|               "metric-type": null, | ||||
|               "accumulative-value": null | ||||
|             } | ||||
|           ], | ||||
|           "path-srlgs": { | ||||
|             "usage": "not used yet", | ||||
|             "values": ["not used yet"] | ||||
|       "response-id": null, | ||||
|       "path-properties": { | ||||
|         "path-metric": [ | ||||
|           { | ||||
|             "metric-type": "SNR@bandwidth", | ||||
|             "accumulative-value": null | ||||
|           }, | ||||
|           "path-route-objects": [ | ||||
|             { | ||||
|               "path-route-object": { | ||||
|                 "index": null, | ||||
|                 "unnumbered-hop": { | ||||
|                   "node-id": null, | ||||
|                   "link-tp-id": null, | ||||
|                   "hop-type": null, | ||||
|                   "direction": "not used" | ||||
|                 }, | ||||
|                 "label-hop": { | ||||
|                   "te-label": { | ||||
|                     "generic": "not used yet", | ||||
|                     "direction": "not used yet" | ||||
|                   } | ||||
|                 } | ||||
|           { | ||||
|             "metric-type": "SNR@0.1nm", | ||||
|             "accumulative-value": null | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "OSNR@bandwidth", | ||||
|             "accumulative-value": null | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "OSNR@0.1nm", | ||||
|             "accumulative-value": null | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "reference_power", | ||||
|             "accumulative-value": null | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "path_bandwidth", | ||||
|             "accumulative-value": null | ||||
|           } | ||||
|         ], | ||||
|         "path-route-objects": [ | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 0, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": null, | ||||
|                 "link-tp-id": null | ||||
|               } | ||||
|             } | ||||
|           ] | ||||
|         } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 1, | ||||
|               "transponder": { | ||||
|                 "transponder-type": null, | ||||
|                 "transponder-mode": null | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 2, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": null, | ||||
|                 "link-tp-id": null | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         ] | ||||
|       } | ||||
|     } | ||||
|   ] | ||||
|   | ||||
| @@ -2,6 +2,7 @@ alabaster>=0.7.12,<1 | ||||
| matplotlib>=3.1.0,<4 | ||||
| networkx>=2.3,<3 | ||||
| numpy>=1.16.1,<2 | ||||
| pandas==0.24.2 | ||||
| Pygments>=2.4.2,<3 | ||||
| pytest>=4.0.0,<5 | ||||
| scipy>=1.3.0,<2 | ||||
|   | ||||
| @@ -6,6 +6,44 @@ | ||||
|       "destination": null, | ||||
|       "src-tp-id": null, | ||||
|       "dst-tp-id": null, | ||||
|       "explicit-route-objects": { | ||||
|         "route-object-include-exclude": [ | ||||
|           { | ||||
|             "explicit-route-usage": null, | ||||
|             "index": null, | ||||
|             "num-unnum-hop": { | ||||
|               "node-id": null, | ||||
|               "link-tp-id": null, | ||||
|               "hop-type": null | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "explicit-route-usage": null, | ||||
|             "index": null, | ||||
|             "label-hop": { | ||||
|               "N": null, | ||||
|               "M": null | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "explicit-route-usage": null, | ||||
|             "index": null, | ||||
|             "transponder": { | ||||
|               "transponder-type": null, | ||||
|               "transponder-mode": null | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "explicit-route-usage": null, | ||||
|             "index": null, | ||||
|             "regenerator": { | ||||
|               "regenerator-id": null, | ||||
|               "transponder-type": null, | ||||
|               "transponder-mode": null | ||||
|             } | ||||
|           } | ||||
|         ] | ||||
|       },       | ||||
|       "path-constraints": { | ||||
|         "te-bandwidth": { | ||||
|           "technology": "flexi-grid", | ||||
| @@ -22,27 +60,6 @@ | ||||
|           "output-power": null, | ||||
|           "path_bandwidth": null | ||||
|           } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": { | ||||
|           "route-object-include-object": [ | ||||
|           { | ||||
|             "index": null, | ||||
|             "unnumbered-hop": { | ||||
|               "node-id": null, | ||||
|               "link-tp-id": "link-tp-id is not used", | ||||
|               "hop-type": null, | ||||
|               "direction": "direction is not used" | ||||
|             }, | ||||
|             "label-hop": { | ||||
|               "te-label": { | ||||
|                 "generic": "generic is not used", | ||||
|                 "direction": "direction is not used" | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|           ] | ||||
|         } | ||||
|       } | ||||
|     }], | ||||
|   "synchronization": [ | ||||
| @@ -50,10 +67,9 @@ | ||||
|       "synchronization-id": null, | ||||
|       "svec": { | ||||
|         "relaxable": "True", | ||||
|         "link-diverse": "False", | ||||
|         "node-diverse": "False", | ||||
|         "disjointness": "node link", | ||||
|         "request-id-number": [ | ||||
|          null ] | ||||
|          null, null ] | ||||
|         }, | ||||
|     } | ||||
|     ] | ||||
|   | ||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										866
									
								
								tests/data/testTopology_response.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										866
									
								
								tests/data/testTopology_response.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,866 @@ | ||||
| { | ||||
|   "response": [ | ||||
|     { | ||||
|       "response-id": "0", | ||||
|       "path-properties": { | ||||
|         "path-metric": [ | ||||
|           { | ||||
|             "metric-type": "SNR-bandwidth", | ||||
|             "accumulative-value": 26.75 | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "SNR-0.1nm", | ||||
|             "accumulative-value": 30.84 | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "OSNR-bandwidth", | ||||
|             "accumulative-value": 26.76 | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "OSNR-0.1nm", | ||||
|             "accumulative-value": 30.84 | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "reference_power", | ||||
|             "accumulative-value": 0.001 | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "path_bandwidth", | ||||
|             "accumulative-value": 100000000000.0 | ||||
|           } | ||||
|         ], | ||||
|         "path-route-objects": [ | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 0, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "trx Lorient_KMA", | ||||
|                 "link-tp-id": "trx Lorient_KMA" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 1, | ||||
|               "transponder": { | ||||
|                 "transponder-type": "Voyager", | ||||
|                 "transponder-mode": "mode 1" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 2, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "roadm Lorient_KMA", | ||||
|                 "link-tp-id": "roadm Lorient_KMA" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 3, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "Edfa1_roadm Lorient_KMA", | ||||
|                 "link-tp-id": "Edfa1_roadm Lorient_KMA" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 4, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "fiber (Lorient_KMA → Vannes_KBE)-F055", | ||||
|                 "link-tp-id": "fiber (Lorient_KMA → Vannes_KBE)-F055" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 5, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "Edfa0_fiber (Lorient_KMA → Vannes_KBE)-F055", | ||||
|                 "link-tp-id": "Edfa0_fiber (Lorient_KMA → Vannes_KBE)-F055" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 6, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "roadm Vannes_KBE", | ||||
|                 "link-tp-id": "roadm Vannes_KBE" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 7, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "trx Vannes_KBE", | ||||
|                 "link-tp-id": "trx Vannes_KBE" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 8, | ||||
|               "transponder": { | ||||
|                 "transponder-type": "Voyager", | ||||
|                 "transponder-mode": "mode 1" | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         ] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "response-id": "1", | ||||
|       "path-properties": { | ||||
|         "path-metric": [ | ||||
|           { | ||||
|             "metric-type": "SNR-bandwidth", | ||||
|             "accumulative-value": 18.03 | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "SNR-0.1nm", | ||||
|             "accumulative-value": 22.11 | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "OSNR-bandwidth", | ||||
|             "accumulative-value": 18.57 | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "OSNR-0.1nm", | ||||
|             "accumulative-value": 22.65 | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "reference_power", | ||||
|             "accumulative-value": 0.0012589254117941673 | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "path_bandwidth", | ||||
|             "accumulative-value": 0 | ||||
|           } | ||||
|         ], | ||||
|         "path-route-objects": [ | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 0, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "trx Brest_KLA", | ||||
|                 "link-tp-id": "trx Brest_KLA" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 1, | ||||
|               "transponder": { | ||||
|                 "transponder-type": "Voyager", | ||||
|                 "transponder-mode": "mode 1" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 2, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "roadm Brest_KLA", | ||||
|                 "link-tp-id": "roadm Brest_KLA" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 3, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "Edfa0_roadm Brest_KLA", | ||||
|                 "link-tp-id": "Edfa0_roadm Brest_KLA" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 4, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "fiber (Brest_KLA → Morlaix)-F060", | ||||
|                 "link-tp-id": "fiber (Brest_KLA → Morlaix)-F060" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 5, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "east fused spans in Morlaix", | ||||
|                 "link-tp-id": "east fused spans in Morlaix" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 6, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "fiber (Morlaix → Lannion_CAS)-F059", | ||||
|                 "link-tp-id": "fiber (Morlaix → Lannion_CAS)-F059" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 7, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "west edfa in Lannion_CAS to Morlaix", | ||||
|                 "link-tp-id": "west edfa in Lannion_CAS to Morlaix" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 8, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "roadm Lannion_CAS", | ||||
|                 "link-tp-id": "roadm Lannion_CAS" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 9, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "east edfa in Lannion_CAS to Corlay", | ||||
|                 "link-tp-id": "east edfa in Lannion_CAS to Corlay" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 10, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "fiber (Lannion_CAS → Corlay)-F061", | ||||
|                 "link-tp-id": "fiber (Lannion_CAS → Corlay)-F061" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 11, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "west fused spans in Corlay", | ||||
|                 "link-tp-id": "west fused spans in Corlay" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 12, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "fiber (Corlay → Loudeac)-F010", | ||||
|                 "link-tp-id": "fiber (Corlay → Loudeac)-F010" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 13, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "west fused spans in Loudeac", | ||||
|                 "link-tp-id": "west fused spans in Loudeac" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 14, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "fiber (Loudeac → Lorient_KMA)-F054", | ||||
|                 "link-tp-id": "fiber (Loudeac → Lorient_KMA)-F054" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 15, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "Edfa0_fiber (Loudeac → Lorient_KMA)-F054", | ||||
|                 "link-tp-id": "Edfa0_fiber (Loudeac → Lorient_KMA)-F054" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 16, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "roadm Lorient_KMA", | ||||
|                 "link-tp-id": "roadm Lorient_KMA" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 17, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "Edfa1_roadm Lorient_KMA", | ||||
|                 "link-tp-id": "Edfa1_roadm Lorient_KMA" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 18, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "fiber (Lorient_KMA → Vannes_KBE)-F055", | ||||
|                 "link-tp-id": "fiber (Lorient_KMA → Vannes_KBE)-F055" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 19, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "Edfa0_fiber (Lorient_KMA → Vannes_KBE)-F055", | ||||
|                 "link-tp-id": "Edfa0_fiber (Lorient_KMA → Vannes_KBE)-F055" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 20, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "roadm Vannes_KBE", | ||||
|                 "link-tp-id": "roadm Vannes_KBE" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 21, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "trx Vannes_KBE", | ||||
|                 "link-tp-id": "trx Vannes_KBE" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 22, | ||||
|               "transponder": { | ||||
|                 "transponder-type": "Voyager", | ||||
|                 "transponder-mode": "mode 1" | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         ] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "response-id": "3", | ||||
|       "path-properties": { | ||||
|         "path-metric": [ | ||||
|           { | ||||
|             "metric-type": "SNR-bandwidth", | ||||
|             "accumulative-value": 21.77 | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "SNR-0.1nm", | ||||
|             "accumulative-value": 25.85 | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "OSNR-bandwidth", | ||||
|             "accumulative-value": 24.2 | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "OSNR-0.1nm", | ||||
|             "accumulative-value": 28.29 | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "reference_power", | ||||
|             "accumulative-value": 0.0012589254117941673 | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "path_bandwidth", | ||||
|             "accumulative-value": 60000000000.0 | ||||
|           } | ||||
|         ], | ||||
|         "path-route-objects": [ | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 0, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "trx Lannion_CAS", | ||||
|                 "link-tp-id": "trx Lannion_CAS" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 1, | ||||
|               "transponder": { | ||||
|                 "transponder-type": "vendorA_trx-type1", | ||||
|                 "transponder-mode": "mode 1" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 2, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "roadm Lannion_CAS", | ||||
|                 "link-tp-id": "roadm Lannion_CAS" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 3, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "east edfa in Lannion_CAS to Stbrieuc", | ||||
|                 "link-tp-id": "east edfa in Lannion_CAS to Stbrieuc" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 4, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "fiber (Lannion_CAS → Stbrieuc)-F056", | ||||
|                 "link-tp-id": "fiber (Lannion_CAS → Stbrieuc)-F056" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 5, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "east edfa in Stbrieuc to Rennes_STA", | ||||
|                 "link-tp-id": "east edfa in Stbrieuc to Rennes_STA" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 6, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "fiber (Stbrieuc → Rennes_STA)-F057", | ||||
|                 "link-tp-id": "fiber (Stbrieuc → Rennes_STA)-F057" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 7, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "Edfa0_fiber (Stbrieuc → Rennes_STA)-F057", | ||||
|                 "link-tp-id": "Edfa0_fiber (Stbrieuc → Rennes_STA)-F057" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 8, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "roadm Rennes_STA", | ||||
|                 "link-tp-id": "roadm Rennes_STA" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 9, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "trx Rennes_STA", | ||||
|                 "link-tp-id": "trx Rennes_STA" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 10, | ||||
|               "transponder": { | ||||
|                 "transponder-type": "vendorA_trx-type1", | ||||
|                 "transponder-mode": "mode 1" | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         ] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "response-id": "4", | ||||
|       "path-properties": { | ||||
|         "path-metric": [ | ||||
|           { | ||||
|             "metric-type": "SNR-bandwidth", | ||||
|             "accumulative-value": 15.05 | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "SNR-0.1nm", | ||||
|             "accumulative-value": 22.15 | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "OSNR-bandwidth", | ||||
|             "accumulative-value": 15.18 | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "OSNR-0.1nm", | ||||
|             "accumulative-value": 22.27 | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "reference_power", | ||||
|             "accumulative-value": 0.001 | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "path_bandwidth", | ||||
|             "accumulative-value": 150000000000.0 | ||||
|           } | ||||
|         ], | ||||
|         "path-route-objects": [ | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 0, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "trx Rennes_STA", | ||||
|                 "link-tp-id": "trx Rennes_STA" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 1, | ||||
|               "transponder": { | ||||
|                 "transponder-type": "vendorA_trx-type1", | ||||
|                 "transponder-mode": "mode 2" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 2, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "roadm Rennes_STA", | ||||
|                 "link-tp-id": "roadm Rennes_STA" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 3, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "Edfa1_roadm Rennes_STA", | ||||
|                 "link-tp-id": "Edfa1_roadm Rennes_STA" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 4, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "fiber (Rennes_STA → Ploermel)-", | ||||
|                 "link-tp-id": "fiber (Rennes_STA → Ploermel)-" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 5, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "east edfa in Ploermel to Vannes_KBE", | ||||
|                 "link-tp-id": "east edfa in Ploermel to Vannes_KBE" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 6, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "fiber (Ploermel → Vannes_KBE)-", | ||||
|                 "link-tp-id": "fiber (Ploermel → Vannes_KBE)-" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 7, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "Edfa0_fiber (Ploermel → Vannes_KBE)-", | ||||
|                 "link-tp-id": "Edfa0_fiber (Ploermel → Vannes_KBE)-" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 8, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "roadm Vannes_KBE", | ||||
|                 "link-tp-id": "roadm Vannes_KBE" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 9, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "Edfa0_roadm Vannes_KBE", | ||||
|                 "link-tp-id": "Edfa0_roadm Vannes_KBE" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 10, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "fiber (Vannes_KBE → Lorient_KMA)-F055", | ||||
|                 "link-tp-id": "fiber (Vannes_KBE → Lorient_KMA)-F055" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 11, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "Edfa0_fiber (Vannes_KBE → Lorient_KMA)-F055", | ||||
|                 "link-tp-id": "Edfa0_fiber (Vannes_KBE → Lorient_KMA)-F055" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 12, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "roadm Lorient_KMA", | ||||
|                 "link-tp-id": "roadm Lorient_KMA" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 13, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "Edfa0_roadm Lorient_KMA", | ||||
|                 "link-tp-id": "Edfa0_roadm Lorient_KMA" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 14, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "fiber (Lorient_KMA → Loudeac)-F054", | ||||
|                 "link-tp-id": "fiber (Lorient_KMA → Loudeac)-F054" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 15, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "east fused spans in Loudeac", | ||||
|                 "link-tp-id": "east fused spans in Loudeac" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 16, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "fiber (Loudeac → Corlay)-F010", | ||||
|                 "link-tp-id": "fiber (Loudeac → Corlay)-F010" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 17, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "east fused spans in Corlay", | ||||
|                 "link-tp-id": "east fused spans in Corlay" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 18, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "fiber (Corlay → Lannion_CAS)-F061", | ||||
|                 "link-tp-id": "fiber (Corlay → Lannion_CAS)-F061" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 19, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "west edfa in Lannion_CAS to Corlay", | ||||
|                 "link-tp-id": "west edfa in Lannion_CAS to Corlay" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 20, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "roadm Lannion_CAS", | ||||
|                 "link-tp-id": "roadm Lannion_CAS" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 21, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "trx Lannion_CAS", | ||||
|                 "link-tp-id": "trx Lannion_CAS" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 22, | ||||
|               "transponder": { | ||||
|                 "transponder-type": "vendorA_trx-type1", | ||||
|                 "transponder-mode": "mode 2" | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         ] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "response-id": "5", | ||||
|       "path-properties": { | ||||
|         "path-metric": [ | ||||
|           { | ||||
|             "metric-type": "SNR-bandwidth", | ||||
|             "accumulative-value": 21.68 | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "SNR-0.1nm", | ||||
|             "accumulative-value": 28.77 | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "OSNR-bandwidth", | ||||
|             "accumulative-value": 23.7 | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "OSNR-0.1nm", | ||||
|             "accumulative-value": 30.79 | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "reference_power", | ||||
|             "accumulative-value": 0.0019952623149688794 | ||||
|           }, | ||||
|           { | ||||
|             "metric-type": "path_bandwidth", | ||||
|             "accumulative-value": 20000000000.0 | ||||
|           } | ||||
|         ], | ||||
|         "path-route-objects": [ | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 0, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "trx Rennes_STA", | ||||
|                 "link-tp-id": "trx Rennes_STA" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 1, | ||||
|               "transponder": { | ||||
|                 "transponder-type": "vendorA_trx-type1", | ||||
|                 "transponder-mode": "mode 2" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 2, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "roadm Rennes_STA", | ||||
|                 "link-tp-id": "roadm Rennes_STA" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 3, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "Edfa0_roadm Rennes_STA", | ||||
|                 "link-tp-id": "Edfa0_roadm Rennes_STA" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 4, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "fiber (Rennes_STA → Stbrieuc)-F057", | ||||
|                 "link-tp-id": "fiber (Rennes_STA → Stbrieuc)-F057" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 5, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "Edfa0_fiber (Rennes_STA → Stbrieuc)-F057", | ||||
|                 "link-tp-id": "Edfa0_fiber (Rennes_STA → Stbrieuc)-F057" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 6, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "fiber (Stbrieuc → Lannion_CAS)-F056", | ||||
|                 "link-tp-id": "fiber (Stbrieuc → Lannion_CAS)-F056" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 7, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "Edfa0_fiber (Stbrieuc → Lannion_CAS)-F056", | ||||
|                 "link-tp-id": "Edfa0_fiber (Stbrieuc → Lannion_CAS)-F056" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 8, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "roadm Lannion_CAS", | ||||
|                 "link-tp-id": "roadm Lannion_CAS" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 9, | ||||
|               "num-unnum-hop": { | ||||
|                 "node-id": "trx Lannion_CAS", | ||||
|                 "link-tp-id": "trx Lannion_CAS" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "path-route-object": { | ||||
|               "index": 10, | ||||
|               "transponder": { | ||||
|                 "transponder-type": "vendorA_trx-type1", | ||||
|                 "transponder-mode": "mode 2" | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         ] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "response-id": "6", | ||||
|       "no-path": "Response without path information, due to failure performing the path computation" | ||||
|     } | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										7
									
								
								tests/data/testTopology_response_expected.csv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								tests/data/testTopology_response_expected.csv
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| response-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 | ||||
| 0,trx Lorient_KMA,trx Vannes_KBE,100.0,True,1,1,Voyager,mode 1,30.84,30.84,26.75,32.0,0.0,trx Lorient_KMA | roadm Lorient_KMA | Edfa1_roadm Lorient_KMA | fiber (Lorient_KMA → Vannes_KBE)-F055 | Edfa0_fiber (Lorient_KMA → Vannes_KBE)-F055 | roadm Vannes_KBE | trx Vannes_KBE | ||||
| 1,trx Brest_KLA,trx Vannes_KBE,0.0,True,0,0,Voyager,mode 1,22.65,22.11,18.03,32.0,1.0,trx Brest_KLA | roadm Brest_KLA | Edfa0_roadm Brest_KLA | fiber (Brest_KLA → Morlaix)-F060 | east fused spans in Morlaix | fiber (Morlaix → Lannion_CAS)-F059 | west edfa in Lannion_CAS to Morlaix | roadm Lannion_CAS | east edfa in Lannion_CAS to Corlay | fiber (Lannion_CAS → Corlay)-F061 | west fused spans in Corlay | fiber (Corlay → Loudeac)-F010 | west fused spans in Loudeac | fiber (Loudeac → Lorient_KMA)-F054 | Edfa0_fiber (Loudeac → Lorient_KMA)-F054 | roadm Lorient_KMA | Edfa1_roadm Lorient_KMA | fiber (Lorient_KMA → Vannes_KBE)-F055 | Edfa0_fiber (Lorient_KMA → Vannes_KBE)-F055 | roadm Vannes_KBE | trx Vannes_KBE | ||||
| 3,trx Lannion_CAS,trx Rennes_STA,60.0,True,1,1,vendorA_trx-type1,mode 1,28.29,25.85,21.77,32.0,1.0,trx Lannion_CAS | roadm Lannion_CAS | east edfa in Lannion_CAS to Stbrieuc | fiber (Lannion_CAS → Stbrieuc)-F056 | east edfa in Stbrieuc to Rennes_STA | fiber (Stbrieuc → Rennes_STA)-F057 | Edfa0_fiber (Stbrieuc → Rennes_STA)-F057 | roadm Rennes_STA | trx Rennes_STA | ||||
| 4,trx Rennes_STA,trx Lannion_CAS,150.0,True,1,1,vendorA_trx-type1,mode 2,22.27,22.15,15.05,64.0,0.0,trx Rennes_STA | roadm Rennes_STA | Edfa1_roadm Rennes_STA | fiber (Rennes_STA → Ploermel)- | east edfa in Ploermel to Vannes_KBE | fiber (Ploermel → Vannes_KBE)- | Edfa0_fiber (Ploermel → Vannes_KBE)- | roadm Vannes_KBE | Edfa0_roadm Vannes_KBE | fiber (Vannes_KBE → Lorient_KMA)-F055 | Edfa0_fiber (Vannes_KBE → Lorient_KMA)-F055 | roadm Lorient_KMA | Edfa0_roadm Lorient_KMA | fiber (Lorient_KMA → Loudeac)-F054 | east fused spans in Loudeac | fiber (Loudeac → Corlay)-F010 | east fused spans in Corlay | fiber (Corlay → Lannion_CAS)-F061 | west edfa in Lannion_CAS to Corlay | roadm Lannion_CAS | trx Lannion_CAS | ||||
| 5,trx Rennes_STA,trx Lannion_CAS,20.0,True,1,1,vendorA_trx-type1,mode 2,30.79,28.77,21.68,64.0,3.0,trx Rennes_STA | roadm Rennes_STA | Edfa0_roadm Rennes_STA | fiber (Rennes_STA → Stbrieuc)-F057 | Edfa0_fiber (Rennes_STA → Stbrieuc)-F057 | fiber (Stbrieuc → Lannion_CAS)-F056 | Edfa0_fiber (Stbrieuc → Lannion_CAS)-F056 | roadm Lannion_CAS | trx Lannion_CAS | ||||
| 6,,,,False,0,,,,,,,,, | ||||
| 
 | 
| @@ -2,8 +2,8 @@ | ||||
|   "path-request": [ | ||||
|     { | ||||
|       "request-id": "0", | ||||
|       "source": "Lorient_KMA", | ||||
|       "destination": "Vannes_KBE", | ||||
|       "source": "trx Lorient_KMA", | ||||
|       "destination": "trx Vannes_KBE", | ||||
|       "src-tp-id": "trx Lorient_KMA", | ||||
|       "dst-tp-id": "trx Vannes_KBE", | ||||
|       "path-constraints": { | ||||
| @@ -13,8 +13,8 @@ | ||||
|           "trx_mode": "mode 1", | ||||
|           "effective-freq-slot": [ | ||||
|             { | ||||
|               "n": "null", | ||||
|               "m": "null" | ||||
|               "N": "null", | ||||
|               "M": "null" | ||||
|             } | ||||
|           ], | ||||
|           "spacing": 50000000000.0, | ||||
| @@ -22,15 +22,12 @@ | ||||
|           "output-power": null, | ||||
|           "path_bandwidth": 100000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "1", | ||||
|       "source": "Brest_KLA", | ||||
|       "destination": "Vannes_KBE", | ||||
|       "source": "trx Brest_KLA", | ||||
|       "destination": "trx Vannes_KBE", | ||||
|       "src-tp-id": "trx Brest_KLA", | ||||
|       "dst-tp-id": "trx Vannes_KBE", | ||||
|       "path-constraints": { | ||||
| @@ -40,8 +37,8 @@ | ||||
|           "trx_mode": "mode 1", | ||||
|           "effective-freq-slot": [ | ||||
|             { | ||||
|               "n": "null", | ||||
|               "m": "null" | ||||
|               "N": "null", | ||||
|               "M": "null" | ||||
|             } | ||||
|           ], | ||||
|           "spacing": 50000000000.0, | ||||
| @@ -50,66 +47,42 @@ | ||||
|           "path_bandwidth": 0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [ | ||||
|       "explicit-route-objects": { | ||||
|         "route-object-include-exclude": [ | ||||
|           { | ||||
|             "explicit-route-usage": "route-include-ero", | ||||
|             "index": 0, | ||||
|             "unnumbered-hop": { | ||||
|             "num-unnum-hop": { | ||||
|               "node-id": "roadm Brest_KLA", | ||||
|               "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" | ||||
|               } | ||||
|               "hop-type": "LOOSE" | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "explicit-route-usage": "route-include-ero", | ||||
|             "index": 1, | ||||
|             "unnumbered-hop": { | ||||
|             "num-unnum-hop": { | ||||
|               "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" | ||||
|               } | ||||
|               "hop-type": "LOOSE" | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "explicit-route-usage": "route-include-ero", | ||||
|             "index": 2, | ||||
|             "unnumbered-hop": { | ||||
|             "num-unnum-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" | ||||
|               } | ||||
|               "hop-type": "LOOSE" | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "explicit-route-usage": "route-include-ero", | ||||
|             "index": 3, | ||||
|             "unnumbered-hop": { | ||||
|             "num-unnum-hop": { | ||||
|               "node-id": "roadm Vannes_KBE", | ||||
|               "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" | ||||
|               } | ||||
|               "hop-type": "LOOSE" | ||||
|             } | ||||
|           } | ||||
|         ] | ||||
| @@ -117,8 +90,8 @@ | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "3", | ||||
|       "source": "Lannion_CAS", | ||||
|       "destination": "Rennes_STA", | ||||
|       "source": "trx Lannion_CAS", | ||||
|       "destination": "trx Rennes_STA", | ||||
|       "src-tp-id": "trx Lannion_CAS", | ||||
|       "dst-tp-id": "trx Rennes_STA", | ||||
|       "path-constraints": { | ||||
| @@ -128,8 +101,8 @@ | ||||
|           "trx_mode": "mode 1", | ||||
|           "effective-freq-slot": [ | ||||
|             { | ||||
|               "n": "null", | ||||
|               "m": "null" | ||||
|               "N": "null", | ||||
|               "M": "null" | ||||
|             } | ||||
|           ], | ||||
|           "spacing": 50000000000.0, | ||||
| @@ -137,15 +110,12 @@ | ||||
|           "output-power": 0.0012589254117941673, | ||||
|           "path_bandwidth": 60000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "4", | ||||
|       "source": "Rennes_STA", | ||||
|       "destination": "Lannion_CAS", | ||||
|       "source": "trx Rennes_STA", | ||||
|       "destination": "trx Lannion_CAS", | ||||
|       "src-tp-id": "trx Rennes_STA", | ||||
|       "dst-tp-id": "trx Lannion_CAS", | ||||
|       "path-constraints": { | ||||
| @@ -155,8 +125,8 @@ | ||||
|           "trx_mode": "mode 2", | ||||
|           "effective-freq-slot": [ | ||||
|             { | ||||
|               "n": "null", | ||||
|               "m": "null" | ||||
|               "N": "null", | ||||
|               "M": "null" | ||||
|             } | ||||
|           ], | ||||
|           "spacing": 75000000000.0, | ||||
| @@ -164,15 +134,12 @@ | ||||
|           "output-power": null, | ||||
|           "path_bandwidth": 150000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "5", | ||||
|       "source": "Rennes_STA", | ||||
|       "destination": "Lannion_CAS", | ||||
|       "source": "trx Rennes_STA", | ||||
|       "destination": "trx Lannion_CAS", | ||||
|       "src-tp-id": "trx Rennes_STA", | ||||
|       "dst-tp-id": "trx Lannion_CAS", | ||||
|       "path-constraints": { | ||||
| @@ -182,8 +149,8 @@ | ||||
|           "trx_mode": "mode 2", | ||||
|           "effective-freq-slot": [ | ||||
|             { | ||||
|               "n": "null", | ||||
|               "m": "null" | ||||
|               "N": "null", | ||||
|               "M": "null" | ||||
|             } | ||||
|           ], | ||||
|           "spacing": 75000000000.0, | ||||
| @@ -191,9 +158,30 @@ | ||||
|           "output-power": 0.0019952623149688794, | ||||
|           "path_bandwidth": 20000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "6", | ||||
|       "source": "trx Lannion_CAS", | ||||
|       "destination": "trx a", | ||||
|       "src-tp-id": "trx Lannion_CAS", | ||||
|       "dst-tp-id": "trx a", | ||||
|       "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": null, | ||||
|           "output-power": null, | ||||
|           "path_bandwidth": 100000000000.0 | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   ], | ||||
| @@ -201,9 +189,8 @@ | ||||
|     { | ||||
|       "synchronization-id": "3", | ||||
|       "svec": { | ||||
|         "relaxable": "False", | ||||
|         "link-diverse": "True", | ||||
|         "node-diverse": "True", | ||||
|         "relaxable": "false", | ||||
|         "disjointness": "node link", | ||||
|         "request-id-number": [ | ||||
|           "3", | ||||
|           "1" | ||||
| @@ -213,9 +200,8 @@ | ||||
|     { | ||||
|       "synchronization-id": "4", | ||||
|       "svec": { | ||||
|         "relaxable": "False", | ||||
|         "link-diverse": "True", | ||||
|         "node-diverse": "True", | ||||
|         "relaxable": "false", | ||||
|         "disjointness": "node link", | ||||
|         "request-id-number": [ | ||||
|           "4", | ||||
|           "5" | ||||
|   | ||||
| @@ -2,8 +2,8 @@ | ||||
|   "path-request": [ | ||||
|     { | ||||
|       "request-id": "1", | ||||
|       "source": "a", | ||||
|       "destination": "g", | ||||
|       "source": "trx a", | ||||
|       "destination": "trx g", | ||||
|       "src-tp-id": "trx a", | ||||
|       "dst-tp-id": "trx g", | ||||
|       "path-constraints": { | ||||
| @@ -22,15 +22,12 @@ | ||||
|           "output-power": 0.001, | ||||
|           "path_bandwidth": 300000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "2a", | ||||
|       "source": "a", | ||||
|       "destination": "h", | ||||
|       "source": "trx a", | ||||
|       "destination": "trx h", | ||||
|       "src-tp-id": "trx a", | ||||
|       "dst-tp-id": "trx h", | ||||
|       "path-constraints": { | ||||
| @@ -49,15 +46,12 @@ | ||||
|           "output-power": 0.001, | ||||
|           "path_bandwidth": 300000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "3", | ||||
|       "source": "f", | ||||
|       "destination": "b", | ||||
|       "source": "trx f", | ||||
|       "destination": "trx b", | ||||
|       "src-tp-id": "trx f", | ||||
|       "dst-tp-id": "trx b", | ||||
|       "path-constraints": { | ||||
| @@ -76,15 +70,12 @@ | ||||
|           "output-power": 0.001, | ||||
|           "path_bandwidth": 300000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "ee", | ||||
|       "source": "c", | ||||
|       "destination": "f", | ||||
|       "source": "trx c", | ||||
|       "destination": "trx f", | ||||
|       "src-tp-id": "trx c", | ||||
|       "dst-tp-id": "trx f", | ||||
|       "path-constraints": { | ||||
| @@ -104,36 +95,23 @@ | ||||
|           "path_bandwidth": 300000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [ | ||||
|       "explicit-route-objects": { | ||||
|         "route-object-include-exclude": [ | ||||
|           { | ||||
|             "explicit-route-usage": "route-include-ero", | ||||
|             "index": 0, | ||||
|             "unnumbered-hop": { | ||||
|             "num-unnum-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" | ||||
|               } | ||||
|               "hop-type": "LOOSE" | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "explicit-route-usage": "route-include-ero", | ||||
|             "index": 1, | ||||
|             "unnumbered-hop": { | ||||
|             "num-unnum-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" | ||||
|               } | ||||
|               "hop-type": "LOOSE" | ||||
|             } | ||||
|           } | ||||
|         ] | ||||
| @@ -141,8 +119,8 @@ | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "ff", | ||||
|       "source": "c", | ||||
|       "destination": "f", | ||||
|       "source": "trx c", | ||||
|       "destination": "trx f", | ||||
|       "src-tp-id": "trx c", | ||||
|       "dst-tp-id": "trx f", | ||||
|       "path-constraints": { | ||||
| @@ -161,15 +139,12 @@ | ||||
|           "output-power": 0.001, | ||||
|           "path_bandwidth": 300000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "10", | ||||
|       "source": "a", | ||||
|       "destination": "g", | ||||
|       "source": "trx a", | ||||
|       "destination": "trx g", | ||||
|       "src-tp-id": "trx a", | ||||
|       "dst-tp-id": "trx g", | ||||
|       "path-constraints": { | ||||
| @@ -188,15 +163,12 @@ | ||||
|           "output-power": 0.001, | ||||
|           "path_bandwidth": 300000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "11", | ||||
|       "source": "a", | ||||
|       "destination": "h", | ||||
|       "source": "trx a", | ||||
|       "destination": "trx h", | ||||
|       "src-tp-id": "trx a", | ||||
|       "dst-tp-id": "trx h", | ||||
|       "path-constraints": { | ||||
| @@ -216,21 +188,15 @@ | ||||
|           "path_bandwidth": 300000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [ | ||||
|       "explicit-route-objects": { | ||||
|         "route-object-include-exclude": [ | ||||
|           { | ||||
|             "explicit-route-usage": "route-include-ero", | ||||
|             "index": 0, | ||||
|             "unnumbered-hop": { | ||||
|             "num-unnum-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" | ||||
|               } | ||||
|               "hop-type": "LOOSE" | ||||
|             } | ||||
|           } | ||||
|         ] | ||||
| @@ -238,8 +204,8 @@ | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "12", | ||||
|       "source": "f", | ||||
|       "destination": "b", | ||||
|       "source": "trx f", | ||||
|       "destination": "trx b", | ||||
|       "src-tp-id": "trx f", | ||||
|       "dst-tp-id": "trx b", | ||||
|       "path-constraints": { | ||||
| @@ -259,21 +225,15 @@ | ||||
|           "path_bandwidth": 300000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [ | ||||
|       "explicit-route-objects": { | ||||
|         "route-object-include-exclude": [ | ||||
|           { | ||||
|             "explicit-route-usage": "route-include-ero", | ||||
|             "index": 0, | ||||
|             "unnumbered-hop": { | ||||
|             "num-unnum-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" | ||||
|               } | ||||
|               "hop-type": "LOOSE" | ||||
|             } | ||||
|           } | ||||
|         ] | ||||
| @@ -281,8 +241,8 @@ | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "13", | ||||
|       "source": "c", | ||||
|       "destination": "f", | ||||
|       "source": "trx c", | ||||
|       "destination": "trx f", | ||||
|       "src-tp-id": "trx c", | ||||
|       "dst-tp-id": "trx f", | ||||
|       "path-constraints": { | ||||
| @@ -301,15 +261,12 @@ | ||||
|           "output-power": 0.001, | ||||
|           "path_bandwidth": 300000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "14", | ||||
|       "source": "c", | ||||
|       "destination": "f", | ||||
|       "source": "trx c", | ||||
|       "destination": "trx f", | ||||
|       "src-tp-id": "trx c", | ||||
|       "dst-tp-id": "trx f", | ||||
|       "path-constraints": { | ||||
| @@ -329,36 +286,23 @@ | ||||
|           "path_bandwidth": 300000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [ | ||||
|       "explicit-route-objects": { | ||||
|         "route-object-include-exclude": [ | ||||
|           { | ||||
|             "explicit-route-usage": "route-include-ero", | ||||
|             "index": 0, | ||||
|             "unnumbered-hop": { | ||||
|             "num-unnum-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" | ||||
|               } | ||||
|               "hop-type": "LOOSE" | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "explicit-route-usage": "route-include-ero", | ||||
|             "index": 1, | ||||
|             "unnumbered-hop": { | ||||
|             "num-unnum-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" | ||||
|               } | ||||
|               "hop-type": "LOOSE" | ||||
|             } | ||||
|           } | ||||
|         ] | ||||
| @@ -366,8 +310,8 @@ | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "e:1# /", | ||||
|       "source": "a", | ||||
|       "destination": "g", | ||||
|       "source": "trx a", | ||||
|       "destination": "trx g", | ||||
|       "src-tp-id": "trx a", | ||||
|       "dst-tp-id": "trx g", | ||||
|       "path-constraints": { | ||||
| @@ -386,15 +330,12 @@ | ||||
|           "output-power": null, | ||||
|           "path_bandwidth": 300000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "b-2a", | ||||
|       "source": "a", | ||||
|       "destination": "h", | ||||
|       "source": "trx a", | ||||
|       "destination": "trx h", | ||||
|       "src-tp-id": "trx a", | ||||
|       "dst-tp-id": "trx h", | ||||
|       "path-constraints": { | ||||
| @@ -413,15 +354,12 @@ | ||||
|           "output-power": 0.001, | ||||
|           "path_bandwidth": 300000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "3a;?", | ||||
|       "source": "f", | ||||
|       "destination": "b", | ||||
|       "source": "trx f", | ||||
|       "destination": "trx b", | ||||
|       "src-tp-id": "trx f", | ||||
|       "dst-tp-id": "trx b", | ||||
|       "path-constraints": { | ||||
| @@ -440,15 +378,12 @@ | ||||
|           "output-power": null, | ||||
|           "path_bandwidth": 300000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "ee-s", | ||||
|       "source": "c", | ||||
|       "destination": "f", | ||||
|       "source": "trx c", | ||||
|       "destination": "trx f", | ||||
|       "src-tp-id": "trx c", | ||||
|       "dst-tp-id": "trx f", | ||||
|       "path-constraints": { | ||||
| @@ -468,36 +403,23 @@ | ||||
|           "path_bandwidth": 300000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [ | ||||
|       "explicit-route-objects": { | ||||
|         "route-object-include-exclude": [ | ||||
|           { | ||||
|             "explicit-route-usage": "route-include-ero", | ||||
|             "index": 0, | ||||
|             "unnumbered-hop": { | ||||
|             "num-unnum-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" | ||||
|               } | ||||
|               "hop-type": "LOOSE" | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "explicit-route-usage": "route-include-ero", | ||||
|             "index": 1, | ||||
|             "unnumbered-hop": { | ||||
|             "num-unnum-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" | ||||
|               } | ||||
|               "hop-type": "LOOSE" | ||||
|             } | ||||
|           } | ||||
|         ] | ||||
| @@ -505,8 +427,8 @@ | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "ff-b", | ||||
|       "source": "c", | ||||
|       "destination": "f", | ||||
|       "source": "trx c", | ||||
|       "destination": "trx f", | ||||
|       "src-tp-id": "trx c", | ||||
|       "dst-tp-id": "trx f", | ||||
|       "path-constraints": { | ||||
| @@ -525,15 +447,12 @@ | ||||
|           "output-power": 0.001, | ||||
|           "path_bandwidth": 300000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "10-z", | ||||
|       "source": "a", | ||||
|       "destination": "g", | ||||
|       "source": "trx a", | ||||
|       "destination": "trx g", | ||||
|       "src-tp-id": "trx a", | ||||
|       "dst-tp-id": "trx g", | ||||
|       "path-constraints": { | ||||
| @@ -552,15 +471,12 @@ | ||||
|           "output-power": null, | ||||
|           "path_bandwidth": 300000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "11 g", | ||||
|       "source": "a", | ||||
|       "destination": "h", | ||||
|       "source": "trx a", | ||||
|       "destination": "trx h", | ||||
|       "src-tp-id": "trx a", | ||||
|       "dst-tp-id": "trx h", | ||||
|       "path-constraints": { | ||||
| @@ -579,15 +495,12 @@ | ||||
|           "output-power": null, | ||||
|           "path_bandwidth": 300000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "12<", | ||||
|       "source": "f", | ||||
|       "destination": "b", | ||||
|       "source": "trx f", | ||||
|       "destination": "trx b", | ||||
|       "src-tp-id": "trx f", | ||||
|       "dst-tp-id": "trx b", | ||||
|       "path-constraints": { | ||||
| @@ -606,15 +519,12 @@ | ||||
|           "output-power": null, | ||||
|           "path_bandwidth": null | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "12>", | ||||
|       "source": "f", | ||||
|       "destination": "b", | ||||
|       "source": "trx f", | ||||
|       "destination": "trx b", | ||||
|       "src-tp-id": "trx f", | ||||
|       "dst-tp-id": "trx b", | ||||
|       "path-constraints": { | ||||
| @@ -633,9 +543,6 @@ | ||||
|           "output-power": null, | ||||
|           "path_bandwidth": null | ||||
|         } | ||||
|       }, | ||||
|       "optimizations": { | ||||
|         "explicit-route-include-objects": [] | ||||
|       } | ||||
|     } | ||||
|   ], | ||||
| @@ -644,8 +551,7 @@ | ||||
|       "synchronization-id": "1", | ||||
|       "svec": { | ||||
|         "relaxable": "False", | ||||
|         "link-diverse": "True", | ||||
|         "node-diverse": "True", | ||||
|         "disjointness": "node link", | ||||
|         "request-id-number": [ | ||||
|           "1", | ||||
|           "2a" | ||||
| @@ -656,8 +562,7 @@ | ||||
|       "synchronization-id": "3", | ||||
|       "svec": { | ||||
|         "relaxable": "False", | ||||
|         "link-diverse": "True", | ||||
|         "node-diverse": "True", | ||||
|         "disjointness": "node link", | ||||
|         "request-id-number": [ | ||||
|           "3", | ||||
|           "1" | ||||
| @@ -668,8 +573,7 @@ | ||||
|       "synchronization-id": "ff", | ||||
|       "svec": { | ||||
|         "relaxable": "False", | ||||
|         "link-diverse": "True", | ||||
|         "node-diverse": "True", | ||||
|         "disjointness": "node link", | ||||
|         "request-id-number": [ | ||||
|           "ff", | ||||
|           "13" | ||||
| @@ -680,8 +584,7 @@ | ||||
|       "synchronization-id": "13", | ||||
|       "svec": { | ||||
|         "relaxable": "False", | ||||
|         "link-diverse": "True", | ||||
|         "node-diverse": "True", | ||||
|         "disjointness": "node link", | ||||
|         "request-id-number": [ | ||||
|           "13", | ||||
|           "14" | ||||
|   | ||||
| @@ -3,38 +3,48 @@ | ||||
| # @Author: Esther Le Rouzic | ||||
| # @Date:   2018-06-15 | ||||
|  | ||||
| from gnpy.core.elements import Edfa | ||||
| import numpy as np | ||||
| """ Adding tests to check the parser non regression | ||||
|     convention of naming of test files: | ||||
|     - ..._expected.json for the reference output | ||||
|     tests: | ||||
|     - generation of topology json | ||||
|     - reading of Eqpt sheet w and W/ power mode | ||||
|     - consistency of autodesign | ||||
|     - generation of service list based on service sheet | ||||
|     - writing of results in csv | ||||
|     - writing of results in json (same keys) | ||||
| """ | ||||
|  | ||||
| from json import load | ||||
| from pathlib import Path | ||||
| from os import unlink | ||||
| from pandas import read_csv | ||||
| import pytest | ||||
| from gnpy.core import network_from_json | ||||
| from gnpy.core.elements import Transceiver, Fiber, Edfa | ||||
| from gnpy.core.utils import lin2db, db2lin | ||||
| from gnpy.core.info import SpectralInformation, Channel, Power | ||||
| from gnpy.core.network import save_network, build_network | ||||
| from tests.compare import compare_networks, compare_services | ||||
| from gnpy.core.utils import lin2db | ||||
| from gnpy.core.network import save_network, build_network | ||||
| from gnpy.core.convert import convert_file | ||||
| from gnpy.core.service_sheet import convert_service_sheet | ||||
| from gnpy.core.equipment import load_equipment, automatic_nch | ||||
| from gnpy.core.network import load_network | ||||
| from pathlib import Path | ||||
| import filecmp | ||||
| from os import unlink | ||||
| from gnpy.core.request import (jsontocsv, requests_aggregation, | ||||
|                                compute_path_dsjctn, Result_element) | ||||
| from examples.path_requests_run import (requests_from_json, disjunctions_from_json, | ||||
|                                         correct_route_list, correct_disjn, | ||||
|                                         compute_path_with_disjunction) | ||||
|  | ||||
| TEST_DIR = Path(__file__).parent | ||||
| DATA_DIR = TEST_DIR / 'data' | ||||
| eqpt_filename = DATA_DIR / 'eqpt_config.json' | ||||
|  | ||||
| # adding tests to check the parser non regression | ||||
| # convention of naming of test files: | ||||
| # | ||||
| #    - ..._expected.json for the reference output | ||||
|  | ||||
| @pytest.mark.parametrize('xls_input,expected_json_output', { | ||||
|     DATA_DIR / 'CORONET_Global_Topology.xls':   DATA_DIR / 'CORONET_Global_Topology_expected.json', | ||||
|     DATA_DIR / 'testTopology.xls':     DATA_DIR / 'testTopology_expected.json', | ||||
|  }.items()) | ||||
|     }.items()) | ||||
| def test_excel_json_generation(xls_input, expected_json_output): | ||||
|     """ tests generation of topology json | ||||
|     """ | ||||
|     convert_file(xls_input) | ||||
|  | ||||
|     actual_json_output = xls_input.with_suffix('.json') | ||||
| @@ -55,20 +65,25 @@ def test_excel_json_generation(xls_input, expected_json_output): | ||||
|  | ||||
| # assume xls entries | ||||
| # test that the build network gives correct results in gain mode | ||||
| #  | ||||
| @pytest.mark.parametrize('xls_input,expected_json_output', { | ||||
|     DATA_DIR / 'CORONET_Global_Topology.xls':   DATA_DIR / 'CORONET_Global_Topology_auto_design_expected.json', | ||||
|     DATA_DIR / 'testTopology.xls':     DATA_DIR / 'testTopology_auto_design_expected.json', | ||||
|  }.items()) | ||||
|  | ||||
| @pytest.mark.parametrize('xls_input,expected_json_output', | ||||
|                          {DATA_DIR / 'CORONET_Global_Topology.xls':\ | ||||
|                           DATA_DIR / 'CORONET_Global_Topology_auto_design_expected.json', | ||||
|                           DATA_DIR / 'testTopology.xls':\ | ||||
|                           DATA_DIR / 'testTopology_auto_design_expected.json', | ||||
|                          }.items()) | ||||
| def test_auto_design_generation_fromxlsgainmode(xls_input, expected_json_output): | ||||
|     """ tests generation of topology json | ||||
|         test that the build network gives correct results in gain mode | ||||
|     """ | ||||
|     equipment = load_equipment(eqpt_filename) | ||||
|     network = load_network(xls_input,equipment) | ||||
|     # in order to test the Eqpt sheet and load gain target, change the power-mode to False (to be in gain mode) | ||||
|     network = load_network(xls_input, equipment) | ||||
|     # in order to test the Eqpt sheet and load gain target, | ||||
|     # change the power-mode to False (to be in gain mode) | ||||
|     equipment['Span']['default'].power_mode = False | ||||
|     # Build the network once using the default power defined in SI in eqpt config | ||||
|  | ||||
|     p_db = equipment['SI']['default'].power_dbm | ||||
|      | ||||
|     p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,\ | ||||
|         equipment['SI']['default'].f_max, equipment['SI']['default'].spacing)) | ||||
|     build_network(network, equipment, p_db, p_total_db) | ||||
| @@ -92,19 +107,23 @@ def test_auto_design_generation_fromxlsgainmode(xls_input, expected_json_output) | ||||
|     assert not results.connections.different | ||||
|  | ||||
| #test that autodesign creates same file as an input file already autodesigned | ||||
| @pytest.mark.parametrize('json_input,expected_json_output', { | ||||
|     DATA_DIR / 'CORONET_Global_Topology_auto_design_expected.json':   DATA_DIR / 'CORONET_Global_Topology_auto_design_expected.json', | ||||
|     DATA_DIR / 'testTopology_auto_design_expected.json':     DATA_DIR / 'testTopology_auto_design_expected.json', | ||||
|  }.items()) | ||||
| @pytest.mark.parametrize('json_input,expected_json_output', | ||||
|                          {DATA_DIR / 'CORONET_Global_Topology_auto_design_expected.json':\ | ||||
|                           DATA_DIR / 'CORONET_Global_Topology_auto_design_expected.json', | ||||
|                           DATA_DIR / 'testTopology_auto_design_expected.json':\ | ||||
|                           DATA_DIR / 'testTopology_auto_design_expected.json', | ||||
|                          }.items()) | ||||
| def test_auto_design_generation_fromjson(json_input, expected_json_output): | ||||
|     """test that autodesign creates same file as an input file already autodesigned | ||||
|     """ | ||||
|     equipment = load_equipment(eqpt_filename) | ||||
|     network = load_network(json_input,equipment) | ||||
|     # in order to test the Eqpt sheet and load gain target, change the power-mode to False (to be in gain mode) | ||||
|     network = load_network(json_input, equipment) | ||||
|     # in order to test the Eqpt sheet and load gain target, | ||||
|     # change the power-mode to False (to be in gain mode) | ||||
|     equipment['Span']['default'].power_mode = False | ||||
|     # Build the network once using the default power defined in SI in eqpt config | ||||
|  | ||||
|     p_db = equipment['SI']['default'].power_dbm | ||||
|      | ||||
|     p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,\ | ||||
|         equipment['SI']['default'].f_max, equipment['SI']['default'].spacing)) | ||||
|     build_network(network, equipment, p_db, p_total_db) | ||||
| @@ -131,8 +150,10 @@ def test_auto_design_generation_fromjson(json_input, expected_json_output): | ||||
|  | ||||
| @pytest.mark.parametrize('xls_input,expected_json_output', { | ||||
|     DATA_DIR / 'testTopology.xls':     DATA_DIR / 'testTopology_services_expected.json', | ||||
| }.items()) | ||||
|     }.items()) | ||||
| def test_excel_service_json_generation(xls_input, expected_json_output): | ||||
|     """ test services creation | ||||
|     """ | ||||
|     convert_service_sheet(xls_input, eqpt_filename) | ||||
|  | ||||
|     actual_json_output = f'{str(xls_input)[:-4]}_services.json' | ||||
| @@ -150,3 +171,128 @@ def test_excel_service_json_generation(xls_input, expected_json_output): | ||||
|     assert not results.synchronizations.missing | ||||
|     assert not results.synchronizations.extra | ||||
|     assert not results.synchronizations.different | ||||
|  | ||||
| # test xls answers creation | ||||
| @pytest.mark.parametrize('json_input, csv_output', { | ||||
|     DATA_DIR / 'testTopology_response.json':     DATA_DIR / 'testTopology_response', | ||||
| }.items()) | ||||
| def test_csv_response_generation(json_input, csv_output): | ||||
|     """ tests if generated csv is consistant with expected generation | ||||
|         same columns (order not important) | ||||
|     """ | ||||
|     with open(json_input) as jsonfile: | ||||
|         json_data = load(jsonfile) | ||||
|     equipment = load_equipment(eqpt_filename) | ||||
|     csv_filename = str(csv_output)+'.csv' | ||||
|     with open(csv_filename, 'w', encoding='utf-8') as fcsv: | ||||
|         jsontocsv(json_data, equipment, fcsv) | ||||
|  | ||||
|     expected_csv_filename = str(csv_output)+'_expected.csv' | ||||
|  | ||||
|     # expected header | ||||
|     # csv_header = \ | ||||
|     # [ | ||||
|     #  'response-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' | ||||
|     # ] | ||||
|  | ||||
|     resp = read_csv(csv_filename) | ||||
|     unlink(csv_filename) | ||||
|     expected_resp = read_csv(expected_csv_filename) | ||||
|     resp_header = list(resp.head(0)) | ||||
|     expected_resp_header = list(expected_resp.head(0)) | ||||
|     # check that headers are the same | ||||
|     resp_header.sort() | ||||
|     expected_resp_header.sort() | ||||
|     print('headers are differents') | ||||
|     print(resp_header) | ||||
|     print(expected_resp_header) | ||||
|     assert resp_header == expected_resp_header | ||||
|  | ||||
|     # for each header checks that the output are as expected | ||||
|     resp.sort_values(by=['response-id']) | ||||
|     expected_resp.sort_values(by=['response-id']) | ||||
|  | ||||
|     for column in expected_resp: | ||||
|         assert list(resp[column].fillna('')) == list(expected_resp[column].fillna('')) | ||||
|         print('results are different') | ||||
|         print(list(resp[column])) | ||||
|         print(list(expected_resp[column])) | ||||
|         print(type(list(resp[column])[-1])) | ||||
|  | ||||
| def compare_response(exp_resp, act_resp): | ||||
|     """ False if the keys are different in the nested dicts as well | ||||
|     """ | ||||
|     print(exp_resp) | ||||
|     print(act_resp) | ||||
|     test = True | ||||
|     for key in act_resp.keys(): | ||||
|         print(key) | ||||
|         if not key in exp_resp.keys(): | ||||
|             print(key) | ||||
|             return False | ||||
|         if isinstance(act_resp[key], dict): | ||||
|             test = compare_response(exp_resp[key], act_resp[key]) | ||||
|     if test: | ||||
|         for key in exp_resp.keys(): | ||||
|             if not key in act_resp.keys(): | ||||
|                 print(key) | ||||
|                 return False | ||||
|             if isinstance(exp_resp[key], dict): | ||||
|                 test = compare_response(exp_resp[key], act_resp[key]) | ||||
|     # at this point exp_resp and act_resp have the same keys. Check if their values are the same | ||||
|     for key in act_resp.keys(): | ||||
|         if not isinstance(act_resp[key], dict): | ||||
|             if exp_resp[key] != act_resp[key]: | ||||
|                 return False | ||||
|     return test | ||||
|  | ||||
|  | ||||
| # test json answers creation | ||||
| @pytest.mark.parametrize('xls_input, expected_response_file', { | ||||
|     DATA_DIR / 'testTopology.xls':     DATA_DIR / 'testTopology_response.json', | ||||
| }.items()) | ||||
| def test_json_response_generation(xls_input, expected_response_file): | ||||
|     """ tests if json response is correctly generated for all combinations of requests | ||||
|     """ | ||||
|     data = convert_service_sheet(xls_input, eqpt_filename) | ||||
|     equipment = load_equipment(eqpt_filename) | ||||
|     network = load_network(xls_input, equipment) | ||||
|     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) | ||||
|     dsjn = correct_disjn(dsjn) | ||||
|     rqs, dsjn = requests_aggregation(rqs, dsjn) | ||||
|     pths = compute_path_dsjctn(network, equipment, rqs, dsjn) | ||||
|     propagatedpths = compute_path_with_disjunction(network, equipment, rqs, pths) | ||||
|     result = [] | ||||
|     for i, pth in enumerate(propagatedpths): | ||||
|         result.append(Result_element(rqs[i], pth)) | ||||
|     temp = { | ||||
|         'response': [n.json for n in result] | ||||
|     } | ||||
|     # load expected result and compare keys | ||||
|     # (not values at this stage) | ||||
|     with open(expected_response_file) as jsonfile: | ||||
|         expected = load(jsonfile) | ||||
|  | ||||
|     for i, response in enumerate(temp['response']): | ||||
|         assert compare_response(expected['response'][i], response) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user