mirror of
https://github.com/Telecominfraproject/oopt-gnpy.git
synced 2025-10-31 18:18:00 +00:00
Develop (#14)
* adding rrc filter, temporarily putting it in utilities.py * added some docstring stuff * added a simple loss class for fiber and cleaned up some duplicate convenience access properties * Changed Carrier to Channel to reflect correct nomenclature for multi-carrier/superchannels * in process fixes for main.py. adding in amp spacings and spans to convert to start adding additional noded to Coronet network * some simple additions to utilites * adding stand alone edfa model
This commit is contained in:
@@ -10,6 +10,17 @@ from networkx import (draw_networkx_nodes, draw_networkx_edges,
|
||||
|
||||
from . import network_from_json
|
||||
from .elements import Transceiver, Fiber
|
||||
from .info import SpectralInformation, Channel, Power
|
||||
from .algorithms import closed_paths
|
||||
|
||||
logger = getLogger(__package__ or __file__)
|
||||
|
||||
def format_si(spectral_infos):
|
||||
return '\n'.join([
|
||||
f'#{idx} Carrier(frequency={c.frequency},\n power=Power(signal={c.power.signal}, nli={c.power.nli}, ase={c.power.ase}))'
|
||||
for idx, si in sorted(set(spectral_infos))
|
||||
for c in set(si.carriers)
|
||||
])
|
||||
|
||||
logger = getLogger('gnpy.core')
|
||||
|
||||
@@ -25,9 +36,38 @@ def main(args):
|
||||
for n in network.nodes()]
|
||||
labels = {n: n.location.city if isinstance(n, Transceiver) else ''
|
||||
for n in network.nodes()}
|
||||
draw_networkx_nodes(network, pos=pos, node_size=size, node_color=color)
|
||||
draw_networkx_edges(network, pos=pos)
|
||||
draw_networkx_labels(network, pos=labels_pos, labels=labels, font_size=14)
|
||||
|
||||
si = SpectralInformation(
|
||||
Channel(1, 193.95e12, '16-qam', 32e9, 0, # 193.95 THz, 32 Gbaud
|
||||
Power(1e-3, 1e-6, 1e-6)), # 1 mW, 1uW, 1uW
|
||||
Channel(1, 195.95e12, '16-qam', 32e9, 0, # 195.95 THz, 32 Gbaud
|
||||
Power(1.2e-3, 1e-6, 1e-6)), # 1.2 mW, 1uW, 1uW
|
||||
)
|
||||
|
||||
nodes = [n for n in network.nodes() if isinstance(n, Transceiver)]
|
||||
source, sink = choice(nodes), choice(nodes)
|
||||
|
||||
results = list(islice(closed_paths(network, source, sink, si), 3))
|
||||
paths = [[n for _, n, _ in r] for r in results]
|
||||
infos = {}
|
||||
for idx, r in enumerate(results):
|
||||
for in_si, node, out_si in r:
|
||||
infos.setdefault(node, []).append((idx, out_si))
|
||||
|
||||
node_color = ['#ff0000' if n is source or n is sink else
|
||||
'#900000' if any(n in p for p in paths) else
|
||||
'#ffdede' if isinstance(n, Transceiver) else '#dedeff'
|
||||
for n in network.nodes()]
|
||||
edge_color = ['#ff9090' if any(u in p for p in paths) and
|
||||
any(v in p for p in paths) else '#dedede'
|
||||
for u, v in network.edges()]
|
||||
|
||||
fig = figure()
|
||||
plot = draw_networkx_nodes(network, pos=pos, node_size=size, node_color=node_color, figure=fig)
|
||||
draw_networkx_edges(network, pos=pos, figure=fig, edge_color=edge_color)
|
||||
draw_networkx_labels(network, pos=labels_pos, labels=labels, font_size=14, figure=fig)
|
||||
|
||||
title(f'Propagating from {source.loc.city} to {sink.loc.city}')
|
||||
axis('off')
|
||||
show()
|
||||
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from core.node import Node
|
||||
from core.units import UNITS
|
||||
import numpy as np
|
||||
from scipy.constants import c
|
||||
|
||||
|
||||
# network elements
|
||||
|
||||
class Transceiver(Node):
|
||||
def __init__(self, config):
|
||||
super().__init__(config)
|
||||
@@ -11,7 +14,6 @@ class Transceiver(Node):
|
||||
def __call__(self, spectral_info):
|
||||
return spectral_info
|
||||
|
||||
|
||||
class Fiber(Node):
|
||||
def __init__(self, config):
|
||||
super().__init__(config)
|
||||
@@ -21,6 +23,51 @@ class Fiber(Node):
|
||||
def __repr__(self):
|
||||
return f'{type(self).__name__}(uid={self.uid}, length={self.length})'
|
||||
|
||||
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 dbkm_2_lin(self, loss_coef):
|
||||
""" calculates the linear loss coefficient
|
||||
"""
|
||||
alpha_pcoef = loss_coef
|
||||
alpha_acoef = alpha_pcoef/(2*4.3429448190325184)
|
||||
s = 'alpha_pcoef is linear loss coefficient in [dB/km^-1] units'
|
||||
s = ''.join([s, "alpha_acoef is linear loss field amplitude \
|
||||
coefficient in [km^-1] units"])
|
||||
d = {'alpha_pcoef': alpha_pcoef, 'alpha_acoef': alpha_acoef,
|
||||
'description:': s}
|
||||
return d
|
||||
|
||||
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
|
||||
|
||||
# convenience access
|
||||
loss = property(lambda self: self.loss_.value)
|
||||
length = property(lambda self: self.length_.value)
|
||||
loc = property(lambda self: self.location)
|
||||
lat = property(lambda self: self.location.latitude)
|
||||
long = property(lambda self: self.location.longitude)
|
||||
|
||||
def propagate(self, *carriers):
|
||||
for carrier in carriers:
|
||||
power = carrier.power
|
||||
@@ -32,3 +79,4 @@ class Fiber(Node):
|
||||
def __call__(self, spectral_info):
|
||||
carriers = tuple(self.propagate(*spectral_info.carriers))
|
||||
return spectral_info.update(carriers=carriers)
|
||||
|
||||
|
||||
42
core/info.py
Normal file
42
core/info.py
Normal file
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
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):
|
||||
_ABBREVS = {'nli': 'nonlinear_interference',
|
||||
'ase': 'amplified_spontaneous_emission',}
|
||||
|
||||
class Channel(namedtuple('Channel', 'channel_number frequency modulation baud_rate alpha power'), ConvenienceAccess):
|
||||
_ABBREVS = {'channel': 'channel_number',
|
||||
'num_chan': 'channel_number',
|
||||
'num_carriers': 'num_carriers',
|
||||
'ffs': 'frequency',
|
||||
'freq': 'frequency',}
|
||||
|
||||
class SpectralInformation(namedtuple('SpectralInformation', 'carriers'), ConvenienceAccess):
|
||||
def __new__(cls, *carriers):
|
||||
return super().__new__(cls, carriers)
|
||||
|
||||
if __name__ == '__main__':
|
||||
si = SpectralInformation(
|
||||
Channel(1, 193.95e12, '16-qam', 32e9, 0, # 193.95 THz, 32 Gbaud
|
||||
Power(1e-3, 1e-6, 1e-6)), # 1 mW, 1uW, 1uW
|
||||
Channel(1, 195.95e12, '16-qam', 32e9, 0, # 195.95 THz, 32 Gbaud
|
||||
Power(1.2e-3, 1e-6, 1e-6)), # 1.2 mW, 1uW, 1uW
|
||||
)
|
||||
print(f'si = {si}')
|
||||
print(f'si = {si.carriers[0].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}')
|
||||
@@ -10,12 +10,36 @@ from collections import namedtuple, Counter
|
||||
from itertools import chain
|
||||
from json import dumps
|
||||
from uuid import uuid4
|
||||
import math
|
||||
import numpy as np
|
||||
|
||||
Node = namedtuple('Node', 'city state country region latitude longitude')
|
||||
class Link(namedtuple('Link', 'from_city to_city distance distance_units')):
|
||||
def __new__(cls, from_city, to_city, distance, distance_units='km'):
|
||||
return super().__new__(cls, from_city, to_city, distance, distance_units)
|
||||
|
||||
def define_span_range(min_span, max_span, nspans):
|
||||
srange = (max_span - min_span) + min_span*np.random.rand(nspans)
|
||||
return srange
|
||||
|
||||
def amp_spacings(min_span,max_span,length):
|
||||
nspans = math.ceil(length/100)
|
||||
spans = define_span_range(min_span, max_span, nspans)
|
||||
tot = spans.sum()
|
||||
delta = length -tot
|
||||
if delta > 0 and delta < 25:
|
||||
ind = np.where(np.min(spans))
|
||||
spans[ind] = spans[ind] + delta
|
||||
elif delta >= 25 and delta < 40:
|
||||
spans = spans + delta/float(nspans)
|
||||
elif delta > 40 and delta < 100:
|
||||
spans = np.append(spans,delta)
|
||||
elif delta > 100:
|
||||
spans = np.append(spans, [delta/2, delta/2])
|
||||
elif delta < 0:
|
||||
spans = spans + delta/float(nspans)
|
||||
return list(spans)
|
||||
|
||||
def parse_excel(args):
|
||||
with open_workbook(args.workbook) as wb:
|
||||
nodes_sheet = wb.sheet_by_name('Nodes')
|
||||
|
||||
1
examples/edfa_model/DFG_96.txt
Executable file
1
examples/edfa_model/DFG_96.txt
Executable file
@@ -0,0 +1 @@
|
||||
2.5135969849999999e+01 2.5118228139999999e+01 2.5095421330000001e+01 2.5062457710000000e+01 2.5026027650000000e+01 2.4996379529999999e+01 2.4981672549999999e+01 2.4975306679999999e+01 2.4983207260000000e+01 2.4997185649999999e+01 2.5017572470000001e+01 2.5038327809999998e+01 2.5054955849999999e+01 2.5067071899999998e+01 2.5070914110000000e+01 2.5070943650000000e+01 2.5071143240000001e+01 2.5075336270000001e+01 2.5087310179999999e+01 2.5103139360000000e+01 2.5122762040000001e+01 2.5142394790000001e+01 2.5159456330000001e+01 2.5173927039999999e+01 2.5176737670000001e+01 2.5170371410000001e+01 2.5152162539999999e+01 2.5131143099999999e+01 2.5108023350000000e+01 2.5085487770000000e+01 2.5069166750000001e+01 2.5058481759999999e+01 2.5054473130000002e+01 2.5051544410000002e+01 2.5049460589999999e+01 2.5047178490000000e+01 2.5045516559999999e+01 2.5044676490000001e+01 2.5040729200000001e+01 2.5032854080000000e+01 2.5023488300000000e+01 2.5016592339999999e+01 2.5013321359999999e+01 2.5011234340000001e+01 2.5010300149999999e+01 2.5009365480000000e+01 2.5008739640000002e+01 2.5008425350000000e+01 2.5006964660000001e+01 2.5004043100000001e+01 2.5000709980000000e+01 2.4998423200000001e+01 2.4993063320000001e+01 2.4983524209999999e+01 2.4971251030000001e+01 2.4960381080000001e+01 2.4948887209999999e+01 2.4935314890000001e+01 2.4921319270000001e+01 2.4908986970000001e+01 2.4898965140000001e+01 2.4889584630000002e+01 2.4880838700000002e+01 2.4872100920000001e+01 2.4864620259999999e+01 2.4858397730000000e+01 2.4854458380000001e+01 2.4851554430000000e+01 2.4851766009999999e+01 2.4854080140000001e+01 2.4859096240000000e+01 2.4864744580000000e+01 2.4872034859999999e+01 2.4880365200000000e+01 2.4889106689999998e+01 2.4897213130000001e+01 2.4902826040000001e+01 2.4906566900000001e+01 2.4908650800000000e+01 2.4910939440000000e+01 2.4913430790000000e+01 2.4915923440000000e+01 2.4921553509999999e+01 2.4930318610000000e+01 2.4940528120000000e+01 2.4949046689999999e+01 2.4957571229999999e+01 2.4967818449999999e+01 2.4981800929999999e+01 2.4997826860000000e+01 2.5013931830000001e+01 2.5028098459999999e+01 2.5040325750000001e+01 2.5052569810000001e+01 2.5064797009999999e+01 2.5077046970000001e+01
|
||||
1
examples/edfa_model/DGT_96.txt
Executable file
1
examples/edfa_model/DGT_96.txt
Executable file
@@ -0,0 +1 @@
|
||||
2.7145266811316859e+00 2.7054438192385049e+00 2.6947834587664494e+00 2.6841217449620203e+00 2.6681935771243177e+00 2.6521732021128046e+00 2.6303964408153848e+00 2.6028603502864280e+00 2.5696460593920065e+00 2.5364027376452056e+00 2.4994462867966041e+00 2.4587748041127506e+00 2.4143984371852212e+00 2.3699990328716107e+00 2.3223736962293420e+00 2.2715207713712529e+00 2.2174389328192197e+00 2.1633756538423898e+00 2.1183028432496016e+00 2.0822250998736478e+00 2.0551007720052352e+00 2.0279625371819305e+00 2.0008103857988204e+00 1.9736443063300082e+00 1.9482128147680253e+00 1.9245345552113182e+00 1.9026104247588487e+00 1.8806927939516411e+00 1.8622356724442459e+00 1.8472755032011290e+00 1.8358140813807049e+00 1.8243814368429321e+00 1.8139629377087627e+00 1.8045606557581335e+00 1.7961751115773796e+00 1.7877868031023945e+00 1.7793941781790852e+00 1.7709972329654864e+00 1.7625959636196327e+00 1.7541903672600494e+00 1.7459181197626403e+00 1.7377807579136351e+00 1.7297783508684146e+00 1.7217732861435076e+00 1.7137640932265894e+00 1.7057507692361864e+00 1.6918150918099673e+00 1.6719047669939942e+00 1.6460167077689267e+00 1.6201194134191075e+00 1.5986915141218316e+00 1.5817353179379183e+00 1.5691997641843789e+00 1.5566577309558969e+00 1.5453741527614671e+00 1.5353620432989845e+00 1.5266220576235803e+00 1.5178910621476225e+00 1.5097346239790443e+00 1.5021530399096861e+00 1.4951454560626991e+00 1.4881342434792260e+00 1.4811193973568100e+00 1.4741004422522110e+00 1.4670307626366115e+00 1.4599103316162523e+00 1.4527395948591399e+00 1.4455651371583680e+00 1.4340878115214444e+00 1.4182738067303231e+00 1.3981208704326855e+00 1.3779439775587023e+00 1.3598972673004606e+00 1.3439818461440451e+00 1.3301807335621048e+00 1.3163839268630830e+00 1.3040618749785347e+00 1.2932153453410835e+00 1.2838336236692311e+00 1.2744470198196236e+00 1.2650555289898042e+00 1.2556591482982988e+00 1.2428104897182262e+00 1.2264996957264114e+00 1.2067249615595257e+00 1.1869318618366975e+00 1.1672278304018044e+00 1.1476135933863398e+00 1.1280891949729075e+00 1.1085552896156590e+00 1.0895983485572227e+00 1.0712204022764056e+00 1.0534217504465226e+00 1.0356155337864215e+00 1.0178077678537021e+00 1.0000000000000000e+00
|
||||
1
examples/edfa_model/NFR_96.txt
Executable file
1
examples/edfa_model/NFR_96.txt
Executable file
@@ -0,0 +1 @@
|
||||
-3.1537433199999998e-01 -3.1537433199999998e-01 -3.1540091571002721e-01 -3.1849146117510951e-01 -3.2158358425400546e-01 -3.2467728615499991e-01 -3.2762368641496226e-01 -3.2054138461232762e-01 -3.1345546385118733e-01 -3.0636592135697482e-01 -2.9920267890990127e-01 -2.7061972852631744e-01 -2.4202215770774693e-01 -2.1340995523361256e-01 -1.8478227130158695e-01 -1.4809761118389625e-01 -1.1139416731807622e-01 -7.4671925273579881e-02 -3.8026748965679924e-02 -1.9958469399422092e-02 -1.8809287980157928e-03 1.6205879960573561e-02 3.4301964005709673e-02 5.2407330474054062e-02 7.0521986509597359e-02 7.9578036683472006e-02 8.8546647361909522e-02 9.7519863231965306e-02 1.0649768784154924e-01 9.7741380449907406e-02 8.8803437172660038e-02 7.9860899732845866e-02 7.0913764587403796e-02 6.3335892740565308e-02 5.5756212252058776e-02 4.8172631747863209e-02 4.0585148217162359e-02 3.3381591675710129e-02 2.6178308595650738e-02 1.8971315351761126e-02 1.1760609076833628e-02 1.6950294922759991e-02 2.2274991357701439e-02 2.7602433189104329e-02 3.2932622540790261e-02 3.8265561538776145e-02 4.3601252311271169e-02 3.4856990743481552e-02 2.5991055149117932e-02 1.7120541224980364e-02 8.2757587359203223e-03 1.9423214065246042e-03 -4.3943890171043590e-03 -1.0734375072893196e-02 -1.7077639301414434e-02 -2.4679702899572852e-02 -3.2297970403821680e-02 -3.9920180090477250e-02 -4.7534566327530239e-02 -4.9234003141433724e-02 -5.0934320036547187e-02 -5.2635517696692252e-02 -5.4337596806402461e-02 -5.6040558050919301e-02 -5.7718452237076875e-02 -5.6840590379175944e-02 -5.5962273198734966e-02 -5.5083500341416583e-02 -5.4204271452516814e-02 -5.8396088726955113e-02 -6.2627330169715334e-02 -6.6860769089203700e-02 -7.0901736256069450e-02 -5.2096097309052243e-02 -3.3280684121412940e-02 -1.4455489070928059e-02 4.3150387579057158e-03 1.4839202394482527e-02 2.5368841662503576e-02 3.5903960836465652e-02 4.6444564195321399e-02 5.6990656022467459e-02 6.7542240605774059e-02 1.0002709623672751e-01 1.3258013095133617e-01 1.6515013362773309e-01 1.9773711753599391e-01 2.3194802687829724e-01 2.6618779883837107e-01 3.0044543658085349e-01 3.3472095409250663e-01 3.5929034770587287e-01 3.8384389188855605e-01 4.0841026111391787e-01 4.3298946543290784e-01 4.3298946543290784e-01
|
||||
8
examples/edfa_model/Pchan2D.txt
Executable file
8
examples/edfa_model/Pchan2D.txt
Executable file
@@ -0,0 +1,8 @@
|
||||
-1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01
|
||||
-2.0000000000000000e+01 -2.0000000000000000e+01 -2.0000000000000000e+01 -2.0000000000000000e+01 -2.0000000000000000e+01 -2.0000000000000000e+01 -2.0000000000000000e+01 -2.0000000000000000e+01 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02
|
||||
-1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -2.0000000000000000e+01 -2.0000000000000000e+01 -2.0000000000000000e+01 -2.0000000000000000e+01 -2.0000000000000000e+01 -2.0000000000000000e+01 -2.0000000000000000e+01 -2.0000000000000000e+01
|
||||
-2.0500000000000000e+01 -2.0489473680000000e+01 -2.0478947370000000e+01 -2.0468421050000000e+01 -2.0457894740000000e+01 -2.0447368420000000e+01 -2.0436842110000001e+01 -2.0426315790000000e+01 -2.0415789470000000e+01 -2.0405263160000001e+01 -2.0394736840000000e+01 -2.0384210530000001e+01 -2.0373684210000000e+01 -2.0363157890000000e+01 -2.0352631580000001e+01 -2.0342105260000000e+01 -2.0331578950000001e+01 -2.0321052630000001e+01 -2.0310526320000001e+01 -2.0300000000000001e+01 -2.0289473680000000e+01 -2.0278947370000001e+01 -2.0268421050000001e+01 -2.0257894740000001e+01 -2.0247368420000001e+01 -2.0236842110000001e+01 -2.0226315790000001e+01 -2.0215789470000001e+01 -2.0205263160000001e+01 -2.0194736840000001e+01 -2.0184210530000001e+01 -2.0173684210000001e+01 -2.0163157890000001e+01 -2.0152631580000001e+01 -2.0142105260000001e+01 -2.0131578950000002e+01 -2.0121052630000001e+01 -2.0110526320000002e+01 -2.0100000000000001e+01 -2.0089473680000001e+01 -2.0078947370000002e+01 -2.0068421050000001e+01 -2.0057894739999998e+01 -2.0047368420000002e+01 -2.0036842109999998e+01 -2.0026315790000002e+01 -2.0015789470000001e+01 -2.0005263159999998e+01 -1.9994736840000002e+01 -1.9984210529999999e+01 -1.9973684209999998e+01 -1.9963157890000002e+01 -1.9952631579999998e+01 -1.9942105260000002e+01 -1.9931578949999999e+01 -1.9921052629999998e+01 -1.9910526319999999e+01 -1.9899999999999999e+01 -1.9889473679999998e+01 -1.9878947369999999e+01 -1.9868421049999998e+01 -1.9857894739999999e+01 -1.9847368419999999e+01 -1.9836842109999999e+01 -1.9826315789999999e+01 -1.9815789469999999e+01 -1.9805263159999999e+01 -1.9794736839999999e+01 -1.9784210529999999e+01 -1.9773684209999999e+01 -1.9763157889999999e+01 -1.9752631579999999e+01 -1.9742105259999999e+01 -1.9731578949999999e+01 -1.9721052629999999e+01 -1.9710526320000000e+01 -1.9699999999999999e+01 -1.9689473679999999e+01 -1.9678947369999999e+01 -1.9668421049999999e+01 -1.9657894740000000e+01 -1.9647368419999999e+01 -1.9636842110000000e+01 -1.9626315790000000e+01 -1.9615789469999999e+01 -1.9605263160000000e+01 -1.9594736839999999e+01 -1.9584210530000000e+01 -1.9573684210000000e+01 -1.9563157889999999e+01 -1.9552631580000000e+01 -1.9542105260000000e+01 -1.9531578950000000e+01 -1.9521052630000000e+01 -1.9510526320000000e+01 -1.9500000000000000e+01
|
||||
-2.0500000000000000e+01 -2.0489473680000000e+01 -2.0478947370000000e+01 -2.0468421050000000e+01 -2.0457894740000000e+01 -2.0447368420000000e+01 -2.0436842110000001e+01 -2.0426315790000000e+01 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.9573684210000000e+01 -1.9563157889999999e+01 -1.9552631580000000e+01 -1.9542105260000000e+01 -1.9531578950000000e+01 -1.9521052630000000e+01 -1.9510526320000000e+01 -1.9500000000000000e+01
|
||||
-1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.4460000000000001e+01
|
||||
-1.4460000000000001e+01 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01 -1.4460000000000001e+01
|
||||
-1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.4460000000000001e+01 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02 -1.0000000000000000e+02
|
||||
8
examples/edfa_model/Pchan2DLegend.txt
Executable file
8
examples/edfa_model/Pchan2DLegend.txt
Executable file
@@ -0,0 +1,8 @@
|
||||
7.0000000000000000e+01 1.1700000000000000e+02 1.0800000000000000e+02 1.0800000000000000e+02 3.2000000000000000e+01 7.0000000000000000e+01 1.0800000000000000e+02 9.7000000000000000e+01 1.1600000000000000e+02 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01
|
||||
7.9000000000000000e+01 1.1000000000000000e+02 1.0100000000000000e+02 3.2000000000000000e+01 7.1000000000000000e+01 1.1400000000000000e+02 1.1100000000000000e+02 1.1700000000000000e+02 1.1200000000000000e+02 3.2000000000000000e+01 6.6000000000000000e+01 1.0800000000000000e+02 1.1700000000000000e+02 1.0100000000000000e+02 3.2000000000000000e+01
|
||||
7.9000000000000000e+01 1.1000000000000000e+02 1.0100000000000000e+02 3.2000000000000000e+01 7.1000000000000000e+01 1.1400000000000000e+02 1.1100000000000000e+02 1.1700000000000000e+02 1.1200000000000000e+02 3.2000000000000000e+01 8.2000000000000000e+01 1.0100000000000000e+02 1.0000000000000000e+02 3.2000000000000000e+01 3.2000000000000000e+01
|
||||
7.0000000000000000e+01 1.1700000000000000e+02 1.0800000000000000e+02 1.0800000000000000e+02 3.2000000000000000e+01 1.1900000000000000e+02 3.2000000000000000e+01 8.3000000000000000e+01 8.2000000000000000e+01 8.3000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01
|
||||
6.6000000000000000e+01 1.1100000000000000e+02 1.1600000000000000e+02 1.0400000000000000e+02 3.2000000000000000e+01 6.9000000000000000e+01 1.1000000000000000e+02 1.0000000000000000e+02 1.1500000000000000e+02 3.2000000000000000e+01 1.1900000000000000e+02 3.2000000000000000e+01 8.3000000000000000e+01 8.2000000000000000e+01 8.3000000000000000e+01
|
||||
1.0400000000000000e+02 1.0100000000000000e+02 9.7000000000000000e+01 1.1800000000000000e+02 1.2100000000000000e+02 3.2000000000000000e+01 9.8000000000000000e+01 1.0800000000000000e+02 1.1700000000000000e+02 1.0100000000000000e+02 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01
|
||||
1.0400000000000000e+02 1.0100000000000000e+02 9.7000000000000000e+01 1.1800000000000000e+02 1.2100000000000000e+02 3.2000000000000000e+01 1.1400000000000000e+02 1.0100000000000000e+02 1.0000000000000000e+02 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01
|
||||
1.1900000000000000e+02 1.1100000000000000e+02 1.1400000000000000e+02 1.1500000000000000e+02 1.1600000000000000e+02 3.2000000000000000e+01 9.9000000000000000e+01 9.7000000000000000e+01 1.1500000000000000e+02 1.0100000000000000e+02 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01 3.2000000000000000e+01
|
||||
300
examples/edfa_model/amplifier.py
Normal file
300
examples/edfa_model/amplifier.py
Normal file
@@ -0,0 +1,300 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Mon Nov 27 12:32:04 2017
|
||||
|
||||
@author: briantaylor
|
||||
"""
|
||||
import numpy as np
|
||||
from numpy import polyfit, polyval, mean
|
||||
from utilities import lin2db, db2lin, itufs, freq2wavelength
|
||||
import matplotlib.pyplot as plt
|
||||
from scipy.constants import h
|
||||
|
||||
|
||||
def noise_profile(nf, gain, ffs, df):
|
||||
""" noise_profile(nf, gain, ffs, df) computes amplifier ase
|
||||
|
||||
:param nf: Noise figure in dB
|
||||
:param gain: Actual gain calculated for the EDFA in dB units
|
||||
:param ffs: A numpy array of frequencies
|
||||
:param df: the reference bw in THz
|
||||
:type nf: numpy.ndarray
|
||||
:type gain: numpy.ndarray
|
||||
:type ffs: numpy.ndarray
|
||||
:type df: float
|
||||
:return: the asepower in dBm
|
||||
:rtype: numpy.ndarray
|
||||
|
||||
ASE POWER USING PER CHANNEL GAIN PROFILE
|
||||
INPUTS:
|
||||
NF_dB - Noise figure in dB, vector of length number of channels or
|
||||
spectral slices
|
||||
G_dB - Actual gain calculated for the EDFA, vector of length number of
|
||||
channels or spectral slices
|
||||
ffs - Center frequency grid of the channels or spectral slices in THz,
|
||||
vector of length number of channels or spectral slices
|
||||
dF - width of each channel or spectral slice in THz,
|
||||
vector of length number of channels or spectral slices
|
||||
OUTPUT:
|
||||
ase_dBm - ase in dBm per channel or spectral slice
|
||||
NOTE: the output is the total ASE in the channel or spectral slice. For
|
||||
50GHz channels the ASE BW is effectively 0.4nm. To get to noise power in
|
||||
0.1nm, subtract 6dB.
|
||||
|
||||
ONSR is usually quoted as channel power divided by
|
||||
the ASE power in 0.1nm RBW, regardless of the width of the actual
|
||||
channel. This is a historical convention from the days when optical
|
||||
signals were much smaller (155Mbps, 2.5Gbps, ... 10Gbps) than the
|
||||
resolution of the OSAs that were used to measure spectral power which
|
||||
were set to 0.1nm resolution for convenience. Moving forward into
|
||||
flexible grid and high baud rate signals, it may be convenient to begin
|
||||
quoting power spectral density in the same BW for both signal and ASE,
|
||||
e.g. 12.5GHz."""
|
||||
|
||||
h_mWThz = 1e-3*h*(1e14)**2
|
||||
nf_lin = db2lin(nf)
|
||||
g_lin = db2lin(gain)
|
||||
ase = h_mWThz*df*ffs*(nf_lin*g_lin - 1)
|
||||
asedb = lin2db(ase)
|
||||
|
||||
return asedb
|
||||
|
||||
|
||||
def gain_profile(dfg, dgt, Pin , gp , gtp):
|
||||
"""
|
||||
:param dfg: design flat gain
|
||||
:param dgt: design gain tilt
|
||||
:param Pin: channing input power profile
|
||||
:param gp: Average gain setpoint in dB units
|
||||
:param gtp: gain tilt setting
|
||||
:type dfg: numpy.ndarray
|
||||
:type dgt: numpy.ndarray
|
||||
:type Pin: numpy.ndarray
|
||||
:type gp: float
|
||||
:type gtp: float
|
||||
:return: gain profile in dBm
|
||||
:rtype: numpy.ndarray
|
||||
|
||||
AMPLIFICATION USING INPUT PROFILE
|
||||
INPUTS:
|
||||
DFG - vector of length number of channels or spectral slices
|
||||
DGT - vector of length number of channels or spectral slices
|
||||
Pin - input powers vector of length number of channels or
|
||||
spectral slices
|
||||
Gp - provisioned gain length 1
|
||||
GTp - provisioned tilt length 1
|
||||
|
||||
OUTPUT:
|
||||
amp gain per channel or spectral slice
|
||||
NOTE: there is no checking done for violations of the total output power
|
||||
capability of the amp.
|
||||
Ported from Matlab version written by David Boerges at Ciena.
|
||||
Based on:
|
||||
R. di Muro, "The Er3+ fiber gain coefficient derived from a dynamic
|
||||
gain
|
||||
tilt technique", Journal of Lightwave Technology, Vol. 18, Iss. 3,
|
||||
Pp. 343-347, 2000.
|
||||
"""
|
||||
err_tolerance = 1.0e-11
|
||||
simple_opt = True
|
||||
|
||||
# TODO make all values linear unit and convert to dB units as needed within
|
||||
# this function.
|
||||
nchan = list(range(len(Pin)))
|
||||
|
||||
# TODO find a way to use these or lose them. Primarily we should have a
|
||||
# way to determine if exceeding the gain or output power of the amp
|
||||
tot_in_power_db = lin2db(np.sum(db2lin(Pin)))
|
||||
avg_gain_db = lin2db(mean(db2lin(dfg)))
|
||||
|
||||
#Linear fit to get the
|
||||
p = polyfit(nchan, dgt, 1)
|
||||
dgt_slope = p[0]
|
||||
|
||||
# Calculate the target slope- Currently assumes equal spaced channels
|
||||
# TODO make it so that supports arbitrary channel spacing.
|
||||
targ_slope = gtp / (len(nchan)-1)
|
||||
|
||||
# 1st estimate of DGT scaling
|
||||
dgts1 = targ_slope / dgt_slope
|
||||
|
||||
# when simple_opt is true code makes 2 attempts to compute gain and
|
||||
# the internal voa value. This is currently here to provide direct
|
||||
# comparison with original Matlab code. Will be removed.
|
||||
# TODO replace with loop
|
||||
|
||||
if simple_opt:
|
||||
|
||||
# 1st estimate of Er gain & voa loss
|
||||
g1st = dfg + dgt*dgts1
|
||||
voa = lin2db(mean(db2lin(g1st))) - gp
|
||||
|
||||
# 2nd estimate of Amp ch gain using the channel input profile
|
||||
g2nd = g1st - voa
|
||||
pout_db = lin2db(np.sum(db2lin(Pin + g2nd)))
|
||||
dgts2 = gp - (pout_db - tot_in_power_db)
|
||||
|
||||
#Center estimate of amp ch gain
|
||||
xcent = dgts2
|
||||
gcent = g1st - voa + dgt*xcent
|
||||
pout_db = lin2db(np.sum(db2lin(Pin + gcent)))
|
||||
gavg_cent = pout_db - tot_in_power_db
|
||||
|
||||
# Lower estimate of Amp ch gain
|
||||
deltax = np.max(g1st) - np.min(g1st)
|
||||
xlow = dgts2 - deltax
|
||||
glow = g1st - voa + xlow*dgt
|
||||
pout_db = lin2db(np.sum(db2lin(Pin + glow)))
|
||||
gavg_low = pout_db - tot_in_power_db
|
||||
|
||||
# Upper gain estimate
|
||||
xhigh =dgts2 + deltax
|
||||
ghigh = g1st - voa + xhigh*dgt
|
||||
pout_db = lin2db(np.sum(db2lin(Pin + ghigh)))
|
||||
gavg_high = pout_db - tot_in_power_db
|
||||
|
||||
# compute slope
|
||||
slope1 = (gavg_low - gavg_cent)/(xlow - xcent)
|
||||
slope2 = (gavg_cent - gavg_high)/(xcent - xhigh)
|
||||
|
||||
if np.abs(gp - gavg_cent) <= err_tolerance:
|
||||
dgts3 = xcent
|
||||
elif gp < gavg_cent:
|
||||
dgts3 = xcent - (gavg_cent - gp)/slope1
|
||||
else:
|
||||
dgts3 = xcent + (-gavg_cent + gp)/slope2
|
||||
|
||||
gprofile = g1st - voa +dgt*dgts3
|
||||
else:
|
||||
gprofile = None
|
||||
|
||||
return gprofile
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
plt.close('all')
|
||||
fc = itufs(0.05)
|
||||
lc = freq2wavelength(fc)/1000
|
||||
nchan = list(range(len(lc)))
|
||||
df = np.array([0.05]*(nchan[-1] + 1))
|
||||
# TODO remove path dependence
|
||||
path = ''
|
||||
|
||||
"""
|
||||
DFG_96: Design flat gain at each wavelength in the 96 channel 50GHz ITU
|
||||
grid in dB. This can be experimentally determined by measuring the gain
|
||||
at each wavelength using a full, flat channel (or ASE) load at the input.
|
||||
The amplifier should be set to its maximum flat gain (tilt = 0dB). This
|
||||
measurement captures the ripple of the amplifier. If the amplifier was
|
||||
designed to be mimimum ripple at some other tilt value, then the ripple
|
||||
reflected in this measurement will not be that minimum. However, when
|
||||
the DGT gets applied through the provisioning of tilt, the model should
|
||||
accurately reproduce the expected ripple at that tilt value. One could
|
||||
also do the measurement at some expected tilt value and back-calculate
|
||||
this vector using the DGT method. Alternatively, one could re-write the
|
||||
algorithm to accept a nominal tilt and a tiled version of this vector.
|
||||
"""
|
||||
|
||||
dfg_96 = np.loadtxt(path + 'DFG_96.txt')
|
||||
|
||||
"""maximum gain for flat operation - the amp in the data file was designed
|
||||
for 25dB gain and has an internal VOA for setting the external gain
|
||||
"""
|
||||
|
||||
avg_dfg = dfg_96.mean()
|
||||
|
||||
"""
|
||||
DGT_96: This is the so-called Dynamic Gain Tilt of the EDFA in dB/dB. It
|
||||
is the change in gain at each wavelength corresponding to a 1dB change at
|
||||
the longest wavelength supported. The value can be obtained
|
||||
experimentally or through analysis of the cross sections or Giles
|
||||
parameters of the Er fibre. This is experimentally measured by changing
|
||||
the gain of the amplifier above the maximum flat gain while not changing
|
||||
the internal VOA (i.e. the mid-stage VOA is set to minimum and does not
|
||||
change during the measurement). Note that the measurement can change the
|
||||
gain by an arbitrary amount and divide by the gain change (in dB) which
|
||||
is measured at the reference wavelength (the red end of the band).
|
||||
"""
|
||||
|
||||
dgt_96 = np.loadtxt(path + 'DGT_96.txt')
|
||||
|
||||
"""
|
||||
pNFfit3: Cubic polynomial fit coefficients to noise figure in dB
|
||||
averaged across wavelength as a function of gain change from design flat:
|
||||
|
||||
NFavg = pNFfit3(1)*dG^3 + pNFfit3(2)*dG^2 pNFfit3(3)*dG + pNFfit3(4)
|
||||
where
|
||||
dG = GainTarget - average(DFG_96)
|
||||
note that dG will normally be a negative value.
|
||||
"""
|
||||
|
||||
nf_fitco = np.loadtxt(path + 'pNFfit3.txt')
|
||||
|
||||
"""NFR_96: Noise figure ripple in dB away from the average noise figure
|
||||
across the band. This captures the wavelength dependence of the NF. To
|
||||
calculate the NF across channels, one uses the cubic fit coefficients
|
||||
with the external gain target to get the average nosie figure, NFavg and
|
||||
then adds this to NFR_96:
|
||||
NF_96 = NFR_96 + NFavg
|
||||
"""
|
||||
|
||||
nf_ripple = np.loadtxt(path + 'NFR_96.txt')
|
||||
|
||||
# This is an example to set the provisionable gain and gain-tilt values
|
||||
# Tilt is in units of dB/THz
|
||||
gain_target = 20.0
|
||||
tilt_target = -0.7
|
||||
|
||||
# calculate the NF for the EDFA at this gain setting
|
||||
dg = gain_target - avg_dfg
|
||||
nf_avg = polyval(nf_fitco, dg)
|
||||
nf_96 = nf_ripple + nf_avg
|
||||
|
||||
# get the input power profiles to show
|
||||
pch2d = np.loadtxt(path + 'Pchan2D.txt')
|
||||
|
||||
# Load legend and assemble legend text
|
||||
pch2d_legend_data = np.loadtxt(path + 'Pchan2DLegend.txt')
|
||||
pch2d_legend = []
|
||||
for ea in pch2d_legend_data:
|
||||
s = ''.join([chr(xx) for xx in ea.astype(dtype=int)]).strip()
|
||||
pch2d_legend.append(s)
|
||||
|
||||
#assemble plot
|
||||
axis_font = {'fontname': 'Arial', 'size':'16', 'fontweight':'bold'}
|
||||
title_font = {'fontname': 'Arial', 'size':'17', 'fontweight':'bold'}
|
||||
tic_font = {'fontname': 'Arial', 'size':'12'}
|
||||
|
||||
plt.rcParams["font.family"] = "Arial"
|
||||
plt.figure()
|
||||
plt.plot(nchan, pch2d.T, '.-', lw=2)
|
||||
plt.xlabel('Channel Number', **axis_font)
|
||||
plt.ylabel('Channel Power [dBm]', **axis_font)
|
||||
plt.title('Input Power Profiles for Different Channel Loading',
|
||||
**title_font)
|
||||
plt.legend(pch2d_legend, loc=5)
|
||||
plt.grid()
|
||||
plt.ylim((-100, -10))
|
||||
plt.xlim((0,110))
|
||||
plt.xticks(np.arange(0,100,10), **tic_font)
|
||||
plt.yticks(np.arange(-110,-10,10), **tic_font)
|
||||
|
||||
plt.figure()
|
||||
ea = pch2d[1,:]
|
||||
for ea in pch2d:
|
||||
chgain = gain_profile(dfg_96, dgt_96, ea, gain_target, tilt_target)
|
||||
pase = noise_profile(nf_96, chgain, fc, df)
|
||||
pout = lin2db(db2lin(ea + chgain) + db2lin(pase))
|
||||
plt.plot(nchan, pout, '.-', lw=2)
|
||||
plt.title('Output Power with ASE for Different Channel Loading',
|
||||
**title_font)
|
||||
plt.xlabel('Channel Number', **axis_font)
|
||||
plt.ylabel('Channel Power [dBm]', **axis_font)
|
||||
plt.grid()
|
||||
plt.ylim((-50, 10))
|
||||
plt.xlim((0,100))
|
||||
plt.xticks(np.arange(0,100,10), **tic_font)
|
||||
plt.yticks(np.arange(-50,10,10), **tic_font)
|
||||
plt.legend(pch2d_legend, loc=5)
|
||||
|
||||
1
examples/edfa_model/pNFfit3.txt
Executable file
1
examples/edfa_model/pNFfit3.txt
Executable file
@@ -0,0 +1 @@
|
||||
1.6824099999999999e-04 4.6996099999999999e-02 3.5954899999999998e-02 5.8285099999999996e+00
|
||||
120
examples/edfa_model/utilities.py
Normal file
120
examples/edfa_model/utilities.py
Normal file
@@ -0,0 +1,120 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Fri Nov 10 17:50:46 2017
|
||||
|
||||
@author: briantaylor
|
||||
"""
|
||||
import numpy as np
|
||||
from numpy import pi, cos, sqrt, log10
|
||||
|
||||
def c():
|
||||
"""
|
||||
Returns the speed of light in meters per second
|
||||
"""
|
||||
return 299792458.0
|
||||
|
||||
def itufs(spacing, startf=191.35, stopf=196.10):
|
||||
"""Creates an array of frequencies whose default range is
|
||||
191.35-196.10 THz
|
||||
|
||||
:param spacing: Frequency spacing in THz
|
||||
:param starf: Start frequency in THz
|
||||
:param stopf: Stop frequency in THz
|
||||
:type spacing: float
|
||||
:type startf: float
|
||||
:type stopf: float
|
||||
:return an array of frequnecies determined by the spacing parameter
|
||||
:rtype: numpy.ndarray
|
||||
"""
|
||||
return np.arange(startf, stopf + spacing/2, spacing)
|
||||
|
||||
def h():
|
||||
"""
|
||||
Returns plank's constant in J*s
|
||||
"""
|
||||
return 6.62607004e-34
|
||||
|
||||
def lin2db(value):
|
||||
return 10*log10(value)
|
||||
|
||||
|
||||
def db2lin(value):
|
||||
return 10**(value/10)
|
||||
|
||||
|
||||
def wavelength2freq(value):
|
||||
""" Converts wavelength units to frequeuncy units.
|
||||
"""
|
||||
return c()/value
|
||||
|
||||
|
||||
def freq2wavelength(value):
|
||||
""" Converts frequency units to wavelength units.
|
||||
"""
|
||||
return c()/value
|
||||
|
||||
|
||||
def deltawl2deltaf(delta_wl, wavelength):
|
||||
""" deltawl2deltaf(delta_wl, wavelength):
|
||||
delta_wl is BW in wavelength units
|
||||
wavelength is the center wl
|
||||
units for delta_wl and wavelength must be same
|
||||
|
||||
|
||||
|
||||
:param delta_wl: delta wavelength BW in same units as wavelength
|
||||
:param wavelength: wavelength BW is relevant for
|
||||
:type delta_wl: float or numpy.ndarray
|
||||
:type wavelength: float
|
||||
:return: The BW in frequency units
|
||||
:rtype: float or ndarray
|
||||
|
||||
"""
|
||||
f = wavelength2freq(wavelength)
|
||||
return delta_wl*f/wavelength
|
||||
|
||||
|
||||
def deltaf2deltawl(delta_f, frequency):
|
||||
""" deltawl2deltaf(delta_f, frequency):
|
||||
converts delta frequency to delta wavelength
|
||||
units for delta_wl and wavelength must be same
|
||||
|
||||
|
||||
:param delta_f: delta frequency in same units as frequency
|
||||
:param frequency: frequency BW is relevant for
|
||||
:type delta_f: float or numpy.ndarray
|
||||
:type frequency: float
|
||||
:return: The BW in wavelength units
|
||||
:rtype: float or ndarray
|
||||
|
||||
"""
|
||||
wl = freq2wavelength(frequency)
|
||||
return delta_f*wl/frequency
|
||||
|
||||
|
||||
def rrc(ffs, baud_rate, alpha):
|
||||
""" rrc(ffs, baud_rate, alpha): computes the root-raised cosine filter
|
||||
function.
|
||||
|
||||
:param ffs: A numpy array of frequencies
|
||||
:param baud_rate: The Baud Rate of the System
|
||||
:param alpha: The roll-off factor of the filter
|
||||
:type ffs: numpy.ndarray
|
||||
:type baud_rate: float
|
||||
:type alpha: float
|
||||
:return: hf a numpy array of the filter shape
|
||||
:rtype: numpy.ndarray
|
||||
|
||||
"""
|
||||
Ts = 1/baud_rate
|
||||
l_lim = (1 - alpha)/(2 * Ts)
|
||||
r_lim = (1 + alpha)/(2 * Ts)
|
||||
hf = np.zeros(np.shape(ffs))
|
||||
slope_inds = np.where(
|
||||
np.logical_and(np.abs(ffs) > l_lim, np.abs(ffs) < r_lim))
|
||||
hf[slope_inds] = 0.5 * (1 + cos((pi * Ts / alpha) *
|
||||
(np.abs(ffs[slope_inds]) - l_lim)))
|
||||
p_inds = np.where(np.logical_and(np.abs(ffs) > 0, np.abs(ffs) < l_lim))
|
||||
hf[p_inds] = 1
|
||||
return sqrt(hf)
|
||||
120
utilities.py
Normal file
120
utilities.py
Normal file
@@ -0,0 +1,120 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Fri Nov 10 17:50:46 2017
|
||||
|
||||
@author: briantaylor
|
||||
"""
|
||||
import numpy as np
|
||||
from numpy import pi, cos, sqrt, log10
|
||||
|
||||
def c():
|
||||
"""
|
||||
Returns the speed of light in meters per second
|
||||
"""
|
||||
return 299792458.0
|
||||
|
||||
def itufs(spacing, startf=191.35, stopf=196.10):
|
||||
"""Creates an array of frequencies whose default range is
|
||||
191.35-196.10 THz
|
||||
|
||||
:param spacing: Frequency spacing in THz
|
||||
:param starf: Start frequency in THz
|
||||
:param stopf: Stop frequency in THz
|
||||
:type spacing: float
|
||||
:type startf: float
|
||||
:type stopf: float
|
||||
:return an array of frequnecies determined by the spacing parameter
|
||||
:rtype: numpy.ndarray
|
||||
"""
|
||||
return np.arange(startf, stopf + spacing/2, spacing)
|
||||
|
||||
def h():
|
||||
"""
|
||||
Returns plank's constant in J*s
|
||||
"""
|
||||
return 6.62607004e-34
|
||||
|
||||
def lin2db(value):
|
||||
return 10*log10(value)
|
||||
|
||||
|
||||
def db2lin(value):
|
||||
return 10**(value/10)
|
||||
|
||||
|
||||
def wavelength2freq(value):
|
||||
""" Converts wavelength units to frequeuncy units.
|
||||
"""
|
||||
return c()/value
|
||||
|
||||
|
||||
def freq2wavelength(value):
|
||||
""" Converts frequency units to wavelength units.
|
||||
"""
|
||||
return c()/value
|
||||
|
||||
|
||||
def deltawl2deltaf(delta_wl, wavelength):
|
||||
""" deltawl2deltaf(delta_wl, wavelength):
|
||||
delta_wl is BW in wavelength units
|
||||
wavelength is the center wl
|
||||
units for delta_wl and wavelength must be same
|
||||
|
||||
|
||||
|
||||
:param delta_wl: delta wavelength BW in same units as wavelength
|
||||
:param wavelength: wavelength BW is relevant for
|
||||
:type delta_wl: float or numpy.ndarray
|
||||
:type wavelength: float
|
||||
:return: The BW in frequency units
|
||||
:rtype: float or ndarray
|
||||
|
||||
"""
|
||||
f = wavelength2freq(wavelength)
|
||||
return delta_wl*f/wavelength
|
||||
|
||||
|
||||
def deltaf2deltawl(delta_f, frequency):
|
||||
""" deltawl2deltaf(delta_f, frequency):
|
||||
converts delta frequency to delta wavelength
|
||||
units for delta_wl and wavelength must be same
|
||||
|
||||
|
||||
:param delta_f: delta frequency in same units as frequency
|
||||
:param frequency: frequency BW is relevant for
|
||||
:type delta_f: float or numpy.ndarray
|
||||
:type frequency: float
|
||||
:return: The BW in wavelength units
|
||||
:rtype: float or ndarray
|
||||
|
||||
"""
|
||||
wl = freq2wavelength(frequency)
|
||||
return delta_f*wl/frequency
|
||||
|
||||
|
||||
def rrc(ffs, baud_rate, alpha):
|
||||
""" rrc(ffs, baud_rate, alpha): computes the root-raised cosine filter
|
||||
function.
|
||||
|
||||
:param ffs: A numpy array of frequencies
|
||||
:param baud_rate: The Baud Rate of the System
|
||||
:param alpha: The roll-off factor of the filter
|
||||
:type ffs: numpy.ndarray
|
||||
:type baud_rate: float
|
||||
:type alpha: float
|
||||
:return: hf a numpy array of the filter shape
|
||||
:rtype: numpy.ndarray
|
||||
|
||||
"""
|
||||
Ts = 1/baud_rate
|
||||
l_lim = (1 - alpha)/(2 * Ts)
|
||||
r_lim = (1 + alpha)/(2 * Ts)
|
||||
hf = np.zeros(np.shape(ffs))
|
||||
slope_inds = np.where(
|
||||
np.logical_and(np.abs(ffs) > l_lim, np.abs(ffs) < r_lim))
|
||||
hf[slope_inds] = 0.5 * (1 + cos((pi * Ts / alpha) *
|
||||
(np.abs(ffs[slope_inds]) - l_lim)))
|
||||
p_inds = np.where(np.logical_and(np.abs(ffs) > 0, np.abs(ffs) < l_lim))
|
||||
hf[p_inds] = 1
|
||||
return sqrt(hf)
|
||||
Reference in New Issue
Block a user