mirror of
https://github.com/Telecominfraproject/oopt-gnpy.git
synced 2025-10-30 17:47:50 +00:00
Also make sure that all modules are covered. It seems that there's no automatic way for doing this, aargh. On the other hand, there's apparently no need to repeat all the Sphinx markup blurb, and even sectioning works nicely (read, "as I expect it to work") now :). I think that it's still necessary to keep these "intermediate files" that only trigger package-level and module-level autodocs, but hey, I can live with this. Change-Id: I705e0054cd7cd4350171770795d69f5c15c226d6
287 lines
8.1 KiB
Python
287 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
|
|
|