mirror of
				https://github.com/Telecominfraproject/oopt-gnpy.git
				synced 2025-10-30 17:47:50 +00:00 
			
		
		
		
	Compare commits
	
		
			32 Commits
		
	
	
		
			v2.11
			...
			experiment
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 049b077ee4 | ||
|   | ab2080a805 | ||
|   | 8ab54e76df | ||
|   | f015c6abed | ||
|   | 71293c1c18 | ||
|   | bd7c70f902 | ||
|   | 20c92d4338 | ||
|   | f0158e7202 | ||
|   | 62408ddc98 | ||
|   | b4f87b36db | ||
|   | 9f49a115a1 | ||
|   | c7d2305589 | ||
|   | 5826a649de | ||
|   | fa826391f6 | ||
|   | 3481ba8ee3 | ||
|   | b4ab0b55de | ||
|   | 0370b45d8a | ||
|   | 468e689094 | ||
|   | aafd82b16d | ||
|   | 60ee331153 | ||
|   | 3a8ce74355 | ||
|   | fd44463238 | ||
|   | 84ba2da553 | ||
|   | e693d96ca1 | ||
|   | 81cb7f8133 | ||
|   | 3471969956 | ||
|   | 7a0985c362 | ||
|   | b79a9e2e67 | ||
|   | 1e037fe6f5 | ||
|   | 0897be57c1 | ||
|   | 4172b06b19 | ||
|   | 32a4875e46 | 
| @@ -5,17 +5,16 @@ set -e | ||||
| IMAGE_NAME=telecominfraproject/oopt-gnpy | ||||
| IMAGE_TAG=$(git describe --tags) | ||||
|  | ||||
| if [[ "${TRAVIS_BRANCH}" == "experimental/2019-summit" ]]; then | ||||
|   IMAGE_NAME=telecominfraproject/oopt-gnpy-experimental | ||||
| fi | ||||
|  | ||||
| ALREADY_FOUND=0 | ||||
| docker pull ${IMAGE_NAME}:${IMAGE_TAG} && ALREADY_FOUND=1 | ||||
|  | ||||
| if [[ $ALREADY_FOUND == 0 ]]; then | ||||
|   docker build . -t ${IMAGE_NAME} | ||||
|   docker tag ${IMAGE_NAME} ${IMAGE_NAME}:${IMAGE_TAG} | ||||
|  | ||||
|   # shared directory setup: do not clobber the real data | ||||
|   mkdir trash | ||||
|   cd trash | ||||
|   docker run -it --rm --volume $(pwd):/shared ${IMAGE_NAME} ./transmission_main_example.py | ||||
| else | ||||
|   echo "Image ${IMAGE_NAME}:${IMAGE_TAG} already available, will just update the other tags" | ||||
| fi | ||||
| @@ -43,5 +42,11 @@ if [[ "${TRAVIS_PULL_REQUEST}" == "false" ]]; then | ||||
|       docker push ${IMAGE_NAME}:${IMAGE_TAG} | ||||
|     fi | ||||
|     docker push ${IMAGE_NAME}:stable | ||||
|   elif [[ "${TRAVIS_BRANCH}" == "experimental/2019-summit" ]]; then | ||||
|     echo "Publishing ad-hoc image for the TIP Summit demo" | ||||
|     do_docker_login | ||||
|     if [[ $ALREADY_FOUND == 0 ]]; then | ||||
|       docker push ${IMAGE_NAME}:${IMAGE_TAG} | ||||
|     fi | ||||
|   fi | ||||
| fi | ||||
|   | ||||
| @@ -2,6 +2,7 @@ FROM python:3.7-slim | ||||
| COPY . /oopt-gnpy | ||||
| WORKDIR /oopt-gnpy | ||||
| RUN python setup.py install | ||||
| WORKDIR /shared/examples | ||||
| WORKDIR /shared | ||||
| ENTRYPOINT ["/oopt-gnpy/.docker-entry.sh"] | ||||
| CMD ["/bin/bash"] | ||||
| CMD ["python", "examples/path_requests_run.py", "examples/2019-demo-topology.json", "examples/2019-demo-services.json", "examples/2019-demo-equipment.json", "--rest"] | ||||
| EXPOSE 5000 | ||||
|   | ||||
							
								
								
									
										124
									
								
								examples/2019-demo-equipment.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								examples/2019-demo-equipment.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,124 @@ | ||||
| {     "Edfa":[ | ||||
|  | ||||
|             { | ||||
|             "type_variety": "fixed27", | ||||
|             "type_def": "fixed_gain", | ||||
|             "gain_flatmax": 27, | ||||
|             "gain_min": 27, | ||||
|             "p_max": 21, | ||||
|             "nf0": 5.5, | ||||
|             "allowed_for_design": false | ||||
|             }, | ||||
|  | ||||
|             { | ||||
|             "type_variety": "fixed22", | ||||
|             "type_def": "fixed_gain", | ||||
|             "gain_flatmax": 22, | ||||
|             "gain_min": 22, | ||||
|             "p_max": 21, | ||||
|             "nf0": 5.5, | ||||
|             "allowed_for_design": false | ||||
|             } | ||||
|       ], | ||||
|       "Fiber":[{ | ||||
|             "type_variety": "SSMF", | ||||
|             "dispersion": 1.67e-05, | ||||
|             "gamma": 0.00127 | ||||
|             }, | ||||
|             { | ||||
|             "type_variety": "NZDF", | ||||
|             "dispersion": 0.5e-05, | ||||
|             "gamma": 0.00146 | ||||
|             }, | ||||
|             { | ||||
|             "type_variety": "LOF", | ||||
|             "dispersion": 2.2e-05, | ||||
|             "gamma": 0.000843 | ||||
|             } | ||||
|       ], | ||||
|       "Span":[{ | ||||
|             "power_mode": false, | ||||
|             "delta_power_range_db": [-2,3,0.5], | ||||
|             "max_fiber_lineic_loss_for_raman": 0.25, | ||||
|             "target_extended_gain": 2.5, | ||||
|             "max_length": 150, | ||||
|             "length_units": "km", | ||||
|             "max_loss": 28, | ||||
|             "padding": 10, | ||||
|             "EOL": 0, | ||||
|             "con_in": 0, | ||||
|             "con_out": 0 | ||||
|             } | ||||
|       ], | ||||
|       "Roadm":[{ | ||||
|             "target_pch_out_db": -25, | ||||
|             "add_drop_osnr": 30.00, | ||||
|             "restrictions": { | ||||
|                             "preamp_variety_list":[], | ||||
|                             "booster_variety_list":[] | ||||
|                             }             | ||||
|             }], | ||||
|       "SI":[{ | ||||
|             "f_min": 191.6e12, | ||||
|             "baud_rate": 32e9, | ||||
|             "f_max":195.1e12, | ||||
|             "spacing": 50e9, | ||||
|             "power_dbm": 0, | ||||
|             "power_range_db": [0,0,1], | ||||
|             "roll_off": 0.15, | ||||
|             "tx_osnr": 40, | ||||
|             "sys_margins": 2 | ||||
|             }], | ||||
|       "Transceiver":[ | ||||
|             { | ||||
|             "type_variety": "Cassini", | ||||
|             "frequency":{ | ||||
|                         "min": 191.35e12, | ||||
|                         "max": 196.1e12 | ||||
|                         }, | ||||
|             "mode":[ | ||||
|                        { | ||||
|  | ||||
|                        "format": "dp-qpsk", | ||||
|                        "baud_rate": 32e9, | ||||
|                        "OSNR": 11, | ||||
|                        "bit_rate": 100e9, | ||||
|                        "roll_off": 0.15, | ||||
|                        "tx_osnr": 40, | ||||
|                        "min_spacing": 37.5e9, | ||||
|                        "cost":1 | ||||
|                        }, | ||||
|                        { | ||||
|                        "format": "16-qam", | ||||
|                        "baud_rate": 66e9, | ||||
|                        "OSNR": 15, | ||||
|                        "bit_rate": 200e9, | ||||
|                        "roll_off": 0.15, | ||||
|                        "tx_osnr": 40, | ||||
|                        "min_spacing": 75e9, | ||||
|                        "cost":1 | ||||
|                        } | ||||
|                    ] | ||||
|             }, | ||||
|             { | ||||
|             "type_variety": "Voyager", | ||||
|             "frequency":{ | ||||
|                         "min": 191.35e12, | ||||
|                         "max": 196.1e12 | ||||
|                         }, | ||||
|             "mode":[ | ||||
|                        { | ||||
|                        "format": "mode 1", | ||||
|                        "baud_rate": 32e9, | ||||
|                        "OSNR": 12, | ||||
|                        "bit_rate": 100e9, | ||||
|                        "roll_off": 0.15, | ||||
|                        "tx_osnr": 40, | ||||
|                        "min_spacing": 37.5e9, | ||||
|                        "cost":1 | ||||
|                        } | ||||
|                    ] | ||||
|             } | ||||
|       ] | ||||
|  | ||||
| } | ||||
							
								
								
									
										67
									
								
								examples/2019-demo-services.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								examples/2019-demo-services.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| { | ||||
|   "path-request": [ | ||||
|     { | ||||
|       "request-id": "first", | ||||
|       "source": "netconf:10.0.254.93:830", | ||||
|       "destination": "netconf:10.0.254.94:830", | ||||
|       "src-tp-id": "trx-Amsterdam", | ||||
|       "dst-tp-id": "trx-Bremen", | ||||
|       "bidirectional": true, | ||||
|       "path-constraints": { | ||||
|         "te-bandwidth": { | ||||
|           "technology": "flexi-grid", | ||||
|           "trx_type": "Cassini", | ||||
|           "trx_mode": null, | ||||
|           "effective-freq-slot": [ | ||||
|             { | ||||
|               "N": "null", | ||||
|               "M": "null" | ||||
|             } | ||||
|           ], | ||||
|           "spacing": 50000000000.0, | ||||
|           "max-nb-of-channel": null, | ||||
|           "output-power": null, | ||||
|           "path_bandwidth": 100000000000.0 | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "second", | ||||
|       "source": "netconf:10.0.254.93:830", | ||||
|       "destination": "netconf:10.0.254.94:830", | ||||
|       "src-tp-id": "trx-Amsterdam", | ||||
|       "dst-tp-id": "trx-Bremen", | ||||
|       "bidirectional": true, | ||||
|       "path-constraints": { | ||||
|         "te-bandwidth": { | ||||
|           "technology": "flexi-grid", | ||||
|           "trx_type": "Cassini", | ||||
|           "trx_mode": null, | ||||
|           "effective-freq-slot": [ | ||||
|             { | ||||
|               "N": "null", | ||||
|               "M": "null" | ||||
|             } | ||||
|           ], | ||||
|           "spacing": 50000000000.0, | ||||
|           "max-nb-of-channel": null, | ||||
|           "output-power": null, | ||||
|           "path_bandwidth": 100000000000.0 | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   ], | ||||
|   "synchronization": [ | ||||
|     { | ||||
|       "synchronization-id": "some redundancy please", | ||||
|       "svec": { | ||||
|         "relaxable": "false", | ||||
|         "disjointness": "node link", | ||||
|         "request-id-number": [ | ||||
|           "first", | ||||
|           "second" | ||||
|         ] | ||||
|       } | ||||
|     } | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										1263
									
								
								examples/2019-demo-topology.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1263
									
								
								examples/2019-demo-topology.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										179
									
								
								examples/2019-generate-tip-demo.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								examples/2019-generate-tip-demo.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,179 @@ | ||||
| # How many nodes in the ring topology? Up to eight is supported, then I ran out of cities.. | ||||
| HOW_MANY = 3 | ||||
|  | ||||
| # city names | ||||
| ALL_CITIES = [ | ||||
|     'Amsterdam', | ||||
|     'Bremen', | ||||
|     'Cologne', | ||||
|     'Dueseldorf', | ||||
|     'Eindhoven', | ||||
|     'Frankfurt', | ||||
|     'Ghent', | ||||
|     'Hague', | ||||
| ] | ||||
| # end of configurable parameters | ||||
|  | ||||
|  | ||||
| J = { | ||||
|     "elements": [], | ||||
|     "connections": [], | ||||
| } | ||||
|  | ||||
| def unidir_join(a, b): | ||||
|     global J | ||||
|     J["connections"].append( | ||||
|         {"from_node": a, "to_node": b} | ||||
|     ) | ||||
|  | ||||
| def mk_edfa(name, gain, voa=0.0): | ||||
|     global J | ||||
|     J["elements"].append( | ||||
|         {"uid": name, "type": "Edfa", "type_variety": f"fixed{gain}", "operational": {"gain_target": gain, "out_voa": voa}} | ||||
|     ) | ||||
|  | ||||
| def add_att(a, b, att): | ||||
|     global J | ||||
|     if att > 0: | ||||
|         uid = f"att-({a})-({b})" | ||||
|     else: | ||||
|         uid = f"splice-({a})-({b})" | ||||
|     J["elements"].append( | ||||
|         {"uid": uid, "type": "Fused", "params": {"loss": att}}, | ||||
|     ) | ||||
|     unidir_join(a, uid) | ||||
|     unidir_join(uid, b) | ||||
|     return uid | ||||
|  | ||||
| def build_fiber(city1, city2): | ||||
|     global J | ||||
|     J["elements"].append( | ||||
|         { | ||||
|             "uid": f"fiber-{city1}-{city2}", | ||||
|             "type": "Fiber", | ||||
|             "type_variety": "SSMF", | ||||
|             "params": { | ||||
|                 "length": 50, | ||||
|                 "length_units": "km", | ||||
|                 "loss_coef": 0.2, | ||||
|                 "con_in": 1.5, | ||||
|                 "con_out": 1.5, | ||||
|             } | ||||
|         } | ||||
|     ) | ||||
|  | ||||
| def unidir_patch(a, b): | ||||
|     global J | ||||
|     uid = f"patch-({a})-({b})" | ||||
|     J["elements"].append( | ||||
|         { | ||||
|             "uid": uid, | ||||
|             "type": "Fiber", | ||||
|             "type_variety": "SSMF", | ||||
|             "params": { | ||||
|                 "length": 0, | ||||
|                 "length_units": "km", | ||||
|                 "loss_coef": 0.2, | ||||
|                 "con_in": 0.5, | ||||
|                 "con_out": 0.5, | ||||
|             } | ||||
|         } | ||||
|     ) | ||||
|     add_att(a, uid, 0.0) | ||||
|     add_att(uid, b, 0.0) | ||||
|  | ||||
| for CITY in (ALL_CITIES[x] for x in range(0, HOW_MANY)): | ||||
|     J["elements"].append( | ||||
|         {"uid": f"trx-{CITY}", "type": "Transceiver"} | ||||
|     ) | ||||
|     target_pwr = [ | ||||
|         {"to_node": f"trx-{CITY}", "target_pch_out_db": -25}, | ||||
|         {"to_node": f"splice-(roadm-{CITY}-AD)-(patch-(roadm-{CITY}-AD)-(roadm-{CITY}-L1))", "target_pch_out_db": -12}, | ||||
|         {"to_node": f"splice-(roadm-{CITY}-AD)-(patch-(roadm-{CITY}-AD)-(roadm-{CITY}-L2))", "target_pch_out_db": -12}, | ||||
|     ] | ||||
|     J["elements"].append( | ||||
|         {"uid": f"roadm-{CITY}-AD", "type": "Roadm", "params": {"target_pch_out_db": -2.0, "per_degree_target_pch_out_db": target_pwr}} | ||||
|     ) | ||||
|     unidir_join(f"trx-{CITY}", f"roadm-{CITY}-AD") | ||||
|     unidir_join(f"roadm-{CITY}-AD", f"trx-{CITY}") | ||||
|  | ||||
|     for n in (1,2): | ||||
|         target_pwr = [ | ||||
|             {"to_node": f"roadm-{CITY}-L{n}-booster", "target_pch_out_db": -23}, | ||||
|             {"to_node": f"splice-(roadm-{CITY}-L{n})-(patch-(roadm-{CITY}-L{n})-(roadm-{CITY}-AD))", "target_pch_out_db": -12}, | ||||
|         ] | ||||
|         for m in (1,2): | ||||
|             if m == n: | ||||
|                 continue | ||||
|             target_pwr.append( | ||||
|               {"to_node": f"splice-(roadm-{CITY}-L{n})-(patch-(roadm-{CITY}-L{n})-(roadm-{CITY}-L{m}))", "target_pch_out_db": -12}, | ||||
|             ) | ||||
|         J["elements"].append( | ||||
|             {"uid": f"roadm-{CITY}-L{n}", "type": "Roadm", "params": {"target_pch_out_db": -23.0, "per_degree_target_pch_out_db": target_pwr}} | ||||
|         ) | ||||
|         mk_edfa(f"roadm-{CITY}-L{n}-booster", 22) | ||||
|         mk_edfa(f"roadm-{CITY}-L{n}-preamp", 27) | ||||
|         unidir_join(f"roadm-{CITY}-L{n}", f"roadm-{CITY}-L{n}-booster") | ||||
|         unidir_join(f"roadm-{CITY}-L{n}-preamp", f"roadm-{CITY}-L{n}") | ||||
|  | ||||
|         unidir_patch(f"roadm-{CITY}-AD", f"roadm-{CITY}-L{n}") | ||||
|         unidir_patch(f"roadm-{CITY}-L{n}", f"roadm-{CITY}-AD") | ||||
|         for m in (1,2): | ||||
|             if m == n: | ||||
|                 continue | ||||
|             #add_att(f"roadm-{CITY}-L{n}", f"roadm-{CITY}-L{m}", 22) | ||||
|             unidir_patch(f"roadm-{CITY}-L{n}", f"roadm-{CITY}-L{m}") | ||||
|  | ||||
| for city1, city2 in ((ALL_CITIES[i], ALL_CITIES[i + 1] if i < HOW_MANY - 1 else ALL_CITIES[0]) for i in range(0, HOW_MANY)): | ||||
|     build_fiber(city1, city2) | ||||
|     unidir_join(f"roadm-{city1}-L1-booster", f"fiber-{city1}-{city2}") | ||||
|     unidir_join(f"fiber-{city1}-{city2}", f"roadm-{city2}-L2-preamp") | ||||
|     build_fiber(city2, city1) | ||||
|     unidir_join(f"roadm-{city2}-L2-booster", f"fiber-{city2}-{city1}") | ||||
|     unidir_join(f"fiber-{city2}-{city1}", f"roadm-{city1}-L1-preamp") | ||||
|  | ||||
|  | ||||
| for _, E in enumerate(J["elements"]): | ||||
|     uid = E["uid"] | ||||
|     if uid.startswith("roadm-") and (uid.endswith("-L1-booster") or uid.endswith("-L2-booster")): | ||||
|         E["operational"]["out_voa"] = 12.0 | ||||
|     #if uid.endswith("-AD-add"): | ||||
|     #    E["operational"]["out_voa"] = 21 | ||||
|  | ||||
| translate = { | ||||
|     #"trx-Amsterdam": "10.0.254.93", | ||||
|     #"trx-Bremen": "10.0.254.94", | ||||
|     "trx-Amsterdam": "10.0.254.76", | ||||
|     "trx-Bremen": "10.0.254.77", | ||||
|  | ||||
|     # Amsterdam A/D: coherent-v9u | ||||
|     "roadm-Amsterdam-AD": "10.0.254.107", | ||||
|     # Bremen A/D: -spi | ||||
|     "roadm-Bremen-AD": "10.0.254.225", | ||||
|  | ||||
|     # Amsterdam -> Bremen ...QR79 | ||||
|     "roadm-Amsterdam-L1": "10.0.254.78", | ||||
|     # Bremen -> Amsterdam ...QCP9 | ||||
|     "roadm-Bremen-L2": "10.0.254.102", | ||||
|  | ||||
|     # Bremen -> Cologne ...WKP | ||||
|     "roadm-Bremen-L1": "10.0.254.100", | ||||
|     # Cologne -> Bremen ...QLK6 | ||||
|     "roadm-Cologne-L2": "10.0.254.104", | ||||
|  | ||||
|     # Cologne -> Amsterdam ...TQQ | ||||
|     "roadm-Cologne-L1": "10.0.254.99", | ||||
|     # Amsterdam -> Cologne ...Q7JS | ||||
|     "roadm-Amsterdam-L2": "10.0.254.79", | ||||
|  | ||||
|     # spare Line/Degree ...QC8B | ||||
|     "spare-line-degree": "10.0.254.101", | ||||
|     # spare Add/Drop: ...NNN | ||||
|     "spare-add-drop": "10.0.254.228", | ||||
| } | ||||
|  | ||||
| import json | ||||
| s = json.dumps(J, indent=2) | ||||
| for (old, new) in translate.items(): | ||||
|     s = s.replace(f'"{old}"', f'"netconf:{new}:830"') | ||||
| print(s) | ||||
							
								
								
									
										1033
									
								
								examples/demo.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1033
									
								
								examples/demo.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -21,7 +21,7 @@ from json import dumps, loads | ||||
| from numpy import mean | ||||
| from gnpy.core.service_sheet import convert_service_sheet, Request_element, Element | ||||
| from gnpy.core.utils import load_json | ||||
| from gnpy.core.network import load_network, build_network, save_network | ||||
| from gnpy.core.network import load_network, build_network, save_network, network_from_json | ||||
| from gnpy.core.equipment import load_equipment, trx_mode_params, automatic_nch | ||||
| from gnpy.core.elements import Transceiver, Roadm | ||||
| from gnpy.core.utils import db2lin, lin2db | ||||
| @@ -38,6 +38,9 @@ from copy import copy, deepcopy | ||||
| from textwrap import dedent | ||||
| from math import ceil | ||||
|  | ||||
| from flask import Flask, jsonify, make_response, request | ||||
| from flask_restful import Api, Resource, reqparse, fields | ||||
|  | ||||
| #EQPT_LIBRARY_FILENAME = Path(__file__).parent / 'eqpt_config.json' | ||||
|  | ||||
| LOGGER = getLogger(__name__) | ||||
| @@ -58,7 +61,12 @@ PARSER.add_argument('-bi', '--bidir', action='store_true',\ | ||||
| PARSER.add_argument('-v', '--verbose', action='count', default=0,\ | ||||
|                     help='increases verbosity for each occurence') | ||||
| PARSER.add_argument('-o', '--output', type=Path) | ||||
| PARSER.add_argument('-r', '--rest', action='count', default=0, help='use the REST API') | ||||
|  | ||||
| NETWORK_FILENAME = 'topoDemov1.json' #'disagregatedTopoDemov1.json' # | ||||
|  | ||||
| APP = Flask(__name__, static_url_path="") | ||||
| API = Api(APP) | ||||
|  | ||||
| def requests_from_json(json_data, equipment): | ||||
|     """ converts the json data into a list of requests elements | ||||
| @@ -360,32 +368,9 @@ def path_result_json(pathresult): | ||||
|     } | ||||
|     return data | ||||
|  | ||||
| def main(args): | ||||
|     """ main function that calls all functions | ||||
| def compute_requests(network, data, equipment): | ||||
|     """ Main program calling functions | ||||
|     """ | ||||
|     LOGGER.info(f'Computing path requests {args.service_filename} into JSON format') | ||||
|     print('\x1b[1;34;40m' +\ | ||||
|           f'Computing path requests {args.service_filename} into JSON format'+ '\x1b[0m') | ||||
|     # for debug | ||||
|     # print( args.eqpt_filename) | ||||
|  | ||||
|     try: | ||||
|         data = load_requests(args.service_filename, args.eqpt_filename, args.bidir) | ||||
|         equipment = load_equipment(args.eqpt_filename) | ||||
|         network = load_network(args.network_filename, equipment) | ||||
|     except EquipmentConfigError as this_e: | ||||
|         print(f'{ansi_escapes.red}Configuration error in the equipment library:{ansi_escapes.reset} {this_e}') | ||||
|         exit(1) | ||||
|     except NetworkTopologyError as this_e: | ||||
|         print(f'{ansi_escapes.red}Invalid network definition:{ansi_escapes.reset} {this_e}') | ||||
|         exit(1) | ||||
|     except ConfigurationError as this_e: | ||||
|         print(f'{ansi_escapes.red}Configuration error:{ansi_escapes.reset} {this_e}') | ||||
|         exit(1) | ||||
|     except ServiceError as this_e: | ||||
|         print(f'{ansi_escapes.red}Service error:{ansi_escapes.reset} {this_e}') | ||||
|         exit(1) | ||||
|  | ||||
|     # Build the network once using the default power defined in SI in eqpt config | ||||
|     # TODO power density: db2linp(ower_dbm": 0)/power_dbm": 0 * nb channels as defined by | ||||
|     # spacing, f_min and f_max | ||||
| @@ -394,7 +379,7 @@ def main(args): | ||||
|     p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,\ | ||||
|         equipment['SI']['default'].f_max, equipment['SI']['default'].spacing)) | ||||
|     build_network(network, equipment, p_db, p_total_db) | ||||
|     save_network(args.network_filename, network) | ||||
|     save_network(ARGS.network_filename, network) | ||||
|  | ||||
|     oms_list = build_oms_list(network, equipment) | ||||
|  | ||||
| @@ -402,7 +387,7 @@ def main(args): | ||||
|         rqs = requests_from_json(data, equipment) | ||||
|     except ServiceError as this_e: | ||||
|         print(f'{ansi_escapes.red}Service error:{ansi_escapes.reset} {this_e}') | ||||
|         exit(1) | ||||
|         raise this_e | ||||
|     # check that request ids are unique. Non unique ids, may | ||||
|     # mess the computation: better to stop the computation | ||||
|     all_ids = [r.request_id for r in rqs] | ||||
| @@ -411,12 +396,13 @@ def main(args): | ||||
|             all_ids.remove(item) | ||||
|         msg = f'Requests id {all_ids} are not unique' | ||||
|         LOGGER.critical(msg) | ||||
|         exit() | ||||
|         raise ServiceError(msg) | ||||
|     try: | ||||
|         rqs = correct_route_list(network, rqs) | ||||
|     except ServiceError as this_e: | ||||
|         print(f'{ansi_escapes.red}Service error:{ansi_escapes.reset} {this_e}') | ||||
|         exit(1) | ||||
|         raise this_e | ||||
|         #exit(1) | ||||
|     # pths = compute_path(network, equipment, rqs) | ||||
|     dsjn = disjunctions_from_json(data) | ||||
|  | ||||
| @@ -440,7 +426,7 @@ def main(args): | ||||
|         pths = compute_path_dsjctn(network, equipment, rqs, dsjn) | ||||
|     except DisjunctionError as this_e: | ||||
|         print(f'{ansi_escapes.red}Disjunction error:{ansi_escapes.reset} {this_e}') | ||||
|         exit(1) | ||||
|         raise this_e | ||||
|  | ||||
|     print('\x1b[1;34;40m' + f'Propagating on selected path' + '\x1b[0m') | ||||
|     propagatedpths, reversed_pths, reversed_propagatedpths = \ | ||||
| @@ -493,20 +479,89 @@ def main(args): | ||||
|     print('\x1b[1;33;40m'+f'Result summary shows mean SNR and OSNR (average over all channels)' +\ | ||||
|           '\x1b[0m') | ||||
|  | ||||
|     if args.output: | ||||
|     return propagatedpths, reversed_propagatedpths, rqs | ||||
|  | ||||
|  | ||||
| def launch_cli(network, data, equipment): | ||||
|     """ Compute requests using network, data and equipment with client line interface | ||||
|     """ | ||||
|     propagatedpths, reversed_propagatedpths, rqs = compute_requests(network, data, equipment) | ||||
|     #Generate the output | ||||
|     if ARGS.output : | ||||
|         result = [] | ||||
|         # assumes that list of rqs and list of propgatedpths have same order | ||||
|         for i, pth in enumerate(propagatedpths): | ||||
|             result.append(Result_element(rqs[i], pth, reversed_propagatedpths[i])) | ||||
|         temp = path_result_json(result) | ||||
|         fnamecsv = f'{str(args.output)[0:len(str(args.output))-len(str(args.output.suffix))]}.csv' | ||||
|         fnamejson = f'{str(args.output)[0:len(str(args.output))-len(str(args.output.suffix))]}.json' | ||||
|         fnamecsv = f'{str(ARGS.output)[0:len(str(ARGS.output))-len(str(ARGS.output.suffix))]}.csv' | ||||
|         fnamejson = f'{str(ARGS.output)[0:len(str(ARGS.output))-len(str(ARGS.output.suffix))]}.json' | ||||
|         with open(fnamejson, 'w', encoding='utf-8') as fjson: | ||||
|             fjson.write(dumps(path_result_json(result), indent=2, ensure_ascii=False)) | ||||
|             with open(fnamecsv, "w", encoding='utf-8') as fcsv: | ||||
|                 jsontocsv(temp, equipment, fcsv) | ||||
|                 print('\x1b[1;34;40m'+f'saving in {args.output} and {fnamecsv}'+ '\x1b[0m') | ||||
|                 print('\x1b[1;34;40m'+f'saving in {ARGS.output} and {fnamecsv}'+ '\x1b[0m') | ||||
|  | ||||
| class GnpyAPI(Resource): | ||||
|     """ Compute requests using network, data and equipment with rest api | ||||
|     """ | ||||
|     def get(self): | ||||
|         return {"ping": True}, 200 | ||||
|  | ||||
|     def post(self): | ||||
|         data = request.get_json() | ||||
|         equipment = load_equipment('examples/2019-demo-equipment.json') | ||||
|         topo_json = load_json('examples/2019-demo-topology.json') | ||||
|         network = network_from_json(topo_json, equipment) | ||||
|         try: | ||||
|             propagatedpths, reversed_propagatedpths, rqs = compute_requests(network, data, equipment) | ||||
|             # Generate the output | ||||
|             result = [] | ||||
|             #assumes that list of rqs and list of propgatedpths have same order | ||||
|             for i, pth in enumerate(propagatedpths): | ||||
|                 result.append(Result_element(rqs[i], pth, reversed_propagatedpths[i])) | ||||
|  | ||||
|             return {"result":path_result_json(result)}, 201 | ||||
|         except ServiceError as this_e: | ||||
|             msg = f'Service error: {this_e}' | ||||
|             return {"result": msg}, 400 | ||||
|  | ||||
| API.add_resource(GnpyAPI, '/gnpy-experimental') | ||||
|  | ||||
| def main(args): | ||||
|     """ main function that calls all functions | ||||
|     """ | ||||
|     LOGGER.info(f'Computing path requests {args.service_filename} into JSON format') | ||||
|     print('\x1b[1;34;40m' +\ | ||||
|           f'Computing path requests {args.service_filename} into JSON format'+ '\x1b[0m') | ||||
|     # for debug | ||||
|     # print( args.eqpt_filename) | ||||
|  | ||||
|     try: | ||||
|         data = load_requests(args.service_filename, args.eqpt_filename, args.bidir) | ||||
|         equipment = load_equipment(args.eqpt_filename) | ||||
|         network = load_network(args.network_filename, equipment) | ||||
|     except EquipmentConfigError as this_e: | ||||
|         print(f'{ansi_escapes.red}Configuration error in the equipment library:{ansi_escapes.reset} {this_e}') | ||||
|         exit(1) | ||||
|     except NetworkTopologyError as this_e: | ||||
|         print(f'{ansi_escapes.red}Invalid network definition:{ansi_escapes.reset} {this_e}') | ||||
|         exit(1) | ||||
|     except ConfigurationError as this_e: | ||||
|         print(f'{ansi_escapes.red}Configuration error:{ansi_escapes.reset} {this_e}') | ||||
|         exit(1) | ||||
|     except ServiceError as this_e: | ||||
|         print(f'{ansi_escapes.red}Service error:{ansi_escapes.reset} {this_e}') | ||||
|         exit(1) | ||||
|     # input_str = raw_input("How will you use your program: c:[cli] , a:[api] ?") | ||||
|     # print(input_str) | ||||
|     # | ||||
|     if ((args.rest == 1) and (args.output is None)): | ||||
|         print('you have chosen the rest mode') | ||||
|         APP.run(host='0.0.0.0', port=5000, debug=True) | ||||
|     elif ((args.rest > 1) or ((args.rest == 1) and (args.output is not None))): | ||||
|         print('command is not well formulated') | ||||
|     else: | ||||
|         launch_cli(network, data, equipment) | ||||
|  | ||||
| if __name__ == '__main__': | ||||
|     ARGS = PARSER.parse_args() | ||||
|   | ||||
							
								
								
									
										180
									
								
								examples/serviceDemov1.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										180
									
								
								examples/serviceDemov1.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,180 @@ | ||||
| { | ||||
|   "path-request": [ | ||||
|     { | ||||
|       "request-id": "0", | ||||
|       "source": "trx site_a", | ||||
|       "destination": "trx site_b", | ||||
|       "src-tp-id": "trx site_a", | ||||
|       "dst-tp-id": "trx site_b", | ||||
|       "bidirectional": false, | ||||
|       "path-constraints": { | ||||
|         "te-bandwidth": { | ||||
|           "technology": "flexi-grid", | ||||
|           "trx_type": "Voyager", | ||||
|           "trx_mode": null, | ||||
|           "effective-freq-slot": [ | ||||
|             { | ||||
|               "N": "null", | ||||
|               "M": "null" | ||||
|             } | ||||
|           ], | ||||
|           "spacing": 50000000000.0, | ||||
|           "max-nb-of-channel": null, | ||||
|           "output-power": null, | ||||
|           "path_bandwidth": 100000000000.0 | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "1", | ||||
|       "source": "trx site_a", | ||||
|       "destination": "trx site_b", | ||||
|       "src-tp-id": "trx site_a", | ||||
|       "dst-tp-id": "trx site_b", | ||||
|       "bidirectional": false, | ||||
|       "path-constraints": { | ||||
|         "te-bandwidth": { | ||||
|           "technology": "flexi-grid", | ||||
|           "trx_type": "Voyager", | ||||
|           "trx_mode": "mode 1", | ||||
|           "effective-freq-slot": [ | ||||
|             { | ||||
|               "N": "null", | ||||
|               "M": "null" | ||||
|             } | ||||
|           ], | ||||
|           "spacing": 50000000000.0, | ||||
|           "max-nb-of-channel": null, | ||||
|           "output-power": null, | ||||
|           "path_bandwidth": 200000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "explicit-route-objects": { | ||||
|         "route-object-include-exclude": [ | ||||
|           { | ||||
|             "explicit-route-usage": "route-include-ero", | ||||
|             "index": 0, | ||||
|             "num-unnum-hop": { | ||||
|               "node-id": "Span1ab", | ||||
|               "link-tp-id": "link-tp-id is not used", | ||||
|               "hop-type": "STRICT" | ||||
|             } | ||||
|           } | ||||
|         ] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "2", | ||||
|       "source": "trx site_a", | ||||
|       "destination": "trx site_b", | ||||
|       "src-tp-id": "trx site_a", | ||||
|       "dst-tp-id": "trx site_b", | ||||
|       "bidirectional": false, | ||||
|       "path-constraints": { | ||||
|         "te-bandwidth": { | ||||
|           "technology": "flexi-grid", | ||||
|           "trx_type": "Voyager", | ||||
|           "trx_mode": "mode 1", | ||||
|           "effective-freq-slot": [ | ||||
|             { | ||||
|               "N": "null", | ||||
|               "M": "null" | ||||
|             } | ||||
|           ], | ||||
|           "spacing": 50000000000.0, | ||||
|           "max-nb-of-channel": null, | ||||
|           "output-power": null, | ||||
|           "path_bandwidth": 200000000000.0 | ||||
|         } | ||||
|       }, | ||||
|       "explicit-route-objects": { | ||||
|         "route-object-include-exclude": [ | ||||
|           { | ||||
|             "explicit-route-usage": "route-include-ero", | ||||
|             "index": 0, | ||||
|             "num-unnum-hop": { | ||||
|               "node-id": "roadm site_c", | ||||
|               "link-tp-id": "link-tp-id is not used", | ||||
|               "hop-type": "STRICT" | ||||
|             } | ||||
|           } | ||||
|         ] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "3", | ||||
|       "source": "trx site_a", | ||||
|       "destination": "trx site_b", | ||||
|       "src-tp-id": "trx site_a", | ||||
|       "dst-tp-id": "trx site_b", | ||||
|       "bidirectional": false, | ||||
|       "path-constraints": { | ||||
|         "te-bandwidth": { | ||||
|           "technology": "flexi-grid", | ||||
|           "trx_type": "Voyager", | ||||
|           "trx_mode": null, | ||||
|           "effective-freq-slot": [ | ||||
|             { | ||||
|               "N": "null", | ||||
|               "M": "null" | ||||
|             } | ||||
|           ], | ||||
|           "spacing": 50000000000.0, | ||||
|           "max-nb-of-channel": null, | ||||
|           "output-power": null, | ||||
|           "path_bandwidth": 100000000000.0 | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "request-id": "4", | ||||
|       "source": "trx site_a", | ||||
|       "destination": "trx site_b", | ||||
|       "src-tp-id": "trx site_a", | ||||
|       "dst-tp-id": "trx site_b", | ||||
|       "bidirectional": false, | ||||
|       "path-constraints": { | ||||
|         "te-bandwidth": { | ||||
|           "technology": "flexi-grid", | ||||
|           "trx_type": "Voyager", | ||||
|           "trx_mode": null, | ||||
|           "effective-freq-slot": [ | ||||
|             { | ||||
|               "N": "null", | ||||
|               "M": "null" | ||||
|             } | ||||
|           ], | ||||
|           "spacing": 50000000000.0, | ||||
|           "max-nb-of-channel": null, | ||||
|           "output-power": null, | ||||
|           "path_bandwidth": 100000000000.0 | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   ], | ||||
|   "synchronization": [ | ||||
|     { | ||||
|       "synchronization-id": "x", | ||||
|       "svec": { | ||||
|         "relaxable": "false", | ||||
|         "disjointness": "node link", | ||||
|         "request-id-number": [ | ||||
|           "3", | ||||
|           "0" | ||||
|         ] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "synchronization-id": "y", | ||||
|       "svec": { | ||||
|         "relaxable": "false", | ||||
|         "disjointness": "node link", | ||||
|         "request-id-number": [ | ||||
|           "4", | ||||
|           "3", | ||||
|           "0" | ||||
|         ] | ||||
|       } | ||||
|     } | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										703
									
								
								examples/topoDemov1.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										703
									
								
								examples/topoDemov1.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,703 @@ | ||||
| { | ||||
|   "elements": [ | ||||
|     { | ||||
|       "uid": "trx site_a", | ||||
|       "type": "Transceiver", | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 0, | ||||
|           "longitude": 0, | ||||
|           "city": "Site a", | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "roadm site_a", | ||||
|       "type": "Roadm", | ||||
|       "params": { | ||||
|         "target_pch_out_db": -20, | ||||
|         "restrictions": { | ||||
|           "preamp_variety_list": [], | ||||
|           "booster_variety_list": [] | ||||
|         } | ||||
|       }, | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 0, | ||||
|           "longitude": 0, | ||||
|           "city": "Site a", | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "Span1ab", | ||||
|       "type": "Fiber", | ||||
|       "type_variety": "SSMF", | ||||
|       "params": { | ||||
|         "type_variety": "SSMF", | ||||
|         "length": 100.0, | ||||
|         "loss_coef": 0.2, | ||||
|         "length_units": "km", | ||||
|         "att_in": 0, | ||||
|         "con_in": 0.5, | ||||
|         "con_out": 0.5 | ||||
|       }, | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 1, | ||||
|           "longitude": 0, | ||||
|           "city": null, | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "Span1ba", | ||||
|       "type": "Fiber", | ||||
|       "type_variety": "SSMF", | ||||
|       "params": { | ||||
|         "type_variety": "SSMF", | ||||
|         "length": 100.0, | ||||
|         "loss_coef": 0.2, | ||||
|         "length_units": "km", | ||||
|         "att_in": 0, | ||||
|         "con_in": 0.5, | ||||
|         "con_out": 0.5 | ||||
|       }, | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 1, | ||||
|           "longitude": 0, | ||||
|           "city": null, | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "Span2ab", | ||||
|       "type": "Fiber", | ||||
|       "type_variety": "SSMF", | ||||
|       "params": { | ||||
|         "type_variety": "SSMF", | ||||
|         "length": 80.0, | ||||
|         "loss_coef": 0.2, | ||||
|         "length_units": "km", | ||||
|         "att_in": 0, | ||||
|         "con_in": 0.5, | ||||
|         "con_out": 0.5 | ||||
|       }, | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 1, | ||||
|           "longitude": 0, | ||||
|           "city": null, | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "Span2ba", | ||||
|       "type": "Fiber", | ||||
|       "type_variety": "SSMF", | ||||
|       "params": { | ||||
|         "type_variety": "SSMF", | ||||
|         "length": 80.0, | ||||
|         "loss_coef": 0.2, | ||||
|         "length_units": "km", | ||||
|         "att_in": 0, | ||||
|         "con_in": 0.5, | ||||
|         "con_out": 0.5 | ||||
|       }, | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 1, | ||||
|           "longitude": 0, | ||||
|           "city": null, | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "roadm site_b", | ||||
|       "type": "Roadm", | ||||
|       "params": { | ||||
|         "target_pch_out_db": -20, | ||||
|         "restrictions": { | ||||
|           "preamp_variety_list": [], | ||||
|           "booster_variety_list": [] | ||||
|         } | ||||
|       }, | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 0, | ||||
|           "longitude": 0, | ||||
|           "city": "Site b", | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "trx site_b", | ||||
|       "type": "Transceiver", | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 2, | ||||
|           "longitude": 0, | ||||
|           "city": "Site b", | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "booster1 site_a", | ||||
|       "type": "Edfa", | ||||
|       "type_variety": "std_medium_gain", | ||||
|       "operational": { | ||||
|         "gain_target": 19.0, | ||||
|         "delta_p": -1.0, | ||||
|         "tilt_target": 0, | ||||
|         "out_voa": 0 | ||||
|       }, | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 0.5, | ||||
|           "longitude": 0.0, | ||||
|           "city": "Site a", | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "preamp site_b", | ||||
|       "type": "Edfa", | ||||
|       "type_variety": "std_low_gain", | ||||
|       "operational": { | ||||
|         "gain_target": 18.0, | ||||
|         "delta_p": 0, | ||||
|         "tilt_target": 0, | ||||
|         "out_voa": 0 | ||||
|       }, | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 0.5, | ||||
|           "longitude": 0.0, | ||||
|           "city": "Site b", | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "booster1 site_b", | ||||
|       "type": "Edfa", | ||||
|       "type_variety": "std_medium_gain", | ||||
|       "operational": { | ||||
|         "gain_target": 19.0, | ||||
|         "delta_p": -1.0, | ||||
|         "tilt_target": 0, | ||||
|         "out_voa": 0 | ||||
|       }, | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 0.5, | ||||
|           "longitude": 0.0, | ||||
|           "city": "Site b", | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "preamp1 site_a", | ||||
|       "type": "Edfa", | ||||
|       "type_variety": "std_low_gain", | ||||
|       "operational": { | ||||
|         "gain_target": 18.0, | ||||
|         "delta_p": 0, | ||||
|         "tilt_target": 0, | ||||
|         "out_voa": 0 | ||||
|       }, | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 0.5, | ||||
|           "longitude": 0.0, | ||||
|           "city": "Site_a", | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "booster2 site_a", | ||||
|       "type": "Edfa", | ||||
|       "type_variety": "std_medium_gain", | ||||
|       "operational": { | ||||
|         "gain_target": 19.0, | ||||
|         "delta_p": -1.0, | ||||
|         "tilt_target": 0, | ||||
|         "out_voa": 0 | ||||
|       }, | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 0.5, | ||||
|           "longitude": 0.0, | ||||
|           "city": "Site a", | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "preamp2 site_b", | ||||
|       "type": "Edfa", | ||||
|       "type_variety": "std_low_gain", | ||||
|       "operational": { | ||||
|         "gain_target": 18.0, | ||||
|         "delta_p": 0, | ||||
|         "tilt_target": 0, | ||||
|         "out_voa": 0 | ||||
|       }, | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 0.5, | ||||
|           "longitude": 0.0, | ||||
|           "city": "Site_b", | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "booster2 site_b", | ||||
|       "type": "Edfa", | ||||
|       "type_variety": "std_medium_gain", | ||||
|       "operational": { | ||||
|         "gain_target": 19.0, | ||||
|         "delta_p": -1.0, | ||||
|         "tilt_target": 0, | ||||
|         "out_voa": 0 | ||||
|       }, | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 0.5, | ||||
|           "longitude": 0.0, | ||||
|           "city": "Site b", | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "preamp2 site_a", | ||||
|       "type": "Edfa", | ||||
|       "type_variety": "std_low_gain", | ||||
|       "operational": { | ||||
|         "gain_target": 18.0, | ||||
|         "delta_p": 0, | ||||
|         "tilt_target": 0, | ||||
|         "out_voa": 0 | ||||
|       }, | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 0.5, | ||||
|           "longitude": 0.0, | ||||
|           "city": "Site_a", | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "booster3 site_a", | ||||
|       "type": "Edfa", | ||||
|       "type_variety": "std_medium_gain", | ||||
|       "operational": { | ||||
|         "gain_target": 19.0, | ||||
|         "delta_p": -1.0, | ||||
|         "tilt_target": 0, | ||||
|         "out_voa": 0 | ||||
|       }, | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 0.5, | ||||
|           "longitude": 0.0, | ||||
|           "city": "Site a", | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "preamp3 site_b", | ||||
|       "type": "Edfa", | ||||
|       "type_variety": "std_low_gain", | ||||
|       "operational": { | ||||
|         "gain_target": 18.0, | ||||
|         "delta_p": 0, | ||||
|         "tilt_target": 0, | ||||
|         "out_voa": 0 | ||||
|       }, | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 0.5, | ||||
|           "longitude": 0.0, | ||||
|           "city": "Site_b", | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "booster3 site_b", | ||||
|       "type": "Edfa", | ||||
|       "type_variety": "std_medium_gain", | ||||
|       "operational": { | ||||
|         "gain_target": 19.0, | ||||
|         "delta_p": -1.0, | ||||
|         "tilt_target": 0, | ||||
|         "out_voa": 0 | ||||
|       }, | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 0.5, | ||||
|           "longitude": 0.0, | ||||
|           "city": "Site b", | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "preamp3 site_a", | ||||
|       "type": "Edfa", | ||||
|       "type_variety": "std_low_gain", | ||||
|       "operational": { | ||||
|         "gain_target": 18.0, | ||||
|         "delta_p": 0, | ||||
|         "tilt_target": 0, | ||||
|         "out_voa": 0 | ||||
|       }, | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 0.5, | ||||
|           "longitude": 0.0, | ||||
|           "city": "Site_a", | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "roadm site_c", | ||||
|       "type": "Roadm", | ||||
|       "params": { | ||||
|         "target_pch_out_db": -20, | ||||
|         "restrictions": { | ||||
|           "preamp_variety_list": [], | ||||
|           "booster_variety_list": [] | ||||
|         } | ||||
|       }, | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 0, | ||||
|           "longitude": 0, | ||||
|           "city": "Site c", | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "booster1 site_c", | ||||
|       "type": "Edfa", | ||||
|       "type_variety": "std_medium_gain", | ||||
|       "operational": { | ||||
|         "gain_target": 19.0, | ||||
|         "delta_p": -1.0, | ||||
|         "tilt_target": 0, | ||||
|         "out_voa": 0 | ||||
|       }, | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 0.5, | ||||
|           "longitude": 0.0, | ||||
|           "city": "Site c", | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "preamp1 site_c", | ||||
|       "type": "Edfa", | ||||
|       "type_variety": "std_low_gain", | ||||
|       "operational": { | ||||
|         "gain_target": 18.0, | ||||
|         "delta_p": 0, | ||||
|         "tilt_target": 0, | ||||
|         "out_voa": 0 | ||||
|       }, | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 0.5, | ||||
|           "longitude": 0.0, | ||||
|           "city": "Site_c", | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "booster2 site_c", | ||||
|       "type": "Edfa", | ||||
|       "type_variety": "std_medium_gain", | ||||
|       "operational": { | ||||
|         "gain_target": 19.0, | ||||
|         "delta_p": -1.0, | ||||
|         "tilt_target": 0, | ||||
|         "out_voa": 0 | ||||
|       }, | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 0.5, | ||||
|           "longitude": 0.0, | ||||
|           "city": "Site c", | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "preamp2 site_c", | ||||
|       "type": "Edfa", | ||||
|       "type_variety": "std_low_gain", | ||||
|       "operational": { | ||||
|         "gain_target": 18.0, | ||||
|         "delta_p": 0, | ||||
|         "tilt_target": 0, | ||||
|         "out_voa": 0 | ||||
|       }, | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 0.5, | ||||
|           "longitude": 0.0, | ||||
|           "city": "Site_c", | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "Span1ac", | ||||
|       "type": "Fiber", | ||||
|       "type_variety": "SSMF", | ||||
|       "params": { | ||||
|         "type_variety": "SSMF", | ||||
|         "length": 80.0, | ||||
|         "loss_coef": 0.2, | ||||
|         "length_units": "km", | ||||
|         "att_in": 0, | ||||
|         "con_in": 0.5, | ||||
|         "con_out": 0.5 | ||||
|       }, | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 1, | ||||
|           "longitude": 0, | ||||
|           "city": null, | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "Span1ca", | ||||
|       "type": "Fiber", | ||||
|       "type_variety": "SSMF", | ||||
|       "params": { | ||||
|         "type_variety": "SSMF", | ||||
|         "length": 80.0, | ||||
|         "loss_coef": 0.2, | ||||
|         "length_units": "km", | ||||
|         "att_in": 0, | ||||
|         "con_in": 0.5, | ||||
|         "con_out": 0.5 | ||||
|       }, | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 1, | ||||
|           "longitude": 0, | ||||
|           "city": null, | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "Span1bc", | ||||
|       "type": "Fiber", | ||||
|       "type_variety": "SSMF", | ||||
|       "params": { | ||||
|         "type_variety": "SSMF", | ||||
|         "length": 80.0, | ||||
|         "loss_coef": 0.2, | ||||
|         "length_units": "km", | ||||
|         "att_in": 0, | ||||
|         "con_in": 0.5, | ||||
|         "con_out": 0.5 | ||||
|       }, | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 1, | ||||
|           "longitude": 0, | ||||
|           "city": null, | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "uid": "Span1cb", | ||||
|       "type": "Fiber", | ||||
|       "type_variety": "SSMF", | ||||
|       "params": { | ||||
|         "type_variety": "SSMF", | ||||
|         "length": 80.0, | ||||
|         "loss_coef": 0.2, | ||||
|         "length_units": "km", | ||||
|         "att_in": 0, | ||||
|         "con_in": 0.5, | ||||
|         "con_out": 0.5 | ||||
|       }, | ||||
|       "metadata": { | ||||
|         "location": { | ||||
|           "latitude": 1, | ||||
|           "longitude": 0, | ||||
|           "city": null, | ||||
|           "region": "" | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   ], | ||||
|   "connections": [ | ||||
|     { | ||||
|       "from_node": "trx site_a", | ||||
|       "to_node": "roadm site_a" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "roadm site_a", | ||||
|       "to_node": "booster1 site_a" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "booster1 site_a", | ||||
|       "to_node": "Span1ab" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "Span1ab", | ||||
|       "to_node": "preamp site_b" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "preamp site_b", | ||||
|       "to_node": "roadm site_b" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "roadm site_b", | ||||
|       "to_node": "trx site_b" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "roadm site_a", | ||||
|       "to_node": "booster2 site_a" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "booster2 site_a", | ||||
|       "to_node": "Span2ab" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "Span2ab", | ||||
|       "to_node": "preamp2 site_b" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "preamp2 site_b", | ||||
|       "to_node": "roadm site_b" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "roadm site_b", | ||||
|       "to_node": "booster1 site_b" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "booster1 site_b", | ||||
|       "to_node": "Span1ba" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "Span1ba", | ||||
|       "to_node": "preamp1 site_a" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "preamp1 site_a", | ||||
|       "to_node": "roadm site_a" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "roadm site_b", | ||||
|       "to_node": "booster2 site_b" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "booster2 site_b", | ||||
|       "to_node": "Span2ba" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "Span2ba", | ||||
|       "to_node": "preamp2 site_a" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "preamp2 site_a", | ||||
|       "to_node": "roadm site_a" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "roadm site_a", | ||||
|       "to_node": "booster3 site_a" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "booster3 site_a", | ||||
|       "to_node": "Span1ac" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "Span1ac", | ||||
|       "to_node": "preamp1 site_c" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "preamp1 site_c", | ||||
|       "to_node": "roadm site_c" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "roadm site_c", | ||||
|       "to_node": "booster1 site_c" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "booster1 site_c", | ||||
|       "to_node": "Span1cb" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "Span1cb", | ||||
|       "to_node": "preamp3 site_b" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "preamp3 site_b", | ||||
|       "to_node": "roadm site_b" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "roadm site_b", | ||||
|       "to_node": "booster3 site_b" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "booster3 site_b", | ||||
|       "to_node": "Span1bc" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "Span1bc", | ||||
|       "to_node": "preamp2 site_c" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "preamp2 site_c", | ||||
|       "to_node": "roadm site_c" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "roadm site_c", | ||||
|       "to_node": "booster2 site_c" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "booster2 site_c", | ||||
|       "to_node": "Span1ca" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "Span1ca", | ||||
|       "to_node": "preamp3 site_a" | ||||
|     }, | ||||
|     { | ||||
|       "from_node": "preamp3 site_a", | ||||
|       "to_node": "roadm site_a" | ||||
|     } | ||||
|   ] | ||||
| } | ||||
| @@ -118,16 +118,19 @@ class Transceiver(Node): | ||||
|         self._calc_snr(spectral_info) | ||||
|         return spectral_info | ||||
|  | ||||
| RoadmParams = namedtuple('RoadmParams', 'target_pch_out_db add_drop_osnr restrictions') | ||||
| RoadmParams = namedtuple('RoadmParams', 'target_pch_out_db add_drop_osnr restrictions per_degree_target_pch_out_db') | ||||
|  | ||||
| class Roadm(Node): | ||||
|     def __init__(self, *args, params, **kwargs): | ||||
|         if 'per_degree_target_pch_out_db' not in params.keys(): | ||||
|             params['per_degree_target_pch_out_db'] = [] | ||||
|         super().__init__(*args, params=RoadmParams(**params), **kwargs) | ||||
|         self.loss = 0 #auto-design interest | ||||
|         self.effective_loss = None | ||||
|         self.effective_pch_out_db = self.params.target_pch_out_db | ||||
|         self.passive = True | ||||
|         self.restrictions = self.params.restrictions | ||||
|         self.per_degree_target_pch_out_db = self.params.per_degree_target_pch_out_db | ||||
|  | ||||
|     @property | ||||
|     def to_json(self): | ||||
| @@ -135,7 +138,8 @@ class Roadm(Node): | ||||
|                 'type'      : type(self).__name__, | ||||
|                 'params'    : { | ||||
|                     'target_pch_out_db' : self.effective_pch_out_db, | ||||
|                     'restrictions'      : self.restrictions | ||||
|                     'restrictions'      : self.restrictions, | ||||
|                     'per_degree_target_pch_out_db': self.per_degree_target_pch_out_db | ||||
|                     }, | ||||
|                 'metadata'      : { | ||||
|                     'location': self.metadata['location']._asdict() | ||||
| @@ -150,15 +154,26 @@ class Roadm(Node): | ||||
|                           f'  effective loss (dB):  {self.effective_loss:.2f}', | ||||
|                           f'  pch out (dBm):        {self.effective_pch_out_db!r}']) | ||||
|  | ||||
|     def propagate(self, pref, *carriers): | ||||
|     def propagate(self, pref, *carriers, degree): | ||||
|         #pin_target and loss are read from eqpt_config.json['Roadm'] | ||||
|         #all ingress channels in xpress are set to this power level | ||||
|         #but add channels are not, so we define an effective loss | ||||
|         #in the case of add channels | ||||
|         self.effective_pch_out_db = min(pref.p_spani, self.params.target_pch_out_db) | ||||
|         if self.per_degree_target_pch_out_db: | ||||
|             # find the target power on this degree | ||||
|             try: | ||||
|                 temp = next(el['target_pch_out_db'] \ | ||||
|                     for el in self.per_degree_target_pch_out_db if el['to_node']==degree) | ||||
|             except StopIteration: | ||||
|                 # if no target power is defined on this degree use the global one | ||||
|                 temp = self.params.target_pch_out_db | ||||
|         else: | ||||
|             # if no per degree target power are defined, use the global one | ||||
|             temp = self.params.target_pch_out_db | ||||
|         self.effective_pch_out_db = min(pref.p_spani, temp) | ||||
|         self.effective_loss = pref.p_spani - self.effective_pch_out_db | ||||
|         carriers_power = array([c.power.signal +c.power.nli+c.power.ase for c in carriers]) | ||||
|         carriers_att = list(map(lambda x : lin2db(x*1e3)-self.params.target_pch_out_db, carriers_power)) | ||||
|         carriers_att = list(map(lambda x : lin2db(x*1e3)-self.effective_pch_out_db, carriers_power)) | ||||
|         exceeding_att = -min(list(filter(lambda x: x < 0, carriers_att)), default = 0) | ||||
|         carriers_att = list(map(lambda x: db2lin(x+exceeding_att), carriers_att)) | ||||
|         for carrier_att, carrier in zip(carriers_att, carriers) : | ||||
| @@ -171,8 +186,8 @@ class Roadm(Node): | ||||
|     def update_pref(self, pref): | ||||
|         return pref._replace(p_span0=pref.p_span0, p_spani=self.effective_pch_out_db) | ||||
|  | ||||
|     def __call__(self, spectral_info): | ||||
|         carriers = tuple(self.propagate(spectral_info.pref, *spectral_info.carriers)) | ||||
|     def __call__(self, spectral_info, degree): | ||||
|         carriers = tuple(self.propagate(spectral_info.pref, *spectral_info.carriers, degree=degree)) | ||||
|         pref = self.update_pref(spectral_info.pref) | ||||
|         return spectral_info._replace(carriers=carriers, pref=pref) | ||||
|  | ||||
|   | ||||
| @@ -233,7 +233,7 @@ def prev_node_generator(network, node): | ||||
|     except StopIteration: | ||||
|         raise NetworkTopologyError(f'Node {node.uid} is not properly connected, please check network topology') | ||||
|     # yield and re-iterate | ||||
|     if isinstance(prev_node, Fused) or isinstance(node, Fused): | ||||
|     if isinstance(prev_node, Fused) or isinstance(node, Fused) and not isinstance(prev_node, Roadm): | ||||
|         yield prev_node | ||||
|         yield from prev_node_generator(network, prev_node) | ||||
|     else: | ||||
| @@ -247,7 +247,7 @@ def next_node_generator(network, node): | ||||
|     except StopIteration: | ||||
|         raise NetworkTopologyError('Node {node.uid} is not properly connected, please check network topology') | ||||
|     # yield and re-iterate | ||||
|     if isinstance(next_node, Fused) or isinstance(node, Fused): | ||||
|     if isinstance(next_node, Fused) or isinstance(node, Fused) and not isinstance(next_node, Roadm): | ||||
|         yield next_node | ||||
|         yield from next_node_generator(network, next_node) | ||||
|     else: | ||||
| @@ -315,7 +315,18 @@ def set_egress_amplifier(network, roadm, equipment, pref_total_db): | ||||
|         #     node = find_last_node(next_node) | ||||
|         #     next_node = next(n for n in network.successors(node)) | ||||
|         #     next_node = find_last_node(next_node) | ||||
|         prev_dp = getattr(node.params, 'target_pch_out_db', 0) | ||||
|          | ||||
|         if node.per_degree_target_pch_out_db: | ||||
|             # find the target power on this degree | ||||
|             try: | ||||
|                 prev_dp = next(el["target_pch_out_db"] for el in \ | ||||
|                     node.per_degree_target_pch_out_db if el["to_node"]==next_node.uid) | ||||
|             except StopIteration: | ||||
|                 # if no target power is defined on this degree use the global one | ||||
|                 prev_dp = getattr(node.params, 'target_pch_out_db', 0) | ||||
|         else: | ||||
|             # if no per degree target power is given use the global one | ||||
|             prev_dp = getattr(node.params, 'target_pch_out_db', 0) | ||||
|         dp = prev_dp | ||||
|         prev_voa = 0 | ||||
|         voa = 0 | ||||
|   | ||||
| @@ -122,6 +122,15 @@ BLOCKING_NOPATH = ['NO_PATH', 'NO_PATH_WITH_CONSTRAINT',\ | ||||
| BLOCKING_NOMODE = ['NO_FEASIBLE_MODE', 'MODE_NOT_FEASIBLE'] | ||||
| BLOCKING_NOSPECTRUM = 'NO_SPECTRUM' | ||||
|  | ||||
| def element_to_node_type(element): | ||||
|     if isinstance(element, Transceiver): | ||||
|         return "transceiver" | ||||
|     if isinstance(element, Edfa): | ||||
|         return "EDFA" | ||||
|     if isinstance(element, Roadm): | ||||
|         return "ROADM" | ||||
|     return None | ||||
|  | ||||
| class Result_element(Element): | ||||
|     def __init__(self, path_request, computed_path, reversed_computed_path=None): | ||||
|         self.path_id = path_request.request_id | ||||
| @@ -131,13 +140,13 @@ class Result_element(Element): | ||||
|         if reversed_computed_path is not None: | ||||
|             self.reversed_computed_path = reversed_computed_path | ||||
|     uid = property(lambda self: repr(self)) | ||||
|     @property | ||||
|     def detailed_path_json(self): | ||||
|  | ||||
|     def detailed_path_json(self, path): | ||||
|         """ a function that builds path object for normal and blocking cases | ||||
|         """ | ||||
|         index = 0 | ||||
|         pro_list = [] | ||||
|         for element in self.computed_path: | ||||
|         for element in path: | ||||
|             temp = { | ||||
|                 'path-route-object': { | ||||
|                     'index': index, | ||||
| @@ -148,6 +157,9 @@ class Result_element(Element): | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             node_type = element_to_node_type(element) | ||||
|             if (node_type is not None): | ||||
|                 temp['path-route-object']['num-unnum-hop']['gnpy-node-type'] = node_type | ||||
|             pro_list.append(temp) | ||||
|             index += 1 | ||||
|             if self.path_request.M > 0: | ||||
| @@ -180,6 +192,31 @@ class Result_element(Element): | ||||
|                     } | ||||
|                 pro_list.append(temp) | ||||
|                 index += 1 | ||||
|             if isinstance(element, Roadm): | ||||
|                 temp = { | ||||
|                     'path-route-object': { | ||||
|                         'index': index, | ||||
|                         'target-channel-power' : { | ||||
|                            'value' : element.effective_pch_out_db, | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 pro_list.append(temp) | ||||
|                 index += 1 | ||||
|             if isinstance(element, Edfa): | ||||
|                 temp = { | ||||
|                     'path-route-object': { | ||||
|                         'index': index, | ||||
|                         'target-channel-power' : { | ||||
|                             'value': element.effective_pch_out_db, | ||||
|                         }, | ||||
|                         'output-voa':  { | ||||
|                             'value': element.out_voa, | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 pro_list.append(temp) | ||||
|                 index += 1 | ||||
|         return pro_list | ||||
|     @property | ||||
|     def path_properties(self): | ||||
| @@ -218,12 +255,13 @@ class Result_element(Element): | ||||
|             path_properties = { | ||||
|                 'path-metric': path_metric(self.computed_path, self.path_request), | ||||
|                 'z-a-path-metric': path_metric(self.reversed_computed_path, self.path_request), | ||||
|                 'path-route-objects': self.detailed_path_json | ||||
|                 'path-route-objects': self.detailed_path_json(self.computed_path), | ||||
|                 'reversed-path-route-objects': self.detailed_path_json(self.reversed_computed_path), | ||||
|                 } | ||||
|         else: | ||||
|             path_properties = { | ||||
|                 'path-metric': path_metric(self.computed_path, self.path_request), | ||||
|                 'path-route-objects': self.detailed_path_json | ||||
|                 'path-route-objects': self.detailed_path_json(self.computed_path) | ||||
|                 } | ||||
|         return path_properties | ||||
|  | ||||
| @@ -383,8 +421,13 @@ def propagate(path, req, equipment): | ||||
|     si = create_input_spectral_information( | ||||
|         req.f_min, req.f_max, req.roll_off, req.baud_rate, | ||||
|         req.power, req.spacing) | ||||
|     for el in path: | ||||
|         si = el(si) | ||||
|     for i, el in enumerate(path): | ||||
|         if isinstance(el, Roadm): | ||||
|             next_el = path[i+1] | ||||
|             si = el(si, degree=next_el.uid) | ||||
|         else: | ||||
|             si = el(si) | ||||
|         print(el) | ||||
|     path[-1].update_snr(req.tx_osnr, equipment['Roadm']['default'].add_drop_osnr) | ||||
|     return path | ||||
|  | ||||
| @@ -393,9 +436,13 @@ def propagate2(path, req, equipment): | ||||
|         req.f_min, req.f_max, req.roll_off, req.baud_rate, | ||||
|         req.power, req.spacing) | ||||
|     infos = {} | ||||
|     for el in path: | ||||
|     for i, el in enumerate(path): | ||||
|         before_si = si | ||||
|         after_si  = si = el(si) | ||||
|         if isinstance(el, Roadm): | ||||
|             next_el = path[i+1] | ||||
|             after_si  = si = el(si, degree=next_el.uid) | ||||
|         else: | ||||
|             after_si  = si = el(si) | ||||
|         infos[el] = before_si, after_si | ||||
|     path[-1].update_snr(req.tx_osnr, equipment['Roadm']['default'].add_drop_osnr) | ||||
|     return infos | ||||
| @@ -424,8 +471,12 @@ def propagate_and_optimize_mode(path, req, equipment): | ||||
|             spc_info = create_input_spectral_information(req.f_min, req.f_max, | ||||
|                                                    equipment['SI']['default'].roll_off, | ||||
|                                                    this_br, req.power, req.spacing) | ||||
|             for el in path: | ||||
|                 spc_info = el(spc_info) | ||||
|             for i, el in enumerate(path): | ||||
|                 if isinstance(el, Roadm): | ||||
|                     next_el = path[i+1] | ||||
|                     spc_info = el(spc_info, degree=next_el.uid) | ||||
|                 else: | ||||
|                     spc_info = el(spc_info) | ||||
|             for this_mode in modes_to_explore: | ||||
|                 if path[-1].snr is not None: | ||||
|                     path[-1].update_snr(this_mode['tx_osnr'], equipment['Roadm']['default'].add_drop_osnr) | ||||
|   | ||||
| @@ -59,6 +59,4 @@ | ||||
|           } | ||||
|         ] | ||||
|       } | ||||
|     } | ||||
|   ] | ||||
| } | ||||
|     },       | ||||
| @@ -1,5 +1,7 @@ | ||||
| alabaster>=0.7.12,<1 | ||||
| docutils==0.15.2 | ||||
| flask==1.0.2 | ||||
| flask-restful==0.3.7 | ||||
| matplotlib>=3.1.0,<4 | ||||
| networkx>=2.3,<3 | ||||
| numpy>=1.16.1,<2 | ||||
|   | ||||
| @@ -47,24 +47,25 @@ | ||||
|       "path-constraints": { | ||||
|         "te-bandwidth": { | ||||
|           "technology": "flexi-grid", | ||||
|           "trx_type": null, | ||||
|           "trx_mode": null, | ||||
|           "trx_type": "name of the tsp type_variety as listed in the library", | ||||
|           "trx_mode": "optional, name of the mode as listed in the tsp type_variety", | ||||
|           "effective-freq-slot": [ | ||||
|             { | ||||
|               "n": "null", | ||||
|               "m": "null" | ||||
|             } | ||||
|           ], | ||||
|           "spacing": null, | ||||
|           "max-nb-of-channel": null, | ||||
|           "output-power": null, | ||||
|           "path_bandwidth": null | ||||
|           } | ||||
|           "spacing": mandatory decimal Hz, | ||||
|           "max-nb-of-channel": optional integer, | ||||
|           "output-power": optional decimal W, | ||||
|           "path_bandwidth": optional bit/s | ||||
|         } | ||||
|       } | ||||
|     }], | ||||
|   "synchronization": [ | ||||
|     } | ||||
|   ], | ||||
|   "synchronization": [   list of disjunctions, optional | ||||
|     { | ||||
|       "synchronization-id": null, | ||||
|       "synchronization-id": "3", | ||||
|       "svec": { | ||||
|         "relaxable": "True", | ||||
|         "disjointness": "node link", | ||||
| @@ -72,5 +73,5 @@ | ||||
|          null, null ] | ||||
|         }, | ||||
|     } | ||||
|     ] | ||||
| } | ||||
|   ]   | ||||
| } | ||||
		Reference in New Issue
	
	Block a user