diff --git a/gnpy/tools/cli_examples.py b/gnpy/tools/cli_examples.py index d9ee818e..5cb28463 100644 --- a/gnpy/tools/cli_examples.py +++ b/gnpy/tools/cli_examples.py @@ -299,6 +299,9 @@ def path_requests_run(args=None): help='considers that all demands are bidir') parser.add_argument('-o', '--output', type=Path, metavar=_help_fname_json_csv, help='Store satisifed requests into a JSON or CSV file') + parser.add_argument('--redesign-per-request', action='store_true', help='Redesign the network at each request' + + ' computation using the request as the reference channel') + args = parser.parse_args(args if args is not None else sys.argv[1:]) _setup_logging(args) @@ -321,7 +324,7 @@ def path_requests_run(args=None): network=network, network_filename=args.topology) _data = requests_from_json(data, equipment) oms_list, propagatedpths, reversed_propagatedpths, rqs, dsjn, result = \ - planning(network, equipment, data) + planning(network, equipment, data, redesign=args.redesign_per_request) except exceptions.NetworkTopologyError as e: print(f'{ansi_escapes.red}Invalid network definition:{ansi_escapes.reset} {e}') sys.exit(1) diff --git a/gnpy/tools/worker_utils.py b/gnpy/tools/worker_utils.py index 09689f33..48c564b9 100644 --- a/gnpy/tools/worker_utils.py +++ b/gnpy/tools/worker_utils.py @@ -140,10 +140,13 @@ def check_request_path_ids(rqs: List[PathRequest]): raise ValueError(msg) -def planning(network: DiGraph, equipment: dict, data: dict) \ +def planning(network: DiGraph, equipment: dict, data: dict, redesign: bool = False) \ -> Tuple[List[OMS], list, list, List[PathRequest], List[Disjunction], List[ResultElement]]: """Run planning data contain the service dict from json + redesign True means that network is redesign using each request as reference channel + when False it means that the design is made once and successive propagation use the settings + computed with this design. """ oms_list = build_oms_list(network, equipment) rqs = requests_from_json(data, equipment) @@ -163,7 +166,7 @@ def planning(network: DiGraph, equipment: dict, data: dict) \ pths = compute_path_dsjctn(network, equipment, rqs, dsjn) logger.info('Propagating on selected path') propagatedpths, reversed_pths, reversed_propagatedpths = \ - compute_path_with_disjunction(network, equipment, rqs, pths) + compute_path_with_disjunction(network, equipment, rqs, pths, redesign=redesign) # Note that deepcopy used in compute_path_with_disjunction returns # a list of nodes which are not belonging to network (they are copies of the node objects). # so there can not be propagation on these nodes. diff --git a/gnpy/topology/request.py b/gnpy/topology/request.py index da00c99d..197ed266 100644 --- a/gnpy/topology/request.py +++ b/gnpy/topology/request.py @@ -1071,7 +1071,7 @@ def deduplicate_disjunctions(disjn): return local_disjn -def compute_path_with_disjunction(network, equipment, pathreqlist, pathlist): +def compute_path_with_disjunction(network, equipment, pathreqlist, pathlist, redesign=False): """use a list but a dictionnary might be helpful to find path based on request_id TODO change all these req, dsjct, res lists into dict ! @@ -1080,6 +1080,10 @@ def compute_path_with_disjunction(network, equipment, pathreqlist, pathlist): reversed_path_res_list = [] propagated_reversed_path_res_list = [] + total_nb_requests = len(pathreqlist) + if redesign: + LOGGER.warning('Redesign the network for each request channel, ' + + 'using the request channel as the reference channel for the design.') for i, pathreq in enumerate(pathreqlist): # use the power specified in requests but might be different from the one @@ -1097,7 +1101,16 @@ def compute_path_with_disjunction(network, equipment, pathreqlist, pathlist): # elements to simulate performance, several demands having the same destination # may use the same transponder for the performance simulation. This is why # we use deepcopy: to ensure that each propagation is recorded and not overwritten - network_module.design_network(pathreq, network, equipment, set_connector_losses=False, verbose=False) + # reversed path is needed for correct spectrum assignment + if redesign: + # this is the legacy case where network was automatically redesigned using the + # request channel as reference (nb and power used for amplifiers total power out) + reversed_path = [] + if pathlist[i]: + reversed_path = find_reversed_path(pathlist[i]) + network_nodes_for_redesign = pathlist[i] + reversed_path + network_module.design_network(pathreq, network.subgraph(network_nodes_for_redesign), equipment, + set_connector_losses=False, verbose=False) total_path = deepcopy(pathlist[i]) msg = msg + f'\n\tComputed path (roadms):{[e.uid for e in total_path if isinstance(e, Roadm)]}' LOGGER.info(msg) diff --git a/tests/invocation/logs_path_request b/tests/invocation/logs_path_request index e0b875da..ec1533ca 100644 --- a/tests/invocation/logs_path_request +++ b/tests/invocation/logs_path_request @@ -118,6 +118,7 @@ INFO gnpy.tools.worker_utils:worker_utils.py The following services have bee loose-list: [] ] INFO gnpy.tools.worker_utils:worker_utils.py Propagating on selected path +WARNING gnpy.topology.request:request.py Redesign the network for each request channel, using the request channel as the reference channel for the design. INFO gnpy.topology.request:request.py request 0 Computing path from trx Lorient_KMA to trx Vannes_KBE diff --git a/tests/test_invocation.py b/tests/test_invocation.py index 7a474345..9f18a1af 100644 --- a/tests/test_invocation.py +++ b/tests/test_invocation.py @@ -14,7 +14,7 @@ SRC_ROOT = Path(__file__).parent.parent ('transmission_main_example', None, transmission_main_example, []), ('transmission_saturated', 'logs_transmission_saturated', transmission_main_example, ['tests/data/testTopology_expected.json', 'lannion', 'lorient', '-e', 'tests/data/eqpt_config.json', '--pow', '3']), - ('path_requests_run', 'logs_path_request', path_requests_run, ['-v']), + ('path_requests_run', 'logs_path_request', path_requests_run, ['--redesign-per-request', '-v']), ('transmission_main_example__raman', None, transmission_main_example, ['gnpy/example-data/raman_edfa_example_network.json', '--sim', 'gnpy/example-data/sim_params.json', '--show-channels', ]), ('openroadm-v4-Stockholm-Gothenburg', None, transmission_main_example, diff --git a/tests/test_parser.py b/tests/test_parser.py index 689f5b93..af309916 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -232,7 +232,7 @@ def test_json_response_generation(xls_input, expected_response_file): rqs, dsjn = requests_aggregation(rqs, dsjn) pths = compute_path_dsjctn(network, equipment, rqs, dsjn) propagatedpths, reversed_pths, reversed_propagatedpths = \ - compute_path_with_disjunction(network, equipment, rqs, pths) + compute_path_with_disjunction(network, equipment, rqs, pths, redesign=True) pth_assign_spectrum(pths, rqs, oms_list, reversed_pths) result = []