mirror of
				https://github.com/Telecominfraproject/oopt-gnpy.git
				synced 2025-10-31 01:57:54 +00:00 
			
		
		
		
	Merge branch 'develop' into path_disjunction solving conflict
Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com>
This commit is contained in:
		
							
								
								
									
										29
									
								
								README.rst
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								README.rst
									
									
									
									
									
								
							| @@ -9,7 +9,7 @@ planning and optimization tools in real-world mesh optical networks.** | ||||
|  | ||||
| `gnpy <http://github.com/telecominfraproject/oopt-gnpy>`__ is: | ||||
|  | ||||
| - a sponsored project of the `OOPT/PSE <https://telecominfraproject.com/open-optical-packet-transport/>`_ working group of the `Telecom Infra Project <http://telecominfraproject.com>`_. | ||||
| - a sponsored project of the `OOPT/PSE <https://telecominfraproject.com/open-optical-packet-transport/>`_ working group of the `Telecom Infra Project <http://telecominfraproject.com>`_ | ||||
| - fully community-driven, fully open source library | ||||
| - driven by a consortium of operators, vendors, and academic researchers | ||||
| - intended for rapid development of production-grade route planning tools | ||||
| @@ -135,8 +135,8 @@ By default, this script operates on a single span network defined in | ||||
| `examples/edfa_example_network.json <examples/edfa_example_network.json>`_ | ||||
|  | ||||
| You can specify a different network at the command line as follows. For | ||||
| example, to use the CORONET Continental US (CONUS) network defined in | ||||
| `examples/coronet_conus_example.json <examples/coronet_conus_example.json>`_: | ||||
| example, to use the CORONET Global network defined in | ||||
| `examples/CORONET_Global_Topology.json <examples/CORONET_Global_Topology.json>`_: | ||||
|  | ||||
| .. code-block:: shell | ||||
|  | ||||
| @@ -150,10 +150,10 @@ further instructions on how to prepare the Excel input file, see | ||||
| `Excel_userguide.rst <Excel_userguide.rst>`_. | ||||
|  | ||||
| The main transmission example will calculate the average signal OSNR and SNR | ||||
| across 93 network elements (transceiver, ROADMs, fibers, and amplifiers) | ||||
| between two transceivers selected by the user. (By default, for the CORONET US | ||||
| network, it will show the transmission of spectral information between Abilene, | ||||
| Texas and Albany, New York.) | ||||
| across network elements (transceiver, ROADMs, fibers, and amplifiers) | ||||
| between two transceivers selected by the user. (By default, for the CORONET Global | ||||
| network, it will show the transmission of spectral information between Albuquerque, | ||||
| New Mexico and Atlanta, Georgia.) | ||||
|  | ||||
| This script calculates the average signal OSNR = |OSNR| and SNR = |SNR|. | ||||
|  | ||||
| @@ -209,7 +209,7 @@ The fiber library currently describes SSMF but additional fiber types can be ent | ||||
| +----------------------+-----------+-----------------------------------------+ | ||||
| | field                | type      | description                             | | ||||
| +======================+===========+=========================================+ | ||||
| | `type_variety`       | (string)  | a unique name to ID the amplifier in the| | ||||
| | `type_variety`       | (string)  | a unique name to ID the fiber in the    | | ||||
| |                      |           | JSON or Excel template topology input   | | ||||
| |                      |           | file                                    | | ||||
| +----------------------+-----------+-----------------------------------------+ | ||||
| @@ -226,7 +226,7 @@ path_request_run.py routine. | ||||
| +----------------------+-----------+-----------------------------------------+ | ||||
| | field                | type      | description                             | | ||||
| +======================+===========+=========================================+ | ||||
| |  `type_variety`      | (string)  | a unique name to ID the amplifier in    | | ||||
| |  `type_variety`      | (string)  | a unique name to ID the transceiver in  | | ||||
| |                      |           | the JSON or Excel template topology     | | ||||
| |                      |           | input file                              | | ||||
| +----------------------+-----------+-----------------------------------------+ | ||||
| @@ -252,7 +252,7 @@ The modes are defined as follows: | ||||
| +----------------------+-----------+-----------------------------------------+ | ||||
| | `bit_rate`           | (number)  | in bit/s                                | | ||||
| +----------------------+-----------+-----------------------------------------+ | ||||
| | `roll_off`           | (number)  |                                         | | ||||
| | `roll_off`           | (number)  | Not used.                               | | ||||
| +----------------------+-----------+-----------------------------------------+ | ||||
|  | ||||
| Simulation parameters are defined as follows. | ||||
| @@ -269,8 +269,8 @@ For amplifiers defined in the topology JSON input but whose gain = 0 | ||||
| (placeholder), auto-design will set its gain automatically: see `power_mode` in | ||||
| the `Spans` library to find out how the gain is calculated. | ||||
|  | ||||
| Span configuration is performed as followws. It is not a list (which may change | ||||
| in later releases,) and the user can only modify the value of existing | ||||
| Span configuration is performed as follows. It is not a list (which may change | ||||
| in later releases) and the user can only modify the value of existing | ||||
| parameters: | ||||
|  | ||||
| +------------------------+-----------+---------------------------------------------+ | ||||
| @@ -470,11 +470,6 @@ dBm/channel. These are not yet parametrized but can be modified directly in the | ||||
| script (via the SpectralInformation structure) to accomodate any baud rate, | ||||
| spacing, power or channel count demand. | ||||
|  | ||||
| The amplifier's gain is set to exactly compensate for the loss in each network | ||||
| element. The amplifier is currently defined with gain range of 15 dB to 25 dB | ||||
| and 21 dBm max output power. Ripple and NF models are defined in | ||||
| `examples/std_medium_gain_advanced_config.json <examples/std_medium_gain_advanced_config.json>`_ | ||||
|  | ||||
| Use `examples/path_requests_run.py <examples/path_requests_run.py>`_ to run multiple optimizations as follows: | ||||
|  | ||||
| .. code-block:: shell | ||||
|   | ||||
| @@ -70,7 +70,7 @@ def read_excel(input_filename): | ||||
|  | ||||
| def create_eqt_template(links,nodes, links_by_src , links_by_dest, input_filename): | ||||
|     output_filename = f'{input_filename[:-4]}_eqpt_sheet.txt' | ||||
|     with open(output_filename,'w') as my_file : | ||||
|     with open(output_filename, 'w', encoding='utf-8') as my_file: | ||||
|         # print header similar to excel | ||||
|         my_file.write('OPTIONAL\n\n\n\ | ||||
|            \t\tNode a egress amp (from a to z)\t\t\t\t\tNode a ingress amp (from z to a) \ | ||||
|   | ||||
| @@ -64,6 +64,16 @@ | ||||
|             "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 | ||||
|             } | ||||
|       ], | ||||
|       "Spans":[{ | ||||
|   | ||||
| @@ -117,7 +117,7 @@ def load_requests(filename,eqpt_filename): | ||||
|         logger.info('Automatically converting requests from XLS to JSON') | ||||
|         json_data = convert_service_sheet(filename,eqpt_filename) | ||||
|     else: | ||||
|         with open(filename) as f: | ||||
|         with open(filename, encoding='utf-8') as f: | ||||
|             json_data = loads(f.read()) | ||||
|     return json_data | ||||
|  | ||||
| @@ -297,7 +297,7 @@ if __name__ == '__main__': | ||||
|         for p in pths: | ||||
|             result.append(Result_element(rqs[pths.index(p)],p)) | ||||
|         with open(args.output, 'w') as f: | ||||
|             f.write(dumps(path_result_json(result), indent=2)) | ||||
|             f.write(dumps(path_result_json(result), indent=2, ensure_ascii=False)) | ||||
|             fnamecsv = next(s for s in args.output.split('.')) + '.csv' | ||||
|             with open(fnamecsv,"w") as fcsv : | ||||
|                 jsontocsv(path_result_json(result),equipment,fcsv) | ||||
|   | ||||
| @@ -150,16 +150,14 @@ if __name__ == '__main__': | ||||
|         exit() | ||||
|  | ||||
|     if args.source: | ||||
|         try: | ||||
|             source = next(transceivers[uid] for uid in transceivers if uid == args.source) | ||||
|         except StopIteration as e: | ||||
|         source = transceivers.get(args.source) | ||||
|         if not source: | ||||
|             #TODO code a more advanced regex to find nodes match | ||||
|             nodes_suggestion = [uid for uid in transceivers \ | ||||
|                 if args.source.lower() in uid.lower()] | ||||
|             source = transceivers[nodes_suggestion[0]] \ | ||||
|                 if len(nodes_suggestion)>0 else list(transceivers.values())[0] | ||||
|             print(f'invalid souce node specified, did you mean:\ | ||||
|                   \n{nodes_suggestion}?\ | ||||
|             print(f'invalid souce node specified,\ | ||||
|                   \n{args.source!r}, replaced with {source.uid}') | ||||
|             del transceivers[source.uid] | ||||
|     else: | ||||
| @@ -167,15 +165,13 @@ if __name__ == '__main__': | ||||
|         source = list(transceivers.values())[0] | ||||
|  | ||||
|     if args.destination: | ||||
|         try: | ||||
|             destination = next(transceivers[uid] for uid in transceivers if uid == args.destination) | ||||
|         except StopIteration as e: | ||||
|         destination = transceivers.get(args.destination) | ||||
|         if not destination: | ||||
|             nodes_suggestion = [uid for uid in transceivers \ | ||||
|                 if args.destination.lower() in uid.lower()] | ||||
|             destination = transceivers[nodes_suggestion[0]] \ | ||||
|                 if len(nodes_suggestion)>0 else list(transceivers.values())[0] | ||||
|             print(f'invalid destination node specified, did you mean:\ | ||||
|                 \n{nodes_suggestion}?\ | ||||
|             print(f'invalid destination node specified,\ | ||||
|                 \n{args.destination!r}, replaced with {destination.uid}') | ||||
|     else: | ||||
|         logger.info('No source node specified: picking random transceiver') | ||||
|   | ||||
| @@ -26,8 +26,8 @@ parser.add_argument('eqpt_filename', nargs='?', type = Path, default=Path(__file | ||||
| if __name__ == '__main__': | ||||
|     args = parser.parse_args() | ||||
|  | ||||
|     with open(args.output_filename,"w") as file : | ||||
|         with open(args.filename) as f: | ||||
|     with open(args.output_filename, 'w', encoding='utf-8') as file: | ||||
|         with open(args.filename, encoding='utf-8') as f: | ||||
|             print(f'Reading {args.filename}') | ||||
|             json_data = loads(f.read()) | ||||
|             equipment = load_equipment(args.eqpt_filename) | ||||
|   | ||||
| @@ -214,14 +214,12 @@ def convert_file(input_filename, filter_region=[]): | ||||
|              for x in nodes_by_city.values() if x.node_type.lower()=='roadm']))) | ||||
|     } | ||||
|  | ||||
|     #print(dumps(data, indent=2)) | ||||
|     # output_json_file_name = input_filename.split(".")[0]+".json" | ||||
|     suffix_filename = str(input_filename.suffixes[0]) | ||||
|     full_input_filename = str(input_filename) | ||||
|     split_filename = [full_input_filename[0:len(full_input_filename)-len(suffix_filename)] , suffix_filename[1:]] | ||||
|     output_json_file_name = split_filename[0]+'.json' | ||||
|     with  open(output_json_file_name,'w') as edfa_json_file: | ||||
|         edfa_json_file.write(dumps(data, indent=2)) | ||||
|     with  open(output_json_file_name, 'w', encoding='utf-8') as edfa_json_file: | ||||
|         edfa_json_file.write(dumps(data, indent=2, ensure_ascii=False)) | ||||
|     return output_json_file_name | ||||
|  | ||||
| def parse_excel(input_filename): | ||||
|   | ||||
| @@ -13,7 +13,7 @@ from sys import exit | ||||
| from operator import itemgetter | ||||
| from math import isclose | ||||
| from pathlib import Path | ||||
| from json import loads | ||||
| from json import load | ||||
| from gnpy.core.utils import lin2db, db2lin, load_json | ||||
| from collections import namedtuple | ||||
| from gnpy.core.elements import Edfa | ||||
| @@ -43,14 +43,14 @@ class Amp(AmpBase): | ||||
|  | ||||
|     @classmethod | ||||
|     def from_advanced_json(cls, filename, **kwargs): | ||||
|         with open(filename) as f: | ||||
|             json_data = loads(f.read()) | ||||
|         with open(filename, encoding='utf-8') as f: | ||||
|             json_data = load(f) | ||||
|         return cls(**{**kwargs, **json_data, 'type_def':None, 'nf_model':None}) | ||||
|  | ||||
|     @classmethod | ||||
|     def from_default_json(cls, filename, **kwargs): | ||||
|         with open(filename) as f: | ||||
|             json_data = loads(f.read()) | ||||
|         with open(filename, encoding='utf-8') as f: | ||||
|             json_data = load(f) | ||||
|         type_variety = kwargs['type_variety'] | ||||
|         type_def = kwargs.get('type_def', 'variable_gain') #default compatibility with older json eqpt files | ||||
|         nf_def = None | ||||
| @@ -211,17 +211,17 @@ def equipment_from_json(json_data, filename): | ||||
|     """ | ||||
|     equipment = {} | ||||
|     for key, entries in json_data.items(): | ||||
|         for entry in entries: | ||||
|             if key not in equipment: | ||||
|         equipment[key] = {} | ||||
|             subkey = entry.get('type_variety', 'default') | ||||
|         typ = globals()[key] | ||||
|         for entry in entries: | ||||
|             subkey = entry.get('type_variety', 'default')            | ||||
|             if key == 'Edfa': | ||||
|                 if 'advanced_config_from_json' in entry: | ||||
|                     config = Path(filename).parent / entry.pop('advanced_config_from_json') | ||||
|                     typ = lambda **kws: Amp.from_advanced_json(config, **kws) | ||||
|                     equipment[key][subkey] = Amp.from_advanced_json(config, **entry) | ||||
|                 else: | ||||
|                     config = Path(filename).parent / 'default_edfa_config.json' | ||||
|                     typ = lambda **kws: Amp.from_default_json(config, **kws) | ||||
|                     equipment[key][subkey] = Amp.from_default_json(config, **entry) | ||||
|             else:                 | ||||
|                 equipment[key][subkey] = typ(**entry) | ||||
|     return equipment | ||||
|   | ||||
| @@ -189,7 +189,7 @@ def convert_service_sheet(input_filename, eqpt_filename, output_filename='', fil | ||||
|         if n.json[1] is not None] | ||||
|     } | ||||
|     with open(output_filename, 'w') as f: | ||||
|             f.write(dumps(data, indent=2)) | ||||
|             f.write(dumps(data, indent=2, ensure_ascii=False)) | ||||
|     return data | ||||
|  | ||||
| # to be used from dutc | ||||
|   | ||||
| @@ -18,14 +18,14 @@ from scipy import constants | ||||
|  | ||||
|  | ||||
| def load_json(filename): | ||||
|     with open(filename, 'r') as f: | ||||
|     with open(filename, 'r', encoding='utf-8') as f: | ||||
|         data = json.load(f) | ||||
|     return data | ||||
|  | ||||
|  | ||||
| def save_json(obj, filename): | ||||
|     with open(filename, 'w') as f: | ||||
|         json.dump(obj, f, indent=2) | ||||
|     with open(filename, 'w', encoding='utf-8') as f: | ||||
|         json.dump(obj, f, indent=2, ensure_ascii=False) | ||||
|  | ||||
| def write_csv(obj, filename): | ||||
|     """ | ||||
| @@ -55,7 +55,7 @@ def write_csv(obj, filename): | ||||
|     result_category 2 | ||||
|     ... | ||||
|     """ | ||||
|     with open(filename, 'w') as f: | ||||
|     with open(filename, 'w', encoding='utf-8') as f: | ||||
|         w = writer(f) | ||||
|         for data_key, data_list in obj.items(): | ||||
|             #main header | ||||
|   | ||||
| @@ -105,16 +105,16 @@ def encode_sets(obj): | ||||
| if __name__ == '__main__': | ||||
|     args = parser.parse_args() | ||||
|  | ||||
|     with open(args.expected_output) as f: | ||||
|     with open(args.expected_output, encoding='utf-8') as f: | ||||
|         expected = load(f) | ||||
|  | ||||
|     with open(args.actual_output) as f: | ||||
|     with open(args.actual_output, encoding='utf-8') as f: | ||||
|         actual = load(f) | ||||
|  | ||||
|     result = COMPARISONS[args.comparison](expected, actual) | ||||
|  | ||||
|     if args.output: | ||||
|         with open(args.output, 'w') as f: | ||||
|             dump(result, f, default=encode_sets, indent=2) | ||||
|         with open(args.output, 'w', encoding='utf-8') as f: | ||||
|             dump(result, f, default=encode_sets, indent=2, ensure_ascii=False) | ||||
|     else: | ||||
|         print(str(result)) | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  | ||||
| from gnpy.core.elements import Edfa | ||||
| from numpy import zeros, array | ||||
| from json import load, dumps | ||||
| from json import load | ||||
| from gnpy.core.elements import Transceiver, Fiber, Edfa | ||||
| from gnpy.core.utils import lin2db, db2lin | ||||
| from gnpy.core.info import create_input_spectral_information, SpectralInformation, Channel, Power, Pref | ||||
|   | ||||
| @@ -37,11 +37,11 @@ def test_excel_json_generation(xls_input, expected_json_output): | ||||
|     convert_file(xls_input) | ||||
|  | ||||
|     actual_json_output = xls_input.with_suffix('.json') | ||||
|     with open(actual_json_output) as f: | ||||
|     with open(actual_json_output, encoding='utf-8') as f: | ||||
|         actual = load(f) | ||||
|     unlink(actual_json_output) | ||||
|  | ||||
|     with open(expected_json_output) as f: | ||||
|     with open(expected_json_output, encoding='utf-8') as f: | ||||
|         expected = load(f) | ||||
|  | ||||
|     results = compare_networks(expected, actual) | ||||
| @@ -65,11 +65,11 @@ def test_excel_service_json_generation(xls_input, expected_json_output): | ||||
|     convert_service_sheet(xls_input, eqpt_filename) | ||||
|  | ||||
|     actual_json_output = f'{str(xls_input)[:-4]}_services.json' | ||||
|     with open(actual_json_output) as f: | ||||
|     with open(actual_json_output, encoding='utf-8') as f: | ||||
|         actual = load(f) | ||||
|     unlink(actual_json_output) | ||||
|  | ||||
|     with open(expected_json_output) as f: | ||||
|     with open(expected_json_output, encoding='utf-8') as f: | ||||
|         expected = load(f) | ||||
|  | ||||
|     results = compare_services(expected, actual) | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  | ||||
| from gnpy.core.elements import Edfa | ||||
| import numpy as np | ||||
| from json import load, dumps | ||||
| from json import load | ||||
| import pytest | ||||
| from gnpy.core.elements import Transceiver, Fiber, Edfa | ||||
| from gnpy.core.utils import lin2db, db2lin | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 EstherLerouzic
					EstherLerouzic