mirror of
https://github.com/Telecominfraproject/oopt-gnpy.git
synced 2025-10-30 17:47:50 +00:00
285 lines
8.1 KiB
Python
285 lines
8.1 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.units import UNITS
|
|
from gnpy.core.utils import db2lin
|
|
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_units_factor = UNITS[kwargs['length_units']]
|
|
self._length = kwargs['length'] * self._length_units_factor # m
|
|
self._length_units = 'm'
|
|
# 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}')
|
|
|
|
@property
|
|
def length(self):
|
|
return self._length
|
|
|
|
@length.setter
|
|
def length(self, length):
|
|
"""length must be in m"""
|
|
self._length = length
|
|
|
|
@property
|
|
def length_units(self):
|
|
return self._length_units
|
|
|
|
@property
|
|
def length_units_factor(self):
|
|
return self._length_units_factor
|
|
|
|
@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
|
|
return dictionary
|