mirror of
				https://github.com/Telecominfraproject/oopt-gnpy.git
				synced 2025-10-31 10:07:57 +00:00 
			
		
		
		
	 07eb2dd13a
			
		
	
	07eb2dd13a
	
	
	
		
			
			The TL;DR behind this patch is that it's better to have a utility conversion function instead of having multiplier LUT and open code which implements the conversion. The FiberParams handling looked fishy -- apparently, it was keeping the multiplier around, but it was unconditionally setting the units to meters, anyway. Given that the units were not being preserved anyway (everything got converted to meters), and that the multipler was not used anywhere, let's refactor the code to just convert to meters using our new utility function, and remove the unused argument. Change-Id: Id886d409a4046f980eed569265baefd97db841bd
		
			
				
	
	
		
			275 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			275 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/usr/bin/env python3
 | |
| # -*- coding: utf-8 -*-
 | |
| 
 | |
| """
 | |
| gnpy.core.parameters
 | |
| ====================
 | |
| 
 | |
| This module contains all parameters to configure standard network elements.
 | |
| 
 | |
| """
 | |
| 
 | |
| from logging import getLogger
 | |
| from scipy.constants import c, pi
 | |
| from numpy import squeeze, log10, exp
 | |
| 
 | |
| 
 | |
| from gnpy.core.utils import db2lin, convert_length
 | |
| from gnpy.core.exceptions import ParametersError
 | |
| 
 | |
| 
 | |
| logger = getLogger(__name__)
 | |
| 
 | |
| 
 | |
| class Parameters:
 | |
|     def asdict(self):
 | |
|         class_dict = self.__class__.__dict__
 | |
|         instance_dict = self.__dict__
 | |
|         new_dict = {}
 | |
|         for key in class_dict:
 | |
|             if isinstance(class_dict[key], property):
 | |
|                 new_dict[key] = instance_dict['_' + key]
 | |
|         return new_dict
 | |
| 
 | |
| 
 | |
| class PumpParams(Parameters):
 | |
|     def __init__(self, power, frequency, propagation_direction):
 | |
|         self._power = power
 | |
|         self._frequency = frequency
 | |
|         self._propagation_direction = propagation_direction
 | |
| 
 | |
|     @property
 | |
|     def power(self):
 | |
|         return self._power
 | |
| 
 | |
|     @property
 | |
|     def frequency(self):
 | |
|         return self._frequency
 | |
| 
 | |
|     @property
 | |
|     def propagation_direction(self):
 | |
|         return self._propagation_direction
 | |
| 
 | |
| 
 | |
| class RamanParams(Parameters):
 | |
|     def __init__(self, **kwargs):
 | |
|         self._flag_raman = kwargs['flag_raman']
 | |
|         self._space_resolution = kwargs['space_resolution'] if 'space_resolution' in kwargs else None
 | |
|         self._tolerance = kwargs['tolerance'] if 'tolerance' in kwargs else None
 | |
| 
 | |
|     @property
 | |
|     def flag_raman(self):
 | |
|         return self._flag_raman
 | |
| 
 | |
|     @property
 | |
|     def space_resolution(self):
 | |
|         return self._space_resolution
 | |
| 
 | |
|     @property
 | |
|     def tolerance(self):
 | |
|         return self._tolerance
 | |
| 
 | |
| 
 | |
| class NLIParams(Parameters):
 | |
|     def __init__(self, **kwargs):
 | |
|         self._nli_method_name = kwargs['nli_method_name']
 | |
|         self._wdm_grid_size = kwargs['wdm_grid_size']
 | |
|         self._dispersion_tolerance = kwargs['dispersion_tolerance']
 | |
|         self._phase_shift_tolerance = kwargs['phase_shift_tolerance']
 | |
|         self._f_cut_resolution = None
 | |
|         self._f_pump_resolution = None
 | |
|         self._computed_channels = kwargs['computed_channels'] if 'computed_channels' in kwargs else None
 | |
| 
 | |
|     @property
 | |
|     def nli_method_name(self):
 | |
|         return self._nli_method_name
 | |
| 
 | |
|     @property
 | |
|     def wdm_grid_size(self):
 | |
|         return self._wdm_grid_size
 | |
| 
 | |
|     @property
 | |
|     def dispersion_tolerance(self):
 | |
|         return self._dispersion_tolerance
 | |
| 
 | |
|     @property
 | |
|     def phase_shift_tolerance(self):
 | |
|         return self._phase_shift_tolerance
 | |
| 
 | |
|     @property
 | |
|     def f_cut_resolution(self):
 | |
|         return self._f_cut_resolution
 | |
| 
 | |
|     @f_cut_resolution.setter
 | |
|     def f_cut_resolution(self, f_cut_resolution):
 | |
|         self._f_cut_resolution = f_cut_resolution
 | |
| 
 | |
|     @property
 | |
|     def f_pump_resolution(self):
 | |
|         return self._f_pump_resolution
 | |
| 
 | |
|     @f_pump_resolution.setter
 | |
|     def f_pump_resolution(self, f_pump_resolution):
 | |
|         self._f_pump_resolution = f_pump_resolution
 | |
| 
 | |
|     @property
 | |
|     def computed_channels(self):
 | |
|         return self._computed_channels
 | |
| 
 | |
| 
 | |
| class SimParams(Parameters):
 | |
|     def __init__(self, **kwargs):
 | |
|         if kwargs:
 | |
|             if 'nli_parameters' in kwargs:
 | |
|                 self._nli_params = NLIParams(**kwargs['nli_parameters'])
 | |
|             else:
 | |
|                 self._nli_params = None
 | |
|             if 'raman_parameters' in kwargs:
 | |
|                 self._raman_params = RamanParams(**kwargs['raman_parameters'])
 | |
|             else:
 | |
|                 self._raman_params = None
 | |
| 
 | |
|     @property
 | |
|     def nli_params(self):
 | |
|         return self._nli_params
 | |
| 
 | |
|     @property
 | |
|     def raman_params(self):
 | |
|         return self._raman_params
 | |
| 
 | |
| 
 | |
| class FiberParams(Parameters):
 | |
|     def __init__(self, **kwargs):
 | |
|         try:
 | |
|             self._length = convert_length(kwargs['length'], kwargs['length_units'])
 | |
|             # fixed attenuator for padding
 | |
|             self._att_in = kwargs['att_in'] if 'att_in' in kwargs else 0
 | |
|             # if not defined in the network json connector loss in/out
 | |
|             # the None value will be updated in network.py[build_network]
 | |
|             # with default values from eqpt_config.json[Spans]
 | |
|             self._con_in = kwargs['con_in'] if 'con_in' in kwargs else None
 | |
|             self._con_out = kwargs['con_out'] if 'con_out' in kwargs else None
 | |
|             self._gamma = kwargs['gamma']  # 1/W/m
 | |
|             self._dispersion = kwargs['dispersion']  # s/m/m
 | |
|             if 'ref_wavelength' in kwargs:
 | |
|                 self._ref_wavelength = kwargs['ref_wavelength']
 | |
|                 self._ref_frequency = c / self._ref_wavelength
 | |
|             elif 'ref_frequency' in kwargs:
 | |
|                 self._ref_frequency = kwargs['ref_frequency']
 | |
|                 self._ref_wavelength = c / self._ref_frequency
 | |
|             else:
 | |
|                 self._ref_wavelength = 1550e-9
 | |
|                 self._ref_frequency = c / self._ref_wavelength
 | |
|             self._beta2 = (self._ref_wavelength ** 2) * abs(self._dispersion) / (2 * pi * c)  # 1/(m * Hz^2)
 | |
|             self._beta3 = kwargs['beta3'] if 'beta3' in kwargs else 0
 | |
|             if type(kwargs['loss_coef']) == dict:
 | |
|                 self._loss_coef = squeeze(kwargs['loss_coef']['loss_coef_power']) * 1e-3  # lineic loss dB/m
 | |
|                 self._f_loss_ref = squeeze(kwargs['loss_coef']['frequency'])  # Hz
 | |
|             else:
 | |
|                 self._loss_coef = kwargs['loss_coef'] * 1e-3  # lineic loss dB/m
 | |
|                 self._f_loss_ref = 193.5e12  # Hz
 | |
|             self._lin_attenuation = db2lin(self._length * self._loss_coef)
 | |
|             self._lin_loss_exp = self._loss_coef / (10 * log10(exp(1)))  # linear power exponent loss Neper/m
 | |
|             self._effective_length = (1 - exp(- self._lin_loss_exp * self._length)) / self._lin_loss_exp
 | |
|             self._asymptotic_length = 1 / self._lin_loss_exp
 | |
|             # raman parameters (not compulsory)
 | |
|             self._raman_efficiency = kwargs['raman_efficiency'] if 'raman_efficiency' in kwargs else None
 | |
|             self._pumps_loss_coef = kwargs['pumps_loss_coef'] if 'pumps_loss_coef' in kwargs else None
 | |
|         except KeyError as e:
 | |
|             raise ParametersError(f'Fiber configurations json must include {e}. Configuration: {kwargs}')
 | |
| 
 | |
|     @property
 | |
|     def length(self):
 | |
|         return self._length
 | |
| 
 | |
|     @length.setter
 | |
|     def length(self, length):
 | |
|         """length must be in m"""
 | |
|         self._length = length
 | |
| 
 | |
|     @property
 | |
|     def att_in(self):
 | |
|         return self._att_in
 | |
| 
 | |
|     @att_in.setter
 | |
|     def att_in(self, att_in):
 | |
|         self._att_in = att_in
 | |
| 
 | |
|     @property
 | |
|     def con_in(self):
 | |
|         return self._con_in
 | |
| 
 | |
|     @con_in.setter
 | |
|     def con_in(self, con_in):
 | |
|         self._con_in = con_in
 | |
| 
 | |
|     @property
 | |
|     def con_out(self):
 | |
|         return self._con_out
 | |
| 
 | |
|     @con_out.setter
 | |
|     def con_out(self, con_out):
 | |
|         self._con_out = con_out
 | |
| 
 | |
|     @property
 | |
|     def dispersion(self):
 | |
|         return self._dispersion
 | |
| 
 | |
|     @property
 | |
|     def gamma(self):
 | |
|         return self._gamma
 | |
| 
 | |
|     @property
 | |
|     def ref_wavelength(self):
 | |
|         return self._ref_wavelength
 | |
| 
 | |
|     @property
 | |
|     def ref_frequency(self):
 | |
|         return self._ref_frequency
 | |
| 
 | |
|     @property
 | |
|     def beta2(self):
 | |
|         return self._beta2
 | |
| 
 | |
|     @property
 | |
|     def beta3(self):
 | |
|         return self._beta3
 | |
| 
 | |
|     @property
 | |
|     def loss_coef(self):
 | |
|         return self._loss_coef
 | |
| 
 | |
|     @property
 | |
|     def f_loss_ref(self):
 | |
|         return self._f_loss_ref
 | |
| 
 | |
|     @property
 | |
|     def lin_loss_exp(self):
 | |
|         return self._lin_loss_exp
 | |
| 
 | |
|     @property
 | |
|     def lin_attenuation(self):
 | |
|         return self._lin_attenuation
 | |
| 
 | |
|     @property
 | |
|     def effective_length(self):
 | |
|         return self._effective_length
 | |
| 
 | |
|     @property
 | |
|     def asymptotic_length(self):
 | |
|         return self._asymptotic_length
 | |
| 
 | |
|     @property
 | |
|     def raman_efficiency(self):
 | |
|         return self._raman_efficiency
 | |
| 
 | |
|     @property
 | |
|     def pumps_loss_coef(self):
 | |
|         return self._pumps_loss_coef
 | |
| 
 | |
|     def asdict(self):
 | |
|         dictionary = super().asdict()
 | |
|         dictionary['loss_coef'] = self.loss_coef * 1e3
 | |
|         dictionary['length_units'] = 'm'
 | |
|         return dictionary
 |