mirror of
https://github.com/Telecominfraproject/oopt-gnpy.git
synced 2025-11-02 19:18:02 +00:00
power mode no longer reads operational_gain: now reads operational.dp_db or calculate optimum dp_db from next span loss gain_mode: reads operational.gain_target or use gain_from_dp Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com> squash to dp Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
97 lines
3.3 KiB
Python
97 lines
3.3 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
'''
|
|
gnpy.core.info
|
|
==============
|
|
|
|
This module contains classes for modelling SpectralInformation.
|
|
'''
|
|
|
|
|
|
from collections import namedtuple
|
|
from numpy import array
|
|
from gnpy.core.utils import lin2db, db2lin
|
|
from json import loads
|
|
from gnpy.core.utils import load_json
|
|
from gnpy.core.equipment import automatic_nch, automatic_spacing
|
|
|
|
class ConvenienceAccess:
|
|
|
|
def __init_subclass__(cls):
|
|
for abbrev, field in getattr(cls, '_ABBREVS', {}).items():
|
|
setattr(cls, abbrev, property(lambda self, f=field: getattr(self, f)))
|
|
|
|
def update(self, **kwargs):
|
|
for abbrev, field in getattr(self, '_ABBREVS', {}).items():
|
|
if abbrev in kwargs:
|
|
kwargs[field] = kwargs.pop(abbrev)
|
|
return self._replace(**kwargs)
|
|
|
|
|
|
class Power(namedtuple('Power', 'signal nonlinear_interference amplified_spontaneous_emission'), ConvenienceAccess):
|
|
"""carriers power in W"""
|
|
_ABBREVS = {'nli': 'nonlinear_interference',
|
|
'ase': 'amplified_spontaneous_emission',}
|
|
|
|
|
|
class Channel(namedtuple('Channel', 'channel_number frequency baud_rate roll_off power'), ConvenienceAccess):
|
|
|
|
_ABBREVS = {'channel': 'channel_number',
|
|
'num_chan': 'channel_number',
|
|
'ffs': 'frequency',
|
|
'freq': 'frequency',}
|
|
|
|
class Pref(namedtuple('Pref', 'p_span0, p_spani, neq_ch '), ConvenienceAccess):
|
|
"""noiseless reference power in dBm:
|
|
p0: inital target carrier power
|
|
pi: carrier power after element i
|
|
neqch: equivalent channel count in dB"""
|
|
|
|
_ABBREVS = {'p0' : 'p_span0',
|
|
'pi' : 'p_spani'}
|
|
|
|
class SpectralInformation(namedtuple('SpectralInformation', 'pref carriers'), ConvenienceAccess):
|
|
|
|
def __new__(cls, pref, carriers):
|
|
return super().__new__(cls, pref, carriers)
|
|
|
|
def merge_input_spectral_information(*si):
|
|
"""mix channel combs of different baud rates and power"""
|
|
#TODO
|
|
pass
|
|
|
|
def create_input_spectral_information(f_min, f_max, roll_off, baud_rate, power, spacing):
|
|
# pref in dB : convert power lin into power in dB
|
|
pref = lin2db(power * 1e3)
|
|
nb_channel = automatic_nch(f_min, f_max, spacing)
|
|
si = SpectralInformation(
|
|
pref=Pref(pref, pref, lin2db(nb_channel)),
|
|
carriers=[
|
|
Channel(f, (f_min+spacing*f),
|
|
baud_rate, roll_off, Power(power, 0, 0)) for f in range(1,nb_channel+1)
|
|
])
|
|
return si
|
|
|
|
if __name__ == '__main__':
|
|
pref = lin2db(power * 1e3)
|
|
si = SpectralInformation(
|
|
Pref(pref, pref),
|
|
Channel(1, 193.95e12, 32e9, 0.15, # 193.95 THz, 32 Gbaud
|
|
Power(1e-3, 1e-6, 1e-6)), # 1 mW, 1uW, 1uW
|
|
Channel(1, 195.95e12, 32e9, 0.15, # 195.95 THz, 32 Gbaud
|
|
Power(1.2e-3, 1e-6, 1e-6)), # 1.2 mW, 1uW, 1uW
|
|
)
|
|
|
|
si = SpectralInformation()
|
|
spacing = 0.05 # THz
|
|
|
|
si = si.update(carriers=tuple(Channel(f+1, 191.3+spacing*(f+1), 32e9, 0.15, Power(1e-3, f, 1)) for f in range(96)))
|
|
|
|
print(f'si = {si}')
|
|
print(f'si = {si.carriers[0].power.nli}')
|
|
print(f'si = {si.carriers[20].power.nli}')
|
|
si2 = si.update(carriers=tuple(c.update(power = c.power.update(nli = c.power.nli * 1e5))
|
|
for c in si.carriers))
|
|
print(f'si2 = {si2}')
|