mirror of
				https://github.com/Telecominfraproject/oopt-gnpy.git
				synced 2025-10-31 10:07:57 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			153 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			153 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/usr/bin/env python3
 | |
| # TelecomInfraProject/gnpy/examples
 | |
| # Module name : path_requests_run.py
 | |
| # Version : 
 | |
| # License : BSD 3-Clause Licence
 | |
| # Copyright (c) 2018, Telecom Infra Project
 | |
| 
 | |
| """
 | |
| @author: esther.lerouzic
 | |
| @author: jeanluc-auge
 | |
| read json request file in accordance with:
 | |
|     Yang model for requesting Path Computation
 | |
|     draft-ietf-teas-yang-path-computation-01.txt. 
 | |
| and returns path results in terms of path and feasibility
 | |
| 
 | |
| """
 | |
| 
 | |
| from sys import exit
 | |
| from argparse import ArgumentParser
 | |
| from pathlib import Path
 | |
| from collections import namedtuple
 | |
| from logging import getLogger, basicConfig, CRITICAL, DEBUG, INFO
 | |
| from json import dumps, loads
 | |
| from networkx import (draw_networkx_nodes, draw_networkx_edges,
 | |
|                       draw_networkx_labels, dijkstra_path, NetworkXNoPath)
 | |
| from numpy import mean
 | |
| from examples.convert_service_sheet import convert_service_sheet, Request_element, Element
 | |
| from gnpy.core.utils import load_json
 | |
| from gnpy.core.network import load_network, build_network
 | |
| from gnpy.core.equipment import load_equipment
 | |
| from gnpy.core.elements import Transceiver, Roadm, Edfa, Fused
 | |
| from gnpy.core.utils import db2lin, lin2db
 | |
| from gnpy.core.info import create_input_spectral_information, SpectralInformation, Channel, Power
 | |
| from gnpy.core.request import Path_request, Result_element, compute_constrained_path, propagate
 | |
| from copy import copy, deepcopy
 | |
| from numpy import log10
 | |
| 
 | |
| #EQPT_LIBRARY_FILENAME = Path(__file__).parent / 'eqpt_config.json'
 | |
| 
 | |
| logger = getLogger(__name__)
 | |
| 
 | |
| parser = ArgumentParser(description = 'A function that computes performances for a list of services provided in a json file or an excel sheet.')
 | |
| parser.add_argument('network_filename', nargs='?', type = Path, default= Path(__file__).parent / 'meshTopologyExampleV2.xls')
 | |
| parser.add_argument('service_filename', nargs='?', type = Path, default= Path(__file__).parent / 'meshTopologyExampleV2.xls')
 | |
| parser.add_argument('eqpt_filename', nargs='?', type = Path, default=Path(__file__).parent / 'eqpt_config.json')
 | |
| parser.add_argument('-v', '--verbose', action='count')
 | |
| parser.add_argument('-o', '--output', default=None)
 | |
| 
 | |
| 
 | |
| def requests_from_json(json_data,equipment):
 | |
|     requests_list = []
 | |
|     tsp_lib = equipment['Transceiver']
 | |
| 
 | |
|     for req in json_data['path-request']:
 | |
|         #print(f'{req}')
 | |
|         params = {}
 | |
|         params['request_id'] = req['request-id']
 | |
|         params['source'] = req['src-tp-id']
 | |
|         params['destination'] = req['dst-tp-id']
 | |
|         params['trx_type'] = req['path-constraints']['te-bandwidth']['trx_type']
 | |
|         params['trx_mode'] = req['path-constraints']['te-bandwidth']['trx_mode']
 | |
|         params['frequency'] = tsp_lib[params['trx_type']].frequency
 | |
|         #TODO Esther
 | |
|         try:
 | |
|             extra_params =  next(m 
 | |
|                 for m in tsp_lib[params['trx_type']].mode if  m['format'] == params['trx_mode'])
 | |
|         except StopIteration :
 | |
|             msg = f'could not find tsp : {params["trx_type"]} with mode: {params["trx_mode"]} in eqpt library'
 | |
|             raise ValueError(msg)
 | |
|         nd_list = req['optimizations']['explicit-route-include-objects']
 | |
|         params['nodes_list'] = [n['unnumbered-hop']['node-id'] for n in nd_list]
 | |
|         params['loose_list'] = [n['unnumbered-hop']['hop-type'] for n in nd_list]
 | |
|         params['spacing'] = req['path-constraints']['te-bandwidth']['spacing']
 | |
|         params['power'] = req['path-constraints']['te-bandwidth']['output-power']
 | |
|         params['nb_channel'] = req['path-constraints']['te-bandwidth']['max-nb-of-channel']
 | |
| 
 | |
|         params.update(extra_params)
 | |
|         requests_list.append(Path_request(**params))
 | |
| 
 | |
|     return requests_list
 | |
| 
 | |
| 
 | |
| def load_requests(filename,eqpt_filename):
 | |
|     if filename.suffix.lower() == '.xls':
 | |
|         logger.info('Automatically converting requests from XLS to JSON')
 | |
|         json_data = convert_service_sheet(filename,eqpt_filename)
 | |
|     else:
 | |
|         with open(filename) as f:
 | |
|             json_data = loads(f.read())
 | |
|     return json_data
 | |
| 
 | |
| def compute_path(network, pathreqlist):
 | |
|     
 | |
|     path_res_list = []
 | |
| 
 | |
|     for pathreq in pathreqlist:
 | |
|         pathreq.nodes_list.append(pathreq.destination)
 | |
|         #we assume that the destination is a strict constraint
 | |
|         pathreq.loose_list.append('strict')
 | |
|         print(f'Computing path from {pathreq.source} to {pathreq.destination}')
 | |
|         print(f'with explicit path: {pathreq.nodes_list}')
 | |
|         total_path = compute_constrained_path(network, pathreq)
 | |
|         
 | |
|         # for debug
 | |
|         # print(f'{pathreq.baudrate}   {pathreq.power}   {pathreq.spacing}   {pathreq.nb_channel}')
 | |
|         
 | |
|         total_path = propagate(total_path,pathreq,equipment, show=False)
 | |
| 
 | |
|         # we record the last tranceiver object in order to have th whole 
 | |
|         # information about spectrum. Important Note: since transceivers 
 | |
|         # attached to roadms are actually logical elements to simulate
 | |
|         # performance, several demands having the same destination may use 
 | |
|         # the same transponder for the performance simaulation. This is why 
 | |
|         # we use deepcopy: to ensure each propagation is recorded and not 
 | |
|         # overwritten 
 | |
|         
 | |
|         path_res_list.append(deepcopy(total_path))
 | |
|     return path_res_list
 | |
| 
 | |
| def path_result_json(pathresult):
 | |
|     data = {
 | |
|         'path': [n.json for n in pathresult]
 | |
|     }
 | |
|     return data
 | |
| 
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     args = parser.parse_args()
 | |
|     basicConfig(level={2: DEBUG, 1: INFO, 0: CRITICAL}.get(args.verbose, CRITICAL))
 | |
|     logger.info(f'Computing path requests {args.service_filename} into JSON format')
 | |
|     # for debug
 | |
|     # print( args.eqpt_filename)
 | |
|     data = load_requests(args.service_filename,args.eqpt_filename)
 | |
|     equipment = load_equipment(args.eqpt_filename)
 | |
|     network = load_network(args.network_filename,equipment)
 | |
|     build_network(network, equipment=equipment)
 | |
|     pths = requests_from_json(data, equipment)
 | |
|     print(pths)
 | |
|     test = compute_path(network,pths)
 | |
| 
 | |
|     if args.output is None:
 | |
|         #TODO write results
 | |
|         print("demand\t\t\t\tsnr@bandwidth\tsnr@0.1nm")
 | |
|         
 | |
|         for i, p in enumerate(test):
 | |
|             print(f'{pths[i].source} to {pths[i].destination} : {round(mean(p[-1].snr),2)} ,\
 | |
|                 {round(mean(p[-1].snr+10*log10(pths[i].baudrate/(12.5e9))),2)}')
 | |
|     else:
 | |
|         result = []
 | |
|         for p in test:
 | |
|             result.append(Result_element(pths[test.index(p)],p))
 | |
|         with open(args.output, 'w') as f:
 | |
|             f.write(dumps(path_result_json(result), indent=2)) | 
