mirror of
https://github.com/Telecominfraproject/oopt-gnpy.git
synced 2025-11-03 03:28:04 +00:00
Add per degree channel power target out
- add the per degree info using the EXACT next node uid as identifier of the degree when a node is a roadm - add the degree identifier on the propagate and on the call functions - use the per degree target_pch_out_db defined in json entry for the target power in network build - verifies existence of the per degree power target in order to support partial per degree target power definition - correct test data files for expected auto design results that now should include the per degree information, even if it is the same for all degree. - in order to enable per degree power definition on direction where booster is not defined, enable the declaration of edfas in json without specifying type variety Signed-off-by: EstherLerouzic <esther.lerouzic@orange.com> Change-Id: I5004cbb250ca5fd6b6498ac9d4b9c4f28a65efee
This commit is contained in:
committed by
Jan Kundrát
parent
a5398a5c57
commit
c56ea898a6
@@ -184,17 +184,20 @@ class Transceiver(_Node):
|
||||
return spectral_info
|
||||
|
||||
|
||||
RoadmParams = namedtuple('RoadmParams', 'target_pch_out_db add_drop_osnr pmd restrictions')
|
||||
RoadmParams = namedtuple('RoadmParams', 'target_pch_out_db add_drop_osnr pmd restrictions per_degree_pch_out_db')
|
||||
|
||||
|
||||
class Roadm(_Node):
|
||||
def __init__(self, *args, params, **kwargs):
|
||||
if 'per_degree_pch_out_db' not in params.keys():
|
||||
params['per_degree_pch_out_db'] = {}
|
||||
super().__init__(*args, params=RoadmParams(**params), **kwargs)
|
||||
self.loss = 0 # auto-design interest
|
||||
self.effective_loss = None
|
||||
self.effective_pch_out_db = self.params.target_pch_out_db
|
||||
self.passive = True
|
||||
self.restrictions = self.params.restrictions
|
||||
self.per_degree_pch_out_db = self.params.per_degree_pch_out_db
|
||||
|
||||
@property
|
||||
def to_json(self):
|
||||
@@ -202,8 +205,9 @@ class Roadm(_Node):
|
||||
'type': type(self).__name__,
|
||||
'params': {
|
||||
'target_pch_out_db': self.effective_pch_out_db,
|
||||
'restrictions': self.restrictions
|
||||
},
|
||||
'restrictions': self.restrictions,
|
||||
'per_degree_pch_out_db': self.per_degree_pch_out_db
|
||||
},
|
||||
'metadata': {
|
||||
'location': self.metadata['location']._asdict()
|
||||
}
|
||||
@@ -220,15 +224,21 @@ class Roadm(_Node):
|
||||
f' effective loss (dB): {self.effective_loss:.2f}',
|
||||
f' pch out (dBm): {self.effective_pch_out_db!r}'])
|
||||
|
||||
def propagate(self, pref, *carriers):
|
||||
def propagate(self, pref, *carriers, degree):
|
||||
# pin_target and loss are read from eqpt_config.json['Roadm']
|
||||
# all ingress channels in xpress are set to this power level
|
||||
# but add channels are not, so we define an effective loss
|
||||
# in the case of add channels
|
||||
self.effective_pch_out_db = min(pref.p_spani, self.params.target_pch_out_db)
|
||||
# find the target power on this degree:
|
||||
# if a target power has been defined for this degree use it else use the global one.
|
||||
# if the input power is lower than the target one, use the input power instead because
|
||||
# a ROADM doesn't amplify, it can only attenuate
|
||||
# TODO maybe add a minimum loss for the ROADM
|
||||
per_degree_pch = self.per_degree_pch_out_db[degree] if degree in self.per_degree_pch_out_db.keys() else self.params.target_pch_out_db
|
||||
self.effective_pch_out_db = min(pref.p_spani, per_degree_pch)
|
||||
self.effective_loss = pref.p_spani - self.effective_pch_out_db
|
||||
carriers_power = array([c.power.signal + c.power.nli + c.power.ase for c in carriers])
|
||||
carriers_att = list(map(lambda x: lin2db(x * 1e3) - self.params.target_pch_out_db, carriers_power))
|
||||
carriers_att = list(map(lambda x: lin2db(x * 1e3) - per_degree_pch, carriers_power))
|
||||
exceeding_att = -min(list(filter(lambda x: x < 0, carriers_att)), default=0)
|
||||
carriers_att = list(map(lambda x: db2lin(x + exceeding_att), carriers_att))
|
||||
for carrier_att, carrier in zip(carriers_att, carriers):
|
||||
@@ -242,8 +252,8 @@ class Roadm(_Node):
|
||||
def update_pref(self, pref):
|
||||
return pref._replace(p_span0=pref.p_span0, p_spani=self.effective_pch_out_db)
|
||||
|
||||
def __call__(self, spectral_info):
|
||||
carriers = tuple(self.propagate(spectral_info.pref, *spectral_info.carriers))
|
||||
def __call__(self, spectral_info, degree):
|
||||
carriers = tuple(self.propagate(spectral_info.pref, *spectral_info.carriers, degree=degree))
|
||||
pref = self.update_pref(spectral_info.pref)
|
||||
return spectral_info._replace(carriers=carriers, pref=pref)
|
||||
|
||||
|
||||
@@ -239,18 +239,34 @@ def set_amplifier_voa(amp, power_target, power_mode):
|
||||
amp.out_voa = voa
|
||||
|
||||
|
||||
def set_egress_amplifier(network, roadm, equipment, pref_total_db):
|
||||
def set_egress_amplifier(network, this_node, equipment, pref_total_db):
|
||||
""" this node can be a transceiver or a ROADM (same function called in both cases)
|
||||
"""
|
||||
power_mode = equipment['Span']['default'].power_mode
|
||||
next_oms = (n for n in network.successors(roadm) if not isinstance(n, elements.Transceiver))
|
||||
next_oms = (n for n in network.successors(this_node) if not isinstance(n, elements.Transceiver))
|
||||
this_node_degree = {k: v for k, v in this_node.per_degree_pch_out_db.items()} if hasattr(this_node, 'per_degree_pch_out_db') else {}
|
||||
for oms in next_oms:
|
||||
# go through all the OMS departing from the Roadm
|
||||
prev_node = roadm
|
||||
# go through all the OMS departing from the ROADM
|
||||
prev_node = this_node
|
||||
node = oms
|
||||
# if isinstance(next_node, elements.Fused): #support ROADM wo egress amp for metro applications
|
||||
# node = find_last_node(next_node)
|
||||
# next_node = next(n for n in network.successors(node))
|
||||
# next_node = find_last_node(next_node)
|
||||
prev_dp = getattr(roadm.params, 'target_pch_out_db', 0)
|
||||
if this_node_degree:
|
||||
# find the target power on this degree
|
||||
if node.uid in this_node_degree.keys():
|
||||
prev_dp = this_node_degree[node.uid]
|
||||
else:
|
||||
# if no target power is defined on this degree use the global one
|
||||
# if target_pch_out_db is not an attribute, then the element must be a transceiver
|
||||
prev_dp = getattr(this_node.params, 'target_pch_out_db', 0)
|
||||
this_node_degree[node.uid] = prev_dp
|
||||
else:
|
||||
# if no per degree target power is given use the global one
|
||||
# if target_pch_out_db is not an attribute, then the element must be a transceiver
|
||||
prev_dp = getattr(this_node.params, 'target_pch_out_db', 0)
|
||||
this_node_degree[node.uid] = prev_dp
|
||||
dp = prev_dp
|
||||
prev_voa = 0
|
||||
voa = 0
|
||||
@@ -313,6 +329,8 @@ def set_egress_amplifier(network, roadm, equipment, pref_total_db):
|
||||
node = next_node
|
||||
# print(f'{node.uid}')
|
||||
|
||||
if isinstance(this_node, elements.Roadm):
|
||||
this_node.per_degree_pch_out_db = {k: v for k, v in this_node_degree.items()}
|
||||
|
||||
def add_egress_amplifier(network, node):
|
||||
next_nodes = [n for n in network.successors(node)
|
||||
|
||||
@@ -349,7 +349,7 @@ def network_from_json(json_data, equipment):
|
||||
temp = merge_amplifier_restrictions(temp, extra_params.__dict__)
|
||||
el_config['params'] = temp
|
||||
el_config['type_variety'] = variety
|
||||
elif typ in ['Edfa', 'Fiber', 'RamanFiber']: # catch it now because the code will crash later!
|
||||
elif typ in ['Fiber', 'RamanFiber']: # catch it now because the code will crash later!
|
||||
raise ConfigurationError(f'The {typ} of variety type {variety} was not recognized:'
|
||||
'\nplease check it is properly defined in the eqpt_config json file')
|
||||
el = cls(**el_config)
|
||||
|
||||
@@ -333,8 +333,11 @@ def propagate(path, req, equipment):
|
||||
si = create_input_spectral_information(
|
||||
req.f_min, req.f_max, req.roll_off, req.baud_rate,
|
||||
req.power, req.spacing)
|
||||
for el in path:
|
||||
si = el(si)
|
||||
for i, el in enumerate(path):
|
||||
if isinstance(el, Roadm):
|
||||
si = el(si, degree=path[i+1].uid)
|
||||
else:
|
||||
si = el(si)
|
||||
path[0].update_snr(req.tx_osnr)
|
||||
if any(isinstance(el, Roadm) for el in path):
|
||||
path[-1].update_snr(req.tx_osnr, equipment['Roadm']['default'].add_drop_osnr)
|
||||
@@ -366,8 +369,11 @@ def propagate_and_optimize_mode(path, req, equipment):
|
||||
spc_info = create_input_spectral_information(req.f_min, req.f_max,
|
||||
equipment['SI']['default'].roll_off,
|
||||
this_br, req.power, req.spacing)
|
||||
for el in path:
|
||||
spc_info = el(spc_info)
|
||||
for i, el in enumerate(path):
|
||||
if isinstance(el, Roadm):
|
||||
spc_info = el(spc_info, degree=path[i+1].uid)
|
||||
else:
|
||||
spc_info = el(spc_info)
|
||||
for this_mode in modes_to_explore:
|
||||
if path[-1].snr is not None:
|
||||
path[0].update_snr(this_mode['tx_osnr'])
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -164,6 +164,11 @@
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
},
|
||||
"per_degree_pch_out_db": {
|
||||
"east edfa in Lannion_CAS to Corlay": -20,
|
||||
"east edfa in Lannion_CAS to Stbrieuc": -20,
|
||||
"east edfa in Lannion_CAS to Morlaix": -20
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
@@ -183,6 +188,11 @@
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
},
|
||||
"per_degree_pch_out_db": {
|
||||
"Edfa0_roadm Lorient_KMA": -20,
|
||||
"Edfa1_roadm Lorient_KMA": -20,
|
||||
"Edfa2_roadm Lorient_KMA": -20
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
@@ -202,6 +212,10 @@
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
},
|
||||
"per_degree_pch_out_db": {
|
||||
"Edfa0_roadm Vannes_KBE": -20,
|
||||
"Edfa1_roadm Vannes_KBE": -20
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
@@ -221,7 +235,12 @@
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
},
|
||||
"per_degree_pch_out_db": {
|
||||
"Edfa0_roadm Rennes_STA": -20,
|
||||
"Edfa1_roadm Rennes_STA": -20
|
||||
}
|
||||
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
@@ -240,6 +259,10 @@
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
},
|
||||
"per_degree_pch_out_db": {
|
||||
"east edfa in Brest_KLA to Quimper": -20,
|
||||
"Edfa0_roadm Brest_KLA": -20
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
@@ -259,6 +282,11 @@
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
},
|
||||
"per_degree_pch_out_db": {
|
||||
"east edfa in c to d": -20,
|
||||
"Edfa0_roadm c": -20,
|
||||
"Edfa1_roadm c": -20
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
@@ -278,6 +306,10 @@
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
},
|
||||
"per_degree_pch_out_db":{
|
||||
"Edfa0_roadm d": -20,
|
||||
"Edfa1_roadm d": -20
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
@@ -297,6 +329,10 @@
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
},
|
||||
"per_degree_pch_out_db":{
|
||||
"Edfa0_roadm e": -20,
|
||||
"Edfa1_roadm e": -20
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
@@ -316,6 +352,11 @@
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
},
|
||||
"per_degree_pch_out_db": {
|
||||
"Edfa0_roadm f": -20,
|
||||
"Edfa1_roadm f": -20,
|
||||
"Edfa2_roadm f": -20
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
@@ -335,6 +376,10 @@
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
},
|
||||
"per_degree_pch_out_db": {
|
||||
"Edfa0_roadm g": -20,
|
||||
"Edfa1_roadm g": -20
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
@@ -354,6 +399,10 @@
|
||||
"restrictions": {
|
||||
"preamp_variety_list": [],
|
||||
"booster_variety_list": []
|
||||
},
|
||||
"per_degree_pch_out_db": {
|
||||
"Edfa0_roadm h": -20,
|
||||
"Edfa1_roadm h": -20
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
@@ -375,7 +424,11 @@
|
||||
"booster_variety_list": [
|
||||
"std_booster"
|
||||
]
|
||||
}
|
||||
},
|
||||
"per_degree_pch_out_db": {
|
||||
"Edfa0_roadm a": -20,
|
||||
"Edfa1_roadm a": -20
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"location": {
|
||||
@@ -396,6 +449,10 @@
|
||||
"std_low_gain"
|
||||
],
|
||||
"booster_variety_list": []
|
||||
},
|
||||
"per_degree_pch_out_db": {
|
||||
"Edfa0_roadm b": -20,
|
||||
"Edfa1_roadm b": -20
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
|
||||
Reference in New Issue
Block a user