mirror of
https://github.com/Telecominfraproject/oopt-gnpy.git
synced 2025-10-30 17:47:50 +00:00
strip whitespace
This commit is contained in:
@@ -7,11 +7,11 @@ xls to json parser, that can be called directly from the transmission_main_examp
|
||||
xls examples are meshTopologyExampleV2.xls and CORONET_Global_Topology.xls
|
||||
Require Nodes and Links sheets, Eqpt sheet is optional
|
||||
*in Nodes sheet, only the 'City' column is mandatory. The column 'Type' is discovered based
|
||||
on the topology: degree 2 = ILA, other degrees = ROADM. The value is also corrected if the user
|
||||
on the topology: degree 2 = ILA, other degrees = ROADM. The value is also corrected if the user
|
||||
specifies an ILA of degree != 2.
|
||||
*In Links sheet only the 3 first columns (Node A, Node Z and east Distance (km)) are mandatory.
|
||||
*In Links sheet only the 3 first columns (Node A, Node Z and east Distance (km)) are mandatory.
|
||||
Missing west information are copied from east information so it is possible to input undir data
|
||||
*in Eqpt sheet
|
||||
*in Eqpt sheet
|
||||
|
||||
"""
|
||||
from sys import exit
|
||||
@@ -39,19 +39,19 @@ class Link(namedtuple('Link', 'from_city to_city \
|
||||
west_distance west_fiber west_lineic west_con_in west_con_out west_pmd west_cable \
|
||||
distance_units')):
|
||||
def __new__(cls, from_city, to_city,
|
||||
east_distance, east_fiber='SSMF', east_lineic=0.2,
|
||||
east_con_in=None, east_con_out=None, east_pmd=0.1, east_cable='',
|
||||
west_distance='', west_fiber='', west_lineic='',
|
||||
east_distance, east_fiber='SSMF', east_lineic=0.2,
|
||||
east_con_in=None, east_con_out=None, east_pmd=0.1, east_cable='',
|
||||
west_distance='', west_fiber='', west_lineic='',
|
||||
west_con_in='', west_con_out='', west_pmd='', west_cable='',
|
||||
distance_units='km'):
|
||||
east_values = [east_distance, east_fiber, east_lineic, east_con_in, east_con_out,
|
||||
east_values = [east_distance, east_fiber, east_lineic, east_con_in, east_con_out,
|
||||
east_pmd, east_cable]
|
||||
west_values = [west_distance, west_fiber, west_lineic, west_con_in, west_con_out,
|
||||
west_values = [west_distance, west_fiber, west_lineic, west_con_in, west_con_out,
|
||||
west_pmd, west_cable]
|
||||
default_values = [80,'SSMF',0.2,None,None,0.1,'']
|
||||
east_values = [x[0] if x[0] != '' else x[1] for x in zip(east_values,default_values)]
|
||||
west_values = [x[0] if x[0] != '' else x[1] for x in zip(west_values,east_values)]
|
||||
return super().__new__(cls, from_city, to_city, *east_values, *west_values, distance_units)
|
||||
return super().__new__(cls, from_city, to_city, *east_values, *west_values, distance_units)
|
||||
|
||||
class Eqpt(namedtuple('Eqpt', 'from_city to_city \
|
||||
egress_amp_type egress_att_in egress_amp_gain egress_amp_tilt egress_amp_att_out\
|
||||
@@ -64,7 +64,7 @@ class Eqpt(namedtuple('Eqpt', 'from_city to_city \
|
||||
ingress_amp_type, ingress_att_in, ingress_amp_gain, ingress_amp_tilt, ingress_amp_att_out]
|
||||
default_values = ['','','',0,0,0,0,'',0,0,0,0]
|
||||
values = [x[0] if x[0] != '' else x[1] for x in zip(values,default_values)]
|
||||
return super().__new__(cls, *values)
|
||||
return super().__new__(cls, *values)
|
||||
|
||||
def sanity_check(nodes, nodes_by_city, links_by_city, eqpts_by_city):
|
||||
try :
|
||||
@@ -83,7 +83,7 @@ def sanity_check(nodes, nodes_by_city, links_by_city, eqpts_by_city):
|
||||
|
||||
for city,link in links_by_city.items():
|
||||
if nodes_by_city[city].node_type.lower()=='ila' and len(link) != 2:
|
||||
#wrong input: ILA sites can only be Degree 2
|
||||
#wrong input: ILA sites can only be Degree 2
|
||||
# => correct to make it a ROADM and remove entry in links_by_city
|
||||
#TODO : put in log rather than print
|
||||
print(f'invalid node type ({nodes_by_city[city].node_type})\
|
||||
@@ -115,7 +115,7 @@ def convert_file(input_filename, filter_region=[]):
|
||||
global eqpts_by_city
|
||||
eqpts_by_city = defaultdict(list)
|
||||
for eqpt in eqpts:
|
||||
eqpts_by_city[eqpt.from_city].append(eqpt)
|
||||
eqpts_by_city[eqpt.from_city].append(eqpt)
|
||||
|
||||
nodes = sanity_check(nodes, nodes_by_city, links_by_city, eqpts_by_city)
|
||||
|
||||
@@ -148,7 +148,7 @@ def convert_file(input_filename, filter_region=[]):
|
||||
'latitude': x.latitude,
|
||||
'longitude': x.longitude}},
|
||||
'type': 'Fused'}
|
||||
for x in nodes_by_city.values() if x.node_type.lower() == 'fused'] +
|
||||
for x in nodes_by_city.values() if x.node_type.lower() == 'fused'] +
|
||||
[{'uid': f'fiber ({x.from_city} → {x.to_city})-{x.east_cable}',
|
||||
'metadata': {'location': midpoint(nodes_by_city[x.from_city],
|
||||
nodes_by_city[x.to_city])},
|
||||
@@ -171,7 +171,7 @@ def convert_file(input_filename, filter_region=[]):
|
||||
'loss_coef': x.west_lineic,
|
||||
'con_in':x.west_con_in,
|
||||
'con_out':x.west_con_out}
|
||||
} # missing ILA construction
|
||||
} # missing ILA construction
|
||||
for x in links] +
|
||||
[{'uid': f'egress edfa in {e.from_city} to {e.to_city}',
|
||||
'metadata': {'location': {'city': nodes_by_city[e.from_city].city,
|
||||
@@ -193,7 +193,7 @@ def convert_file(input_filename, filter_region=[]):
|
||||
'type_variety': e.ingress_amp_type,
|
||||
'operational': {'gain_target': e.ingress_amp_gain,
|
||||
'tilt_target': e.ingress_amp_tilt}
|
||||
}
|
||||
}
|
||||
for e in eqpts if e.ingress_amp_type.lower() != ''],
|
||||
'connections':
|
||||
list(chain.from_iterable([eqpt_connection_by_city(n.city)
|
||||
@@ -205,7 +205,7 @@ def convert_file(input_filename, filter_region=[]):
|
||||
for x in nodes_by_city.values() if x.node_type.lower()=='roadm'],
|
||||
[{'from_node': f'roadm {x.city}',
|
||||
'to_node': f'trx {x.city}'}
|
||||
for x in nodes_by_city.values() if x.node_type.lower()=='roadm'])))
|
||||
for x in nodes_by_city.values() if x.node_type.lower()=='roadm'])))
|
||||
}
|
||||
|
||||
#print(dumps(data, indent=2))
|
||||
@@ -235,20 +235,20 @@ def parse_excel(input_filename):
|
||||
expected = ['City', 'State', 'Country', 'Region', 'Latitude', 'Longitude']
|
||||
if header != expected:
|
||||
raise ValueError(f'Malformed header on Nodes sheet: {header} != {expected}')
|
||||
"""
|
||||
"""
|
||||
|
||||
nodes = []
|
||||
for row in all_rows(nodes_sheet, start=5):
|
||||
nodes.append(Node(*(x.value for x in row[0:NODES_COLUMN])))
|
||||
#check input
|
||||
expected_node_types = ('ROADM', 'ILA', 'FUSED')
|
||||
nodes = [n._replace(node_type='ILA')
|
||||
nodes = [n._replace(node_type='ILA')
|
||||
if not (n.node_type in expected_node_types) else n for n in nodes]
|
||||
|
||||
# sanity check
|
||||
"""
|
||||
header = [x.value.strip() for x in links_sheet.row(4)]
|
||||
expected = ['Node A', 'Node Z',
|
||||
expected = ['Node A', 'Node Z',
|
||||
'Distance (km)', 'Fiber type', 'lineic att', 'Con_in', 'Con_out', 'PMD', 'Cable id',
|
||||
'Distance (km)', 'Fiber type', 'lineic att', 'Con_in', 'Con_out', 'PMD', 'Cable id']
|
||||
if header != expected:
|
||||
@@ -280,7 +280,7 @@ def eqpt_connection_by_city(city_name):
|
||||
if nodes_by_city[city_name].node_type.lower() in ('ila', 'fused'):
|
||||
# Then len(other_cities) == 2
|
||||
direction = ['ingress', 'egress']
|
||||
for i in range(2):
|
||||
for i in range(2):
|
||||
from_ = fiber_link(other_cities[i], city_name)
|
||||
in_ = eqpt_in_city_to_city(city_name, other_cities[0],direction[i])
|
||||
to_ = fiber_link(city_name, other_cities[1-i])
|
||||
@@ -334,7 +334,7 @@ def fiber_dest_from_source(city_name):
|
||||
destinations = []
|
||||
links_from_city = links_by_city[city_name]
|
||||
for l in links_from_city:
|
||||
if l.from_city == city_name:
|
||||
if l.from_city == city_name:
|
||||
destinations.append(l.to_city)
|
||||
else:
|
||||
destinations.append(l.from_city)
|
||||
|
||||
@@ -109,7 +109,7 @@ class Roadm(Node):
|
||||
'metadata' : {
|
||||
'location': self.metadata['location']._asdict()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def __repr__(self):
|
||||
return f'{type(self).__name__}(uid={self.uid!r}, loss={self.loss!r})'
|
||||
@@ -174,7 +174,7 @@ class Fused(Node):
|
||||
nonlinear_interference=pwr.nli/attenuation,
|
||||
amplified_spontaneous_emission=pwr.ase/attenuation)
|
||||
yield carrier._replace(power=pwr)
|
||||
|
||||
|
||||
def update_pref(self, pref):
|
||||
return pref._replace(p_span0=pref.p0, p_spani=pref.pi - self.loss)
|
||||
|
||||
@@ -192,7 +192,7 @@ class Fiber(Node):
|
||||
params = {}
|
||||
if 'con_in' not in params:
|
||||
# if not defined in the network json connector loss in/out
|
||||
# the None value will be updated in network.py[build_network]
|
||||
# the None value will be updated in network.py[build_network]
|
||||
# with default values from eqpt_config.json[Spans]
|
||||
params['con_in'] = None
|
||||
params['con_out'] = None
|
||||
@@ -209,8 +209,8 @@ class Fiber(Node):
|
||||
self.con_in = self.params.con_in
|
||||
self.con_out = self.params.con_out
|
||||
self.dispersion = self.params.dispersion # s/m/m
|
||||
self.gamma = self.params.gamma # 1/W/m
|
||||
self.pch_out = None
|
||||
self.gamma = self.params.gamma # 1/W/m
|
||||
self.pch_out = None
|
||||
# TODO|jla: discuss factor 2 in the linear lineic attenuation
|
||||
|
||||
@property
|
||||
@@ -249,15 +249,15 @@ class Fiber(Node):
|
||||
def fiber_loss(self):
|
||||
# dB fiber loss, not including padding attenuator
|
||||
return self.loss_coef * self.length + self.con_in + self.con_out
|
||||
|
||||
|
||||
@property
|
||||
def loss(self):
|
||||
#total loss incluiding padding att_in: useful for polymorphism with roadm loss
|
||||
return self.loss_coef * self.length + self.con_in + self.con_out + self.att_in
|
||||
|
||||
|
||||
@property
|
||||
def passive(self):
|
||||
return True
|
||||
return True
|
||||
|
||||
@property
|
||||
def lin_attenuation(self):
|
||||
@@ -459,7 +459,7 @@ class Edfa(Node):
|
||||
if self.pin_db is None or self.pout_db is None:
|
||||
return f'{type(self).__name__} {self.uid}'
|
||||
nf = mean(self.nf)
|
||||
return '\n'.join([f'{type(self).__name__} {self.uid}',
|
||||
return '\n'.join([f'{type(self).__name__} {self.uid}',
|
||||
f' type_variety: {self.params.type_variety}',
|
||||
f' effective gain(dB): {self.effective_gain:.2f}',
|
||||
f' (before att_in and before output VOA)',
|
||||
@@ -519,13 +519,13 @@ class Edfa(Node):
|
||||
g1a = gain_target - self.params.nf_model.delta_p - dg
|
||||
nf_avg = lin2db(db2lin(self.params.nf_model.nf1) + db2lin(self.params.nf_model.nf2)/db2lin(g1a))
|
||||
elif self.params.type_def == 'fixed_gain':
|
||||
nf_avg = self.params.nf_model.nf0
|
||||
nf_avg = self.params.nf_model.nf0
|
||||
else:
|
||||
nf_avg = polyval(self.params.nf_fit_coeff, -dg)
|
||||
if avg:
|
||||
return nf_avg + pad
|
||||
else:
|
||||
return self.interpol_nf_ripple + nf_avg + pad # input VOA = 1 for 1 NF degradation
|
||||
return self.interpol_nf_ripple + nf_avg + pad # input VOA = 1 for 1 NF degradation
|
||||
|
||||
def noise_profile(self, df):
|
||||
""" noise_profile(bw) computes amplifier ase (W) in signal bw (Hz)
|
||||
@@ -704,7 +704,7 @@ class Edfa(Node):
|
||||
yield carrier._replace(power=pwr)
|
||||
|
||||
def update_pref(self, pref):
|
||||
return pref._replace(p_span0=pref.p0,
|
||||
return pref._replace(p_span0=pref.p0,
|
||||
p_spani=pref.pi + self.effective_gain - self.operational.out_voa)
|
||||
|
||||
def __call__(self, spectral_info):
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
'''
|
||||
nf model parameters calculation
|
||||
calculate nf1, nf2 and Delta_P of a 2 coils edfa with internal VOA
|
||||
from nf_min and nf_max inputs
|
||||
from nf_min and nf_max inputs
|
||||
'''
|
||||
from numpy import clip, polyval
|
||||
from sys import exit
|
||||
@@ -31,12 +31,12 @@ AmpBase = namedtuple(
|
||||
' nf_model nf_fit_coeff nf_ripple dgt gain_ripple out_voa_auto allowed_for_design')
|
||||
class Amp(AmpBase):
|
||||
def __new__(cls,
|
||||
type_variety, type_def, gain_flatmax, gain_min, p_max, nf_model=None,
|
||||
nf_fit_coeff=None, nf_ripple=None, dgt=None, gain_ripple=None,
|
||||
type_variety, type_def, gain_flatmax, gain_min, p_max, nf_model=None,
|
||||
nf_fit_coeff=None, nf_ripple=None, dgt=None, gain_ripple=None,
|
||||
out_voa_auto=False, allowed_for_design=True):
|
||||
return super().__new__(cls,
|
||||
type_variety, type_def, gain_flatmax, gain_min, p_max,
|
||||
nf_model, nf_fit_coeff, nf_ripple, dgt, gain_ripple,
|
||||
type_variety, type_def, gain_flatmax, gain_min, p_max,
|
||||
nf_model, nf_fit_coeff, nf_ripple, dgt, gain_ripple,
|
||||
out_voa_auto, allowed_for_design)
|
||||
|
||||
@classmethod
|
||||
@@ -162,7 +162,7 @@ def trx_mode_params(equipment, trx_type_variety='', trx_mode='', error_message=F
|
||||
print('Computation stopped.')
|
||||
exit()
|
||||
else:
|
||||
# default transponder charcteristics
|
||||
# default transponder charcteristics
|
||||
trx_params['frequency'] = {'min': default_si_data.f_min, 'max': default_si_data.f_max}
|
||||
trx_params['baud_rate'] = default_si_data.baud_rate
|
||||
trx_params['spacing'] = default_si_data.spacing
|
||||
@@ -178,10 +178,10 @@ def trx_mode_params(equipment, trx_type_variety='', trx_mode='', error_message=F
|
||||
|
||||
def automatic_spacing(baud_rate):
|
||||
"""return the min possible channel spacing for a given baud rate"""
|
||||
spacing_list = [(38e9,50e9), (67e9,75e9), (92e9,100e9)] #list of possible tuples
|
||||
spacing_list = [(38e9,50e9), (67e9,75e9), (92e9,100e9)] #list of possible tuples
|
||||
#[(max_baud_rate, spacing_for_this_baud_rate)]
|
||||
acceptable_spacing_list = list(filter(lambda x : x[0]>baud_rate, spacing_list))
|
||||
if len(acceptable_spacing_list) < 1:
|
||||
if len(acceptable_spacing_list) < 1:
|
||||
#can't find an adequate spacing from the list, so default to:
|
||||
return baud_rate*1.2
|
||||
else:
|
||||
|
||||
@@ -25,7 +25,7 @@ class ConvenienceAccess:
|
||||
if abbrev in kwargs:
|
||||
kwargs[field] = kwargs.pop(abbrev)
|
||||
return self._replace(**kwargs)
|
||||
|
||||
|
||||
#def ptot_dbm(self):
|
||||
# p = array([c.power.signal+c.power.nli+c.power.ase for c in self.carriers])
|
||||
# return lin2db(sum(p*1e3))
|
||||
@@ -64,7 +64,7 @@ def create_input_spectral_information(f_min, roll_off, baud_rate, power, spacing
|
||||
pref = lin2db(power * 1e3)
|
||||
si = SpectralInformation(pref=Pref(pref, pref))
|
||||
si = si.update(carriers=[
|
||||
Channel(f, (f_min+spacing*f),
|
||||
Channel(f, (f_min+spacing*f),
|
||||
baud_rate, roll_off, Power(power, 0, 0)) for f in range(1,nb_channel+1)
|
||||
])
|
||||
return si
|
||||
|
||||
@@ -26,7 +26,7 @@ logger = getLogger(__name__)
|
||||
def load_network(filename, equipment):
|
||||
json_filename = ''
|
||||
if filename.suffix.lower() == '.xls':
|
||||
logger.info('Automatically generating topology JSON file')
|
||||
logger.info('Automatically generating topology JSON file')
|
||||
json_filename = convert_file(filename)
|
||||
elif filename.suffix.lower() == '.json':
|
||||
json_filename = filename
|
||||
@@ -95,7 +95,7 @@ def select_edfa(gain_target, power_target, equipment):
|
||||
power=min(
|
||||
pin
|
||||
+edfa.gain_flatmax
|
||||
+TARGET_EXTENDED_GAIN,
|
||||
+TARGET_EXTENDED_GAIN,
|
||||
edfa.p_max
|
||||
)
|
||||
-power_target,
|
||||
@@ -106,7 +106,7 @@ def select_edfa(gain_target, power_target, equipment):
|
||||
|
||||
acceptable_gain_list = \
|
||||
list(filter(lambda x : x.gain>-TARGET_EXTENDED_GAIN, edfa_list))
|
||||
if len(acceptable_gain_list) < 1:
|
||||
if len(acceptable_gain_list) < 1:
|
||||
#no amplifier satisfies the required gain, so pick the highest gain:
|
||||
gain_max = max(edfa_list, key=itemgetter(2)).gain
|
||||
#pick up all amplifiers that share this max gain:
|
||||
@@ -127,10 +127,10 @@ def select_edfa(gain_target, power_target, equipment):
|
||||
|
||||
def set_roadm_loss(network, equipment, pref_ch_db):
|
||||
roadms = [roadm for roadm in network if isinstance(roadm, Roadm)]
|
||||
power_mode = equipment['Spans']['default'].power_mode
|
||||
power_mode = equipment['Spans']['default'].power_mode
|
||||
default_roadm_loss = equipment['Roadms']['default'].gain_mode_default_loss
|
||||
pref_roadm_db = equipment['Roadms']['default'].power_mode_pref
|
||||
roadm_loss = pref_ch_db - pref_roadm_db
|
||||
roadm_loss = pref_ch_db - pref_roadm_db
|
||||
|
||||
for roadm in roadms:
|
||||
if power_mode:
|
||||
@@ -165,7 +165,7 @@ def target_power(dp_from_gain, network, node, equipment): #get_fiber_dp
|
||||
#print(f'{repr(node)} delta power in:\n{dp}dB')
|
||||
|
||||
return dp
|
||||
|
||||
|
||||
|
||||
def prev_node_generator(network, node):
|
||||
"""fused spans interest:
|
||||
@@ -187,7 +187,7 @@ def next_node_generator(network, node):
|
||||
yield next_node
|
||||
yield from next_node_generator(network, next_node)
|
||||
else:
|
||||
StopIteration
|
||||
StopIteration
|
||||
|
||||
def span_loss(network, node):
|
||||
"""Fused span interest:
|
||||
@@ -197,10 +197,10 @@ def span_loss(network, node):
|
||||
prev_node = next(n for n in network.predecessors(node))
|
||||
if isinstance(prev_node, Fused):
|
||||
loss += sum(n.loss for n in prev_node_generator(network, node))
|
||||
except StopIteration:
|
||||
except StopIteration:
|
||||
pass
|
||||
try:
|
||||
next_node = next(n for n in network.successors(node))
|
||||
next_node = next(n for n in network.successors(node))
|
||||
if isinstance(next_node, Fused):
|
||||
loss += sum(n.loss for n in next_node_generator(network, node))
|
||||
except StopIteration:
|
||||
@@ -209,7 +209,7 @@ def span_loss(network, node):
|
||||
|
||||
def find_first_node(network, node):
|
||||
"""Fused node interest:
|
||||
returns the 1st node at the origin of a succession of fused nodes
|
||||
returns the 1st node at the origin of a succession of fused nodes
|
||||
(aka no amp in between)"""
|
||||
this_node = node
|
||||
for this_node in prev_node_generator(network, node):
|
||||
@@ -218,7 +218,7 @@ def find_first_node(network, node):
|
||||
|
||||
def find_last_node(network, node):
|
||||
"""Fused node interest:
|
||||
returns the last node in a succession of fused nodes
|
||||
returns the last node in a succession of fused nodes
|
||||
(aka no amp in between)"""
|
||||
this_node = node
|
||||
for this_node in next_node_generator(network, node):
|
||||
@@ -231,7 +231,7 @@ def set_amplifier_voa(amp, pref_total_db, power_mode):
|
||||
if power_mode:
|
||||
gain_target = amp.operational.gain_target
|
||||
pout = pref_total_db + amp.dp_db
|
||||
voa = min(amp.params.p_max-pout,
|
||||
voa = min(amp.params.p_max-pout,
|
||||
amp.params.gain_flatmax-amp.operational.gain_target)
|
||||
voa = round2float(max(voa, 0), 0.5) - VOA_MARGIN if amp.params.out_voa_auto else 0
|
||||
amp.dp_db = amp.dp_db + voa
|
||||
@@ -283,7 +283,7 @@ def set_egress_amplifier(network, roadm, equipment, pref_total_db):
|
||||
|
||||
|
||||
def add_egress_amplifier(network, node):
|
||||
next_nodes = [n for n in network.successors(node)
|
||||
next_nodes = [n for n in network.successors(node)
|
||||
if not (isinstance(n, Transceiver) or isinstance(n, Fused) or isinstance(n, Edfa))]
|
||||
#no amplification for fused spans or TRX
|
||||
for i, next_node in enumerate(next_nodes):
|
||||
@@ -393,16 +393,16 @@ def build_network(network, equipment, pref_ch_db, pref_total_db):
|
||||
padding = default_span_data.padding
|
||||
|
||||
#set raodm loss for gain_mode before to build network
|
||||
set_roadm_loss(network, equipment, pref_ch_db)
|
||||
set_roadm_loss(network, equipment, pref_ch_db)
|
||||
fibers = [f for f in network.nodes() if isinstance(f, Fiber)]
|
||||
add_connector_loss(fibers, con_in, con_out, default_span_data.EOL)
|
||||
add_fiber_padding(network, fibers, padding)
|
||||
# don't group split fiber and add amp in the same loop
|
||||
# don't group split fiber and add amp in the same loop
|
||||
# =>for code clarity (at the expense of speed):
|
||||
for fiber in fibers:
|
||||
split_fiber(network, fiber, bounds, target_length, equipment)
|
||||
|
||||
amplified_nodes = [n for n in network.nodes()
|
||||
amplified_nodes = [n for n in network.nodes()
|
||||
if isinstance(n, Fiber) or isinstance(n, Roadm)]
|
||||
for node in amplified_nodes:
|
||||
add_egress_amplifier(network, node)
|
||||
@@ -411,9 +411,9 @@ def build_network(network, equipment, pref_ch_db, pref_total_db):
|
||||
for roadm in roadms:
|
||||
set_egress_amplifier(network, roadm, equipment, pref_total_db)
|
||||
|
||||
#support older json input topology wo Roadms:
|
||||
if len(roadms) == 0:
|
||||
#support older json input topology wo Roadms:
|
||||
if len(roadms) == 0:
|
||||
trx = [t for t in network.nodes() if isinstance(t, Transceiver)]
|
||||
for t in trx:
|
||||
set_egress_amplifier(network, t, equipment, pref_total_db)
|
||||
set_egress_amplifier(network, t, equipment, pref_total_db)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
# TelecomInfraProject/gnpy/examples
|
||||
# Module name : path_requests_run.py
|
||||
# Version :
|
||||
# Version :
|
||||
# License : BSD 3-Clause Licence
|
||||
# Copyright (c) 2018, Telecom Infra Project
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
@author: jeanluc-auge
|
||||
read json request file in accordance with:
|
||||
Yang model for requesting Path Computation
|
||||
draft-ietf-teas-yang-path-computation-01.txt.
|
||||
draft-ietf-teas-yang-path-computation-01.txt.
|
||||
and returns path results in terms of path and feasibility
|
||||
|
||||
"""
|
||||
@@ -76,8 +76,8 @@ class Result_element(Element):
|
||||
self.computed_path = computed_path
|
||||
hop_type = []
|
||||
for e in computed_path :
|
||||
if isinstance(e, Transceiver) :
|
||||
hop_type.append(' - '.join([path_request.tsp,path_request.tsp_mode]))
|
||||
if isinstance(e, Transceiver) :
|
||||
hop_type.append(' - '.join([path_request.tsp,path_request.tsp_mode]))
|
||||
else:
|
||||
hop_type.append('not recorded')
|
||||
self.hop_type = hop_type
|
||||
@@ -203,10 +203,10 @@ class Result_element(Element):
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@property
|
||||
def json(self):
|
||||
return self.pathresult
|
||||
return self.pathresult
|
||||
|
||||
def compute_constrained_path(network, req):
|
||||
trx = [n for n in network.nodes() if isinstance(n, Transceiver)]
|
||||
@@ -226,7 +226,7 @@ def compute_constrained_path(network, req):
|
||||
node = next(el for el in roadm if el.uid == f'roadm {n}')
|
||||
except StopIteration:
|
||||
try:
|
||||
node = next(el for el in edfa
|
||||
node = next(el for el in edfa
|
||||
if el.uid.startswith(f'egress edfa in {n}'))
|
||||
except StopIteration:
|
||||
msg = f'could not find node : {n} in network topology: \
|
||||
@@ -257,7 +257,7 @@ def compute_constrained_path(network, req):
|
||||
# target=next(el for el in trx if el.uid == req.destination)):
|
||||
# print([e.uid for e in p if isinstance(e,Roadm)])
|
||||
|
||||
return total_path
|
||||
return total_path
|
||||
|
||||
def propagate(path, req, equipment, show=False):
|
||||
#update roadm loss in case of power sweep (power mode only)
|
||||
@@ -269,13 +269,13 @@ def propagate(path, req, equipment, show=False):
|
||||
si = el(si)
|
||||
if show :
|
||||
print(el)
|
||||
return path
|
||||
return path
|
||||
|
||||
|
||||
def jsontocsv(json_data,equipment,fileout):
|
||||
# read json path result file in accordance with:
|
||||
# Yang model for requesting Path Computation
|
||||
# draft-ietf-teas-yang-path-computation-01.txt.
|
||||
# draft-ietf-teas-yang-path-computation-01.txt.
|
||||
# and write results in an CSV file
|
||||
|
||||
mywriter = writer(fileout)
|
||||
@@ -290,32 +290,32 @@ def jsontocsv(json_data,equipment,fileout):
|
||||
['path-route-object']['unnumbered-hop']['node-id']
|
||||
destination = p['path-properties']['path-route-objects'][-1]\
|
||||
['path-route-object']['unnumbered-hop']['node-id']
|
||||
pth = ' | '.join([ e['path-route-object']['unnumbered-hop']['node-id']
|
||||
pth = ' | '.join([ e['path-route-object']['unnumbered-hop']['node-id']
|
||||
for e in p['path-properties']['path-route-objects']])
|
||||
|
||||
[tsp,mode] = p['path-properties']['path-route-objects'][0]\
|
||||
['path-route-object']['unnumbered-hop']['hop-type'].split(' - ')
|
||||
|
||||
|
||||
# find the min acceptable OSNR, baud rate from the eqpt library based on tsp (tupe) and mode (format)
|
||||
try:
|
||||
[minosnr, baud_rate] = next([m['OSNR'] , m['baud_rate']]
|
||||
[minosnr, baud_rate] = next([m['OSNR'] , m['baud_rate']]
|
||||
for m in equipment['Transceiver'][tsp].mode if m['format']==mode)
|
||||
|
||||
# for debug
|
||||
# print(f'coucou {baud_rate}')
|
||||
except IndexError:
|
||||
msg = f'could not find tsp : {self.tsp} with mode: {self.tsp_mode} in eqpt library'
|
||||
|
||||
|
||||
raise ValueError(msg)
|
||||
output_snr = next(e['accumulative-value']
|
||||
output_snr = next(e['accumulative-value']
|
||||
for e in p['path-properties']['path-metric'] if e['metric-type'] == 'SNR@0.1nm')
|
||||
output_snrbandwidth = next(e['accumulative-value']
|
||||
output_snrbandwidth = next(e['accumulative-value']
|
||||
for e in p['path-properties']['path-metric'] if e['metric-type'] == 'SNR@bandwidth')
|
||||
output_osnr = next(e['accumulative-value']
|
||||
output_osnr = next(e['accumulative-value']
|
||||
for e in p['path-properties']['path-metric'] if e['metric-type'] == 'OSNR@0.1nm')
|
||||
output_osnrbandwidth = next(e['accumulative-value']
|
||||
output_osnrbandwidth = next(e['accumulative-value']
|
||||
for e in p['path-properties']['path-metric'] if e['metric-type'] == 'OSNR@bandwidth')
|
||||
power = next(e['accumulative-value']
|
||||
power = next(e['accumulative-value']
|
||||
for e in p['path-properties']['path-metric'] if e['metric-type'] == 'reference_power')
|
||||
if isinstance(output_snr, str):
|
||||
isok = ''
|
||||
@@ -333,5 +333,5 @@ def jsontocsv(json_data,equipment,fileout):
|
||||
output_osnr,
|
||||
output_snrbandwidth,
|
||||
output_snr,
|
||||
isok
|
||||
))
|
||||
isok
|
||||
))
|
||||
|
||||
@@ -61,10 +61,10 @@ def write_csv(obj, filename):
|
||||
#main header
|
||||
w.writerow([data_key])
|
||||
#sub headers:
|
||||
headers = [_ for _ in data_list[0].keys()]
|
||||
headers = [_ for _ in data_list[0].keys()]
|
||||
w.writerow(headers)
|
||||
for data_dict in data_list:
|
||||
w.writerow([_ for _ in data_dict.values()])
|
||||
w.writerow([_ for _ in data_dict.values()])
|
||||
|
||||
def c():
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user