mirror of
				https://github.com/Telecominfraproject/oopt-gnpy.git
				synced 2025-11-04 03:57:47 +00:00 
			
		
		
		
	Compare commits
	
		
			32 Commits
		
	
	
		
			v2.3.1
			...
			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_NAME=telecominfraproject/oopt-gnpy
 | 
				
			||||||
IMAGE_TAG=$(git describe --tags)
 | 
					IMAGE_TAG=$(git describe --tags)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [[ "${TRAVIS_BRANCH}" == "experimental/2019-summit" ]]; then
 | 
				
			||||||
 | 
					  IMAGE_NAME=telecominfraproject/oopt-gnpy-experimental
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ALREADY_FOUND=0
 | 
					ALREADY_FOUND=0
 | 
				
			||||||
docker pull ${IMAGE_NAME}:${IMAGE_TAG} && ALREADY_FOUND=1
 | 
					docker pull ${IMAGE_NAME}:${IMAGE_TAG} && ALREADY_FOUND=1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if [[ $ALREADY_FOUND == 0 ]]; then
 | 
					if [[ $ALREADY_FOUND == 0 ]]; then
 | 
				
			||||||
  docker build . -t ${IMAGE_NAME}
 | 
					  docker build . -t ${IMAGE_NAME}
 | 
				
			||||||
  docker tag ${IMAGE_NAME} ${IMAGE_NAME}:${IMAGE_TAG}
 | 
					  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
 | 
					else
 | 
				
			||||||
  echo "Image ${IMAGE_NAME}:${IMAGE_TAG} already available, will just update the other tags"
 | 
					  echo "Image ${IMAGE_NAME}:${IMAGE_TAG} already available, will just update the other tags"
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
@@ -43,5 +42,11 @@ if [[ "${TRAVIS_PULL_REQUEST}" == "false" ]]; then
 | 
				
			|||||||
      docker push ${IMAGE_NAME}:${IMAGE_TAG}
 | 
					      docker push ${IMAGE_NAME}:${IMAGE_TAG}
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
    docker push ${IMAGE_NAME}:stable
 | 
					    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
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,7 @@ FROM python:3.7-slim
 | 
				
			|||||||
COPY . /oopt-gnpy
 | 
					COPY . /oopt-gnpy
 | 
				
			||||||
WORKDIR /oopt-gnpy
 | 
					WORKDIR /oopt-gnpy
 | 
				
			||||||
RUN python setup.py install
 | 
					RUN python setup.py install
 | 
				
			||||||
WORKDIR /shared/examples
 | 
					WORKDIR /shared
 | 
				
			||||||
ENTRYPOINT ["/oopt-gnpy/.docker-entry.sh"]
 | 
					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 numpy import mean
 | 
				
			||||||
from gnpy.core.service_sheet import convert_service_sheet, Request_element, Element
 | 
					from gnpy.core.service_sheet import convert_service_sheet, Request_element, Element
 | 
				
			||||||
from gnpy.core.utils import load_json
 | 
					from gnpy.core.utils import load_json
 | 
				
			||||||
from gnpy.core.network import load_network, build_network, 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.equipment import load_equipment, trx_mode_params, automatic_nch
 | 
				
			||||||
from gnpy.core.elements import Transceiver, Roadm
 | 
					from gnpy.core.elements import Transceiver, Roadm
 | 
				
			||||||
from gnpy.core.utils import db2lin, lin2db
 | 
					from gnpy.core.utils import db2lin, lin2db
 | 
				
			||||||
@@ -38,6 +38,9 @@ from copy import copy, deepcopy
 | 
				
			|||||||
from textwrap import dedent
 | 
					from textwrap import dedent
 | 
				
			||||||
from math import ceil
 | 
					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'
 | 
					#EQPT_LIBRARY_FILENAME = Path(__file__).parent / 'eqpt_config.json'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LOGGER = getLogger(__name__)
 | 
					LOGGER = getLogger(__name__)
 | 
				
			||||||
@@ -58,7 +61,12 @@ PARSER.add_argument('-bi', '--bidir', action='store_true',\
 | 
				
			|||||||
PARSER.add_argument('-v', '--verbose', action='count', default=0,\
 | 
					PARSER.add_argument('-v', '--verbose', action='count', default=0,\
 | 
				
			||||||
                    help='increases verbosity for each occurence')
 | 
					                    help='increases verbosity for each occurence')
 | 
				
			||||||
PARSER.add_argument('-o', '--output', type=Path)
 | 
					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):
 | 
					def requests_from_json(json_data, equipment):
 | 
				
			||||||
    """ converts the json data into a list of requests elements
 | 
					    """ converts the json data into a list of requests elements
 | 
				
			||||||
@@ -360,32 +368,9 @@ def path_result_json(pathresult):
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    return data
 | 
					    return data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def main(args):
 | 
					def compute_requests(network, data, equipment):
 | 
				
			||||||
    """ main function that calls all functions
 | 
					    """ 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
 | 
					    # 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
 | 
					    # TODO power density: db2linp(ower_dbm": 0)/power_dbm": 0 * nb channels as defined by
 | 
				
			||||||
    # spacing, f_min and f_max
 | 
					    # 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,\
 | 
					    p_total_db = p_db + lin2db(automatic_nch(equipment['SI']['default'].f_min,\
 | 
				
			||||||
        equipment['SI']['default'].f_max, equipment['SI']['default'].spacing))
 | 
					        equipment['SI']['default'].f_max, equipment['SI']['default'].spacing))
 | 
				
			||||||
    build_network(network, equipment, p_db, p_total_db)
 | 
					    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)
 | 
					    oms_list = build_oms_list(network, equipment)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -402,7 +387,7 @@ def main(args):
 | 
				
			|||||||
        rqs = requests_from_json(data, equipment)
 | 
					        rqs = requests_from_json(data, equipment)
 | 
				
			||||||
    except ServiceError as this_e:
 | 
					    except ServiceError as this_e:
 | 
				
			||||||
        print(f'{ansi_escapes.red}Service error:{ansi_escapes.reset} {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
 | 
					    # check that request ids are unique. Non unique ids, may
 | 
				
			||||||
    # mess the computation: better to stop the computation
 | 
					    # mess the computation: better to stop the computation
 | 
				
			||||||
    all_ids = [r.request_id for r in rqs]
 | 
					    all_ids = [r.request_id for r in rqs]
 | 
				
			||||||
@@ -411,12 +396,13 @@ def main(args):
 | 
				
			|||||||
            all_ids.remove(item)
 | 
					            all_ids.remove(item)
 | 
				
			||||||
        msg = f'Requests id {all_ids} are not unique'
 | 
					        msg = f'Requests id {all_ids} are not unique'
 | 
				
			||||||
        LOGGER.critical(msg)
 | 
					        LOGGER.critical(msg)
 | 
				
			||||||
        exit()
 | 
					        raise ServiceError(msg)
 | 
				
			||||||
    try:
 | 
					    try:
 | 
				
			||||||
        rqs = correct_route_list(network, rqs)
 | 
					        rqs = correct_route_list(network, rqs)
 | 
				
			||||||
    except ServiceError as this_e:
 | 
					    except ServiceError as this_e:
 | 
				
			||||||
        print(f'{ansi_escapes.red}Service error:{ansi_escapes.reset} {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)
 | 
					    # pths = compute_path(network, equipment, rqs)
 | 
				
			||||||
    dsjn = disjunctions_from_json(data)
 | 
					    dsjn = disjunctions_from_json(data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -440,7 +426,7 @@ def main(args):
 | 
				
			|||||||
        pths = compute_path_dsjctn(network, equipment, rqs, dsjn)
 | 
					        pths = compute_path_dsjctn(network, equipment, rqs, dsjn)
 | 
				
			||||||
    except DisjunctionError as this_e:
 | 
					    except DisjunctionError as this_e:
 | 
				
			||||||
        print(f'{ansi_escapes.red}Disjunction error:{ansi_escapes.reset} {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')
 | 
					    print('\x1b[1;34;40m' + f'Propagating on selected path' + '\x1b[0m')
 | 
				
			||||||
    propagatedpths, reversed_pths, reversed_propagatedpths = \
 | 
					    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)' +\
 | 
					    print('\x1b[1;33;40m'+f'Result summary shows mean SNR and OSNR (average over all channels)' +\
 | 
				
			||||||
          '\x1b[0m')
 | 
					          '\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 = []
 | 
					        result = []
 | 
				
			||||||
        # assumes that list of rqs and list of propgatedpths have same order
 | 
					        # assumes that list of rqs and list of propgatedpths have same order
 | 
				
			||||||
        for i, pth in enumerate(propagatedpths):
 | 
					        for i, pth in enumerate(propagatedpths):
 | 
				
			||||||
            result.append(Result_element(rqs[i], pth, reversed_propagatedpths[i]))
 | 
					            result.append(Result_element(rqs[i], pth, reversed_propagatedpths[i]))
 | 
				
			||||||
        temp = path_result_json(result)
 | 
					        temp = path_result_json(result)
 | 
				
			||||||
        fnamecsv = f'{str(args.output)[0:len(str(args.output))-len(str(args.output.suffix))]}.csv'
 | 
					        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'
 | 
					        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:
 | 
					        with open(fnamejson, 'w', encoding='utf-8') as fjson:
 | 
				
			||||||
            fjson.write(dumps(path_result_json(result), indent=2, ensure_ascii=False))
 | 
					            fjson.write(dumps(path_result_json(result), indent=2, ensure_ascii=False))
 | 
				
			||||||
            with open(fnamecsv, "w", encoding='utf-8') as fcsv:
 | 
					            with open(fnamecsv, "w", encoding='utf-8') as fcsv:
 | 
				
			||||||
                jsontocsv(temp, equipment, 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__':
 | 
					if __name__ == '__main__':
 | 
				
			||||||
    ARGS = PARSER.parse_args()
 | 
					    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)
 | 
					        self._calc_snr(spectral_info)
 | 
				
			||||||
        return 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):
 | 
					class Roadm(Node):
 | 
				
			||||||
    def __init__(self, *args, params, **kwargs):
 | 
					    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)
 | 
					        super().__init__(*args, params=RoadmParams(**params), **kwargs)
 | 
				
			||||||
        self.loss = 0 #auto-design interest
 | 
					        self.loss = 0 #auto-design interest
 | 
				
			||||||
        self.effective_loss = None
 | 
					        self.effective_loss = None
 | 
				
			||||||
        self.effective_pch_out_db = self.params.target_pch_out_db
 | 
					        self.effective_pch_out_db = self.params.target_pch_out_db
 | 
				
			||||||
        self.passive = True
 | 
					        self.passive = True
 | 
				
			||||||
        self.restrictions = self.params.restrictions
 | 
					        self.restrictions = self.params.restrictions
 | 
				
			||||||
 | 
					        self.per_degree_target_pch_out_db = self.params.per_degree_target_pch_out_db
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def to_json(self):
 | 
					    def to_json(self):
 | 
				
			||||||
@@ -135,7 +138,8 @@ class Roadm(Node):
 | 
				
			|||||||
                'type'      : type(self).__name__,
 | 
					                'type'      : type(self).__name__,
 | 
				
			||||||
                'params'    : {
 | 
					                'params'    : {
 | 
				
			||||||
                    'target_pch_out_db' : self.effective_pch_out_db,
 | 
					                    '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'      : {
 | 
					                'metadata'      : {
 | 
				
			||||||
                    'location': self.metadata['location']._asdict()
 | 
					                    'location': self.metadata['location']._asdict()
 | 
				
			||||||
@@ -150,15 +154,26 @@ class Roadm(Node):
 | 
				
			|||||||
                          f'  effective loss (dB):  {self.effective_loss:.2f}',
 | 
					                          f'  effective loss (dB):  {self.effective_loss:.2f}',
 | 
				
			||||||
                          f'  pch out (dBm):        {self.effective_pch_out_db!r}'])
 | 
					                          f'  pch out (dBm):        {self.effective_pch_out_db!r}'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def propagate(self, pref, *carriers):
 | 
					    def propagate(self, pref, *carriers, degree):
 | 
				
			||||||
        #pin_target and loss are read from eqpt_config.json['Roadm']
 | 
					        #pin_target and loss are read from eqpt_config.json['Roadm']
 | 
				
			||||||
        #all ingress channels in xpress are set to this power level
 | 
					        #all ingress channels in xpress are set to this power level
 | 
				
			||||||
        #but add channels are not, so we define an effective loss
 | 
					        #but add channels are not, so we define an effective loss
 | 
				
			||||||
        #in the case of add channels
 | 
					        #in the case of add channels
 | 
				
			||||||
        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
 | 
					        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_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)
 | 
					        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))
 | 
					        carriers_att = list(map(lambda x: db2lin(x+exceeding_att), carriers_att))
 | 
				
			||||||
        for carrier_att, carrier in zip(carriers_att, carriers) :
 | 
					        for carrier_att, carrier in zip(carriers_att, carriers) :
 | 
				
			||||||
@@ -171,8 +186,8 @@ class Roadm(Node):
 | 
				
			|||||||
    def update_pref(self, pref):
 | 
					    def update_pref(self, pref):
 | 
				
			||||||
        return pref._replace(p_span0=pref.p_span0, p_spani=self.effective_pch_out_db)
 | 
					        return pref._replace(p_span0=pref.p_span0, p_spani=self.effective_pch_out_db)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __call__(self, spectral_info):
 | 
					    def __call__(self, spectral_info, degree):
 | 
				
			||||||
        carriers = tuple(self.propagate(spectral_info.pref, *spectral_info.carriers))
 | 
					        carriers = tuple(self.propagate(spectral_info.pref, *spectral_info.carriers, degree=degree))
 | 
				
			||||||
        pref = self.update_pref(spectral_info.pref)
 | 
					        pref = self.update_pref(spectral_info.pref)
 | 
				
			||||||
        return spectral_info._replace(carriers=carriers, pref=pref)
 | 
					        return spectral_info._replace(carriers=carriers, pref=pref)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -233,7 +233,7 @@ def prev_node_generator(network, node):
 | 
				
			|||||||
    except StopIteration:
 | 
					    except StopIteration:
 | 
				
			||||||
        raise NetworkTopologyError(f'Node {node.uid} is not properly connected, please check network topology')
 | 
					        raise NetworkTopologyError(f'Node {node.uid} is not properly connected, please check network topology')
 | 
				
			||||||
    # yield and re-iterate
 | 
					    # 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 prev_node
 | 
				
			||||||
        yield from prev_node_generator(network, prev_node)
 | 
					        yield from prev_node_generator(network, prev_node)
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
@@ -247,7 +247,7 @@ def next_node_generator(network, node):
 | 
				
			|||||||
    except StopIteration:
 | 
					    except StopIteration:
 | 
				
			||||||
        raise NetworkTopologyError('Node {node.uid} is not properly connected, please check network topology')
 | 
					        raise NetworkTopologyError('Node {node.uid} is not properly connected, please check network topology')
 | 
				
			||||||
    # yield and re-iterate
 | 
					    # 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 next_node
 | 
				
			||||||
        yield from next_node_generator(network, next_node)
 | 
					        yield from next_node_generator(network, next_node)
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
@@ -315,7 +315,18 @@ def set_egress_amplifier(network, roadm, equipment, pref_total_db):
 | 
				
			|||||||
        #     node = find_last_node(next_node)
 | 
					        #     node = find_last_node(next_node)
 | 
				
			||||||
        #     next_node = next(n for n in network.successors(node))
 | 
					        #     next_node = next(n for n in network.successors(node))
 | 
				
			||||||
        #     next_node = find_last_node(next_node)
 | 
					        #     next_node = find_last_node(next_node)
 | 
				
			||||||
        prev_dp = 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
 | 
					        dp = prev_dp
 | 
				
			||||||
        prev_voa = 0
 | 
					        prev_voa = 0
 | 
				
			||||||
        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_NOMODE = ['NO_FEASIBLE_MODE', 'MODE_NOT_FEASIBLE']
 | 
				
			||||||
BLOCKING_NOSPECTRUM = 'NO_SPECTRUM'
 | 
					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):
 | 
					class Result_element(Element):
 | 
				
			||||||
    def __init__(self, path_request, computed_path, reversed_computed_path=None):
 | 
					    def __init__(self, path_request, computed_path, reversed_computed_path=None):
 | 
				
			||||||
        self.path_id = path_request.request_id
 | 
					        self.path_id = path_request.request_id
 | 
				
			||||||
@@ -131,13 +140,13 @@ class Result_element(Element):
 | 
				
			|||||||
        if reversed_computed_path is not None:
 | 
					        if reversed_computed_path is not None:
 | 
				
			||||||
            self.reversed_computed_path = reversed_computed_path
 | 
					            self.reversed_computed_path = reversed_computed_path
 | 
				
			||||||
    uid = property(lambda self: repr(self))
 | 
					    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
 | 
					        """ a function that builds path object for normal and blocking cases
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        index = 0
 | 
					        index = 0
 | 
				
			||||||
        pro_list = []
 | 
					        pro_list = []
 | 
				
			||||||
        for element in self.computed_path:
 | 
					        for element in path:
 | 
				
			||||||
            temp = {
 | 
					            temp = {
 | 
				
			||||||
                'path-route-object': {
 | 
					                'path-route-object': {
 | 
				
			||||||
                    'index': index,
 | 
					                    '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)
 | 
					            pro_list.append(temp)
 | 
				
			||||||
            index += 1
 | 
					            index += 1
 | 
				
			||||||
            if self.path_request.M > 0:
 | 
					            if self.path_request.M > 0:
 | 
				
			||||||
@@ -180,6 +192,31 @@ class Result_element(Element):
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
                pro_list.append(temp)
 | 
					                pro_list.append(temp)
 | 
				
			||||||
                index += 1
 | 
					                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
 | 
					        return pro_list
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def path_properties(self):
 | 
					    def path_properties(self):
 | 
				
			||||||
@@ -218,12 +255,13 @@ class Result_element(Element):
 | 
				
			|||||||
            path_properties = {
 | 
					            path_properties = {
 | 
				
			||||||
                'path-metric': path_metric(self.computed_path, self.path_request),
 | 
					                'path-metric': path_metric(self.computed_path, self.path_request),
 | 
				
			||||||
                'z-a-path-metric': path_metric(self.reversed_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:
 | 
					        else:
 | 
				
			||||||
            path_properties = {
 | 
					            path_properties = {
 | 
				
			||||||
                'path-metric': path_metric(self.computed_path, self.path_request),
 | 
					                '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
 | 
					        return path_properties
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -383,8 +421,13 @@ def propagate(path, req, equipment):
 | 
				
			|||||||
    si = create_input_spectral_information(
 | 
					    si = create_input_spectral_information(
 | 
				
			||||||
        req.f_min, req.f_max, req.roll_off, req.baud_rate,
 | 
					        req.f_min, req.f_max, req.roll_off, req.baud_rate,
 | 
				
			||||||
        req.power, req.spacing)
 | 
					        req.power, req.spacing)
 | 
				
			||||||
    for el in path:
 | 
					    for i, el in enumerate(path):
 | 
				
			||||||
        si = el(si)
 | 
					        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)
 | 
					    path[-1].update_snr(req.tx_osnr, equipment['Roadm']['default'].add_drop_osnr)
 | 
				
			||||||
    return path
 | 
					    return path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -393,9 +436,13 @@ def propagate2(path, req, equipment):
 | 
				
			|||||||
        req.f_min, req.f_max, req.roll_off, req.baud_rate,
 | 
					        req.f_min, req.f_max, req.roll_off, req.baud_rate,
 | 
				
			||||||
        req.power, req.spacing)
 | 
					        req.power, req.spacing)
 | 
				
			||||||
    infos = {}
 | 
					    infos = {}
 | 
				
			||||||
    for el in path:
 | 
					    for i, el in enumerate(path):
 | 
				
			||||||
        before_si = si
 | 
					        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
 | 
					        infos[el] = before_si, after_si
 | 
				
			||||||
    path[-1].update_snr(req.tx_osnr, equipment['Roadm']['default'].add_drop_osnr)
 | 
					    path[-1].update_snr(req.tx_osnr, equipment['Roadm']['default'].add_drop_osnr)
 | 
				
			||||||
    return infos
 | 
					    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,
 | 
					            spc_info = create_input_spectral_information(req.f_min, req.f_max,
 | 
				
			||||||
                                                   equipment['SI']['default'].roll_off,
 | 
					                                                   equipment['SI']['default'].roll_off,
 | 
				
			||||||
                                                   this_br, req.power, req.spacing)
 | 
					                                                   this_br, req.power, req.spacing)
 | 
				
			||||||
            for el in path:
 | 
					            for i, el in enumerate(path):
 | 
				
			||||||
                spc_info = el(spc_info)
 | 
					                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:
 | 
					            for this_mode in modes_to_explore:
 | 
				
			||||||
                if path[-1].snr is not None:
 | 
					                if path[-1].snr is not None:
 | 
				
			||||||
                    path[-1].update_snr(this_mode['tx_osnr'], equipment['Roadm']['default'].add_drop_osnr)
 | 
					                    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
 | 
					alabaster>=0.7.12,<1
 | 
				
			||||||
docutils==0.15.2
 | 
					docutils==0.15.2
 | 
				
			||||||
 | 
					flask==1.0.2
 | 
				
			||||||
 | 
					flask-restful==0.3.7
 | 
				
			||||||
matplotlib>=3.1.0,<4
 | 
					matplotlib>=3.1.0,<4
 | 
				
			||||||
networkx>=2.3,<3
 | 
					networkx>=2.3,<3
 | 
				
			||||||
numpy>=1.16.1,<2
 | 
					numpy>=1.16.1,<2
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -47,24 +47,25 @@
 | 
				
			|||||||
      "path-constraints": {
 | 
					      "path-constraints": {
 | 
				
			||||||
        "te-bandwidth": {
 | 
					        "te-bandwidth": {
 | 
				
			||||||
          "technology": "flexi-grid",
 | 
					          "technology": "flexi-grid",
 | 
				
			||||||
          "trx_type": null,
 | 
					          "trx_type": "name of the tsp type_variety as listed in the library",
 | 
				
			||||||
          "trx_mode": null,
 | 
					          "trx_mode": "optional, name of the mode as listed in the tsp type_variety",
 | 
				
			||||||
          "effective-freq-slot": [
 | 
					          "effective-freq-slot": [
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
              "n": "null",
 | 
					              "n": "null",
 | 
				
			||||||
              "m": "null"
 | 
					              "m": "null"
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          ],
 | 
					          ],
 | 
				
			||||||
          "spacing": null,
 | 
					          "spacing": mandatory decimal Hz,
 | 
				
			||||||
          "max-nb-of-channel": null,
 | 
					          "max-nb-of-channel": optional integer,
 | 
				
			||||||
          "output-power": null,
 | 
					          "output-power": optional decimal W,
 | 
				
			||||||
          "path_bandwidth": null
 | 
					          "path_bandwidth": optional bit/s
 | 
				
			||||||
          }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }],
 | 
					    }
 | 
				
			||||||
  "synchronization": [
 | 
					  ],
 | 
				
			||||||
 | 
					  "synchronization": [   list of disjunctions, optional
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      "synchronization-id": null,
 | 
					      "synchronization-id": "3",
 | 
				
			||||||
      "svec": {
 | 
					      "svec": {
 | 
				
			||||||
        "relaxable": "True",
 | 
					        "relaxable": "True",
 | 
				
			||||||
        "disjointness": "node link",
 | 
					        "disjointness": "node link",
 | 
				
			||||||
@@ -72,5 +73,5 @@
 | 
				
			|||||||
         null, null ]
 | 
					         null, null ]
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    ]
 | 
					  ]  
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user