mirror of
https://github.com/Telecominfraproject/oopt-gnpy.git
synced 2025-11-02 19:18:02 +00:00
160 lines
5.4 KiB
Python
160 lines
5.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
Created on Wed Dec 21 15:09:47 2016
|
|
|
|
@author: briantaylor
|
|
"""
|
|
|
|
import numpy as np
|
|
from gnpy.constants import c, h
|
|
|
|
|
|
class NetworkElement:
|
|
|
|
def __init__(self, **kwargs):
|
|
"""
|
|
self.direction = [("E", "Z"), ("E", "Z"), ("E", "Z"), ("W", "Z")]
|
|
self.port_mapping = [(1, 5), (2, 5), (3, 5), (4, 5)]
|
|
self.uid = uuid4()
|
|
self.coordinates = (29.9792, 31.1342)
|
|
"""
|
|
try:
|
|
for key in ('port_mapping', 'direction', 'coordinates', 'name',
|
|
'description', 'manufacturer', 'model', 'sn', 'id'):
|
|
if key in kwargs:
|
|
setattr(self, key, kwargs[key])
|
|
else:
|
|
setattr(self, key, None)
|
|
# print('No Value defined for :', key)
|
|
# TODO: add logging functionality
|
|
except KeyError as e:
|
|
if 'name' in kwargs:
|
|
s = kwargs['name']
|
|
print('Missing Required Network Element Key!', 'name:=', s)
|
|
# TODO Put log here instead of print
|
|
print(e)
|
|
raise
|
|
|
|
def get_output_ports(self):
|
|
"""Translate the port mapping into list of output ports
|
|
"""
|
|
return None
|
|
|
|
def get_input_ports(self):
|
|
"""Translate the port mapping into list of output ports
|
|
"""
|
|
return None
|
|
|
|
def __repr__(self):
|
|
return self.__class__.__name__
|
|
|
|
|
|
class Edfa(NetworkElement):
|
|
|
|
def __init__(self, **kwargs):
|
|
'''Reads in configuration data checking for keys. Sets those attributes
|
|
for each element that exists.
|
|
conventions:
|
|
units are SI except where noted below (meters, seconds, Hz)
|
|
rbw=12.5 GHz today.
|
|
TODO add unit checking so inputs can be added in conventional
|
|
nm units.
|
|
nfdB = noise figure in dB units
|
|
psatdB = saturation power in dB units
|
|
gaindB = gain in dB units
|
|
pdgdB = polarization dependent gain in dB
|
|
rippledB = gain ripple in dB
|
|
'''
|
|
try:
|
|
for key in ('gaindB', 'nfdB', 'psatdB', 'rbw', 'wavelengths',
|
|
'pdgdB', 'rippledB', 'id', 'node', 'location'):
|
|
if key in kwargs:
|
|
setattr(self, key, kwargs[key])
|
|
elif 'id' in kwargs is None:
|
|
setattr(self, 'id', Edfa.class_counter)
|
|
else:
|
|
setattr(self, key, None)
|
|
print('No Value defined for :', key)
|
|
self.pas = [(h*c/ll)*self.rbw*1e9 for ll in self.wavelengths]
|
|
|
|
except KeyError as e:
|
|
if 'name' in kwargs:
|
|
s = kwargs['name']
|
|
print('Missing Edfa Input Key!', 'name:=', s)
|
|
print(e)
|
|
raise
|
|
|
|
|
|
class Fiber(NetworkElement):
|
|
class_counter = 0
|
|
|
|
def __init__(self, **kwargs):
|
|
""" Reads in configuration data checking for keys. Sets those
|
|
attributes for each element that exists.
|
|
conventions:
|
|
units are SI (meters, seconds, Hz) except where noted below
|
|
rbw=12.5 GHz today. TODO add unit checking so inputs can be added
|
|
in conventional nm units.
|
|
nf_db = noise figure in dB units
|
|
psat_db = saturation power in dB units
|
|
gain_db = gain in dB units
|
|
pdg_db = polarization dependent gain in dB
|
|
ripple_db = gain ripple in dB
|
|
"""
|
|
try:
|
|
for key in ('fiber_type', 'attenuationdB', 'span_length',
|
|
'dispersion', 'wavelengths', 'id', 'name', 'location',
|
|
'direction', 'launch_power', 'rbw'):
|
|
if key in kwargs:
|
|
setattr(self, key, kwargs[key])
|
|
elif 'id' in kwargs is None:
|
|
setattr(self, 'id', Span.class_counter)
|
|
Span.class_counter += 1
|
|
else:
|
|
setattr(self, key, None)
|
|
print('No Value defined for :', key)
|
|
except KeyError as e:
|
|
if 'name' in kwargs:
|
|
s = kwargs['name']
|
|
print('Missing Span Input Key!', 'name:=', s)
|
|
print(e)
|
|
raise
|
|
|
|
def effective_length(self, loss_coef):
|
|
alpha_dict = self.dbkm_2_lin(loss_coef)
|
|
alpha = alpha_dict['alpha_acoef']
|
|
leff = 1 - np.exp(-2 * alpha * self.span_length)
|
|
return leff
|
|
|
|
def asymptotic_length(self, loss_coef):
|
|
alpha_dict = self.dbkm_2_lin(loss_coef)
|
|
alpha = alpha_dict['alpha_acoef']
|
|
aleff = 1/(2 * alpha)
|
|
return aleff
|
|
|
|
|
|
|
|
def beta2(self, dispersion, ref_wavelength=None):
|
|
""" Returns beta2 from dispersion parameter. Dispersion is entered in
|
|
ps/nm/km. Disperion can be a numpy array or a single value. If a
|
|
value ref_wavelength is not entered 1550e-9m will be assumed.
|
|
ref_wavelength can be a numpy array.
|
|
"""
|
|
if ref_wavelength is None:
|
|
ref_wavelength = 1550e-9
|
|
wl = ref_wavelength
|
|
D = np.abs(dispersion)
|
|
b2 = (10**21) * (wl**2) * D / (2 * np.pi * c)
|
|
# 10^21 scales to ps^2/km
|
|
return b2
|
|
|
|
# TODO
|
|
def generic_span(self):
|
|
""" calculates a generic version that shows how all the functions of
|
|
the class are used. It makes the following assumptions about the span:
|
|
"""
|
|
return
|
|
|
|
def __repr__(self):
|
|
return f'{self.__class__.__name__}({self.span_length}km)'
|