Fused spans class and edfa gain adaptation

*new Fused spans class to support the connection between 2 fibers
without amplification
*add_egress_amplifier adjust the edfa gain to compensate the loss
of n fused spans
*eqpt not found in eqpt library is caught and stop the code

Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>

code fix for the eqpt sheet reading in xls parser

Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>

amplifier design and eqpt parser code fix

Signed-off-by: Jean-Luc Auge <jeanluc.auge@orange.com>
This commit is contained in:
Jean-Luc Auge
2018-04-24 15:13:11 +02:00
parent 9720c979b3
commit af90a6658e
8 changed files with 229 additions and 283 deletions

View File

@@ -115,14 +115,21 @@ def convert_file(input_filename, filter_region=[]):
'latitude': x.latitude,
'longitude': x.longitude}},
'type': 'Transceiver'}
for x in nodes if x.node_type.lower() == 'roadm'] +
for x in nodes_by_city.values() if x.node_type.lower() == 'roadm'] +
[{'uid': f'roadm {x.city}',
'metadata': {'location': {'city': x.city,
'region': x.region,
'latitude': x.latitude,
'longitude': x.longitude}},
'type': 'Roadm'}
for x in nodes if x.node_type.lower() == 'roadm'] +
for x in nodes_by_city.values() if x.node_type.lower() == 'roadm'] +
[{'uid': f'fused spans in {x.city}',
'metadata': {'location': {'city': x.city,
'region': x.region,
'latitude': x.latitude,
'longitude': x.longitude}},
'type': '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])},
@@ -143,7 +150,7 @@ def convert_file(input_filename, filter_region=[]):
'loss_coef': x.west_lineic}
}
for x in links] +
[{'uid': f'egress edfa in {e.from_city}',
[{'uid': f'egress edfa in {e.from_city} to {e.to_city}',
'metadata': {'location': {'city': nodes_by_city[e.from_city].city,
'region': nodes_by_city[e.from_city].region,
'latitude': nodes_by_city[e.from_city].latitude,
@@ -154,7 +161,7 @@ def convert_file(input_filename, filter_region=[]):
'tilt_target': e.egress_amp_tilt}
}
for e in eqpts if e.egress_amp_type.lower() != ''] +
[{'uid': f'ingress edfa in {e.from_city}',
[{'uid': f'ingress edfa in {e.from_city} to {e.to_city}',
'metadata': {'location': {'city': nodes_by_city[e.from_city].city,
'region': nodes_by_city[e.from_city].region,
'latitude': nodes_by_city[e.from_city].latitude,
@@ -172,10 +179,10 @@ def convert_file(input_filename, filter_region=[]):
list(chain.from_iterable(zip(
[{'from_node': f'trx {x.city}',
'to_node': f'roadm {x.city}'}
for x in nodes if x.node_type.lower()=='roadm'],
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 if x.node_type.lower()=='roadm'])))
for x in nodes_by_city.values() if x.node_type.lower()=='roadm'])))
}
#print(dumps(data, indent=2))
@@ -246,7 +253,7 @@ def eqpt_connection_by_city(city_name):
# Then len(other_cities) == 2
for i in range(2):
from_ = fiber_link(other_cities[i], city_name)
in_ = eqpt_in_city_from_city(city_name, other_cities[i])
in_ = eqpt_in_city_to_city(city_name, other_cities[i],"ingress")
to_ = fiber_link(city_name, other_cities[1-i])
subdata += connect_eqpt(from_, in_, to_)
elif nodes_by_city[city_name].node_type.lower() == 'roadm':
@@ -257,7 +264,7 @@ def eqpt_connection_by_city(city_name):
subdata += connect_eqpt(from_, in_, to_)
from_ = fiber_link(other_city, city_name)
in_ = eqpt_in_city_from_city(city_name, other_city)
in_ = eqpt_in_city_to_city(city_name, other_city, "ingress")
to_ = f'roadm {city_name}'
subdata += connect_eqpt(from_, in_, to_)
return subdata
@@ -273,27 +280,24 @@ def connect_eqpt(from_, in_, to_):
return connections
def eqpt_in_city_from_city(in_city, from_city):
eqpt = eqpts_by_city.get(in_city)
def eqpt_in_city_to_city(in_city, to_city, direction ="egress"):
rev_direction = "ingress" if direction == "egress" else "egress"
amp_direction = direction + "_amp_type"
amp_rev_direction = rev_direction + "_amp_type"
return_eqpt = ''
if eqpt != None:
for e in eqpt:
if e.to_city == from_city and e.ingress_amp_type != '':
return_eqpt = f'ingress edfa in {in_city}'
elif nodes_by_city[in_city].node_type.lower() == 'ila' and e.egress_amp_type != '':
return_eqpt = f'egress edfa in {in_city}'
return return_eqpt
def eqpt_in_city_to_city(in_city, to_city):
eqpt = eqpts_by_city.get(in_city)
return_eqpt = ''
if eqpt != None:
for e in eqpt:
if e.to_city == to_city and e.ingress_amp_type != '':
return_eqpt = f'egress edfa in {in_city}'
elif nodes_by_city[in_city].node_type == 'ila' and e.egress_amp_type != '':
return_eqpt = f'ingress edfa in {in_city}'
eqpt = (e for e in eqpts_by_city.get(in_city) if e!=None)
for e in eqpt:
if nodes_by_city[in_city].node_type.lower() == 'roadm':
if e.to_city == to_city and getattr(e, amp_direction) != '':
return_eqpt = f'{direction} edfa in {e.from_city} to {e.to_city}'
elif nodes_by_city[in_city].node_type.lower() == 'ila':
if e.to_city != to_city:
direction = rev_direction
amp_direction = amp_rev_direction
if getattr(e, amp_direction) != '':
return_eqpt = f'{direction} edfa in {e.from_city} to {e.to_city}'
if nodes_by_city[in_city].node_type.lower() == 'fused':
return_eqpt = f'fused spans in {in_city}'
return return_eqpt
@@ -309,8 +313,8 @@ def fiber_dest_from_source(city_name):
def fiber_link(from_city, to_city):
link = links_by_city[from_city]
source_dest = (from_city, to_city)
link = links_by_city[from_city]
l = next(l for l in link if l.from_city in source_dest and l.to_city in source_dest)
if l.from_city == from_city:
fiber = f'fiber ({l.from_city}{l.to_city})-{l.east_cable}'

View File

@@ -1,15 +1,23 @@
{ "Edfa":[{
"type_variety": "std_medium_gain",
"type_variety": "CienaDB_medium_gain",
"gain_flatmax": 25,
"gain_min": 15,
"p_max": 21,
"advanced_config_from_json": "std_medium_gain_advanced_config.json"
},
{
"type_variety": "std_medium_gain",
"gain_flatmax": 23,
"gain_min": 13,
"p_max": 23,
"nf_min": 6,
"nf_max": 9
},
{
"type_variety": "std_low_gain",
"gain_flatmax": 19,
"gain_min": 12,
"p_max": 22,
"gain_flatmax": 17,
"gain_min": 6,
"p_max": 23,
"nf_min": 6.5,
"nf_max": 10
}

View File

@@ -121,7 +121,31 @@
"type": "Roadm"
},
{
"uid": "fiber (Lannion_CAS \u2192 Corlay)-F061",
"uid": "fused spans in Loudeac",
"metadata": {
"location": {
"city": "Loudeac",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Fused"
},
{
"uid": "fused spans in Morlaix",
"metadata": {
"location": {
"city": "Morlaix",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Fused"
},
{
"uid": "fiber (Lannion_CAS \u2192 Corlay)-",
"metadata": {
"location": {
"latitude": 0.0,
@@ -137,7 +161,7 @@
}
},
{
"uid": "fiber (Corlay \u2192 Loudeac)-F010",
"uid": "fiber (Corlay \u2192 Loudeac)-",
"metadata": {
"location": {
"latitude": 0.0,
@@ -153,7 +177,7 @@
}
},
{
"uid": "fiber (Loudeac \u2192 Lorient_KMA)-F010",
"uid": "fiber (Loudeac \u2192 Lorient_KMA)-",
"metadata": {
"location": {
"latitude": 0.0,
@@ -169,7 +193,7 @@
}
},
{
"uid": "fiber (Lorient_KMA \u2192 Vannes_KBE)-F054",
"uid": "fiber (Lorient_KMA \u2192 Vannes_KBE)-",
"metadata": {
"location": {
"latitude": 0.0,
@@ -185,7 +209,7 @@
}
},
{
"uid": "fiber (Lorient_KMA \u2192 Vannes_KBE)-F055",
"uid": "fiber (Lorient_KMA \u2192 Vannes_KBE)-",
"metadata": {
"location": {
"latitude": 0.0,
@@ -201,7 +225,7 @@
}
},
{
"uid": "fiber (Lannion_CAS \u2192 Stbrieuc)-F056",
"uid": "fiber (Lannion_CAS \u2192 Stbrieuc)-",
"metadata": {
"location": {
"latitude": 0.0,
@@ -217,7 +241,7 @@
}
},
{
"uid": "fiber (Stbrieuc \u2192 Rennes_STA)-F057",
"uid": "fiber (Stbrieuc \u2192 Rennes_STA)-",
"metadata": {
"location": {
"latitude": 0.0,
@@ -233,7 +257,7 @@
}
},
{
"uid": "fiber (Lannion_CAS \u2192 Morlaix)-F059",
"uid": "fiber (Lannion_CAS \u2192 Morlaix)-",
"metadata": {
"location": {
"latitude": 0.0,
@@ -249,7 +273,7 @@
}
},
{
"uid": "fiber (Morlaix \u2192 Brest_KLA)-F060",
"uid": "fiber (Morlaix \u2192 Brest_KLA)-",
"metadata": {
"location": {
"latitude": 0.0,
@@ -265,7 +289,7 @@
}
},
{
"uid": "fiber (Corlay \u2192 Lannion_CAS)-F061",
"uid": "fiber (Corlay \u2192 Lannion_CAS)-",
"metadata": {
"location": {
"latitude": 0.0,
@@ -281,7 +305,7 @@
}
},
{
"uid": "fiber (Loudeac \u2192 Corlay)-F010",
"uid": "fiber (Loudeac \u2192 Corlay)-",
"metadata": {
"location": {
"latitude": 0.0,
@@ -297,7 +321,7 @@
}
},
{
"uid": "fiber (Lorient_KMA \u2192 Loudeac)-F010",
"uid": "fiber (Lorient_KMA \u2192 Loudeac)-",
"metadata": {
"location": {
"latitude": 0.0,
@@ -313,7 +337,7 @@
}
},
{
"uid": "fiber (Vannes_KBE \u2192 Lorient_KMA)-F054",
"uid": "fiber (Vannes_KBE \u2192 Lorient_KMA)-",
"metadata": {
"location": {
"latitude": 0.0,
@@ -329,7 +353,7 @@
}
},
{
"uid": "fiber (Vannes_KBE \u2192 Lorient_KMA)-F055",
"uid": "fiber (Vannes_KBE \u2192 Lorient_KMA)-",
"metadata": {
"location": {
"latitude": 0.0,
@@ -345,7 +369,7 @@
}
},
{
"uid": "fiber (Stbrieuc \u2192 Lannion_CAS)-F056",
"uid": "fiber (Stbrieuc \u2192 Lannion_CAS)-",
"metadata": {
"location": {
"latitude": 0.0,
@@ -361,7 +385,7 @@
}
},
{
"uid": "fiber (Rennes_STA \u2192 Stbrieuc)-F057",
"uid": "fiber (Rennes_STA \u2192 Stbrieuc)-",
"metadata": {
"location": {
"latitude": 0.0,
@@ -377,7 +401,7 @@
}
},
{
"uid": "fiber (Morlaix \u2192 Lannion_CAS)-F059",
"uid": "fiber (Morlaix \u2192 Lannion_CAS)-",
"metadata": {
"location": {
"latitude": 0.0,
@@ -387,13 +411,13 @@
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 70.0,
"length": 75.0,
"length_units": "km",
"loss_coef": 0.2
}
},
{
"uid": "fiber (Brest_KLA \u2192 Morlaix)-F060",
"uid": "fiber (Brest_KLA \u2192 Morlaix)-",
"metadata": {
"location": {
"latitude": 0.0,
@@ -403,291 +427,139 @@
"type": "Fiber",
"type_variety": "SSMF",
"params": {
"length": 70.0,
"length": 80.0,
"length_units": "km",
"loss_coef": 0.2
}
},
{
"uid": "egress edfa in Lannion_CAS",
"metadata": {
"location": {
"city": "Lannion_CAS",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": 20.0,
"tilt_target": 0
}
},
{
"uid": "egress edfa in Lannion_CAS",
"metadata": {
"location": {
"city": "Lannion_CAS",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": 20.0,
"tilt_target": 0.0
}
},
{
"uid": "egress edfa in Lannion_CAS",
"metadata": {
"location": {
"city": "Lannion_CAS",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": 20.0,
"tilt_target": 0
}
},
{
"uid": "egress edfa in Corlay",
"metadata": {
"location": {
"city": "Corlay",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": 12.0,
"tilt_target": 0.0
}
},
{
"uid": "ingress edfa in Lannion_CAS",
"metadata": {
"location": {
"city": "Lannion_CAS",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": 20.0,
"tilt_target": 0
}
},
{
"uid": "ingress edfa in Lannion_CAS",
"metadata": {
"location": {
"city": "Lannion_CAS",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": 12.0,
"tilt_target": 0.0
}
},
{
"uid": "ingress edfa in Lannion_CAS",
"metadata": {
"location": {
"city": "Lannion_CAS",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": 20.0,
"tilt_target": 0
}
},
{
"uid": "ingress edfa in Corlay",
"metadata": {
"location": {
"city": "Corlay",
"region": "RLD",
"latitude": 0,
"longitude": 0
}
},
"type": "Edfa",
"type_variety": "std_low_gain",
"operational": {
"gain_target": 11.0,
"tilt_target": 0.0
}
}
],
"connections": [
{
"from_node": "roadm Lannion_CAS",
"to_node": "egress edfa in Lannion_CAS"
"to_node": "fiber (Lannion_CAS \u2192 Corlay)-"
},
{
"from_node": "egress edfa in Lannion_CAS",
"to_node": "fiber (Lannion_CAS \u2192 Corlay)-F061"
},
{
"from_node": "fiber (Corlay \u2192 Lannion_CAS)-F061",
"to_node": "ingress edfa in Lannion_CAS"
},
{
"from_node": "ingress edfa in Lannion_CAS",
"from_node": "fiber (Corlay \u2192 Lannion_CAS)-",
"to_node": "roadm Lannion_CAS"
},
{
"from_node": "roadm Lannion_CAS",
"to_node": "egress edfa in Lannion_CAS"
"to_node": "fiber (Lannion_CAS \u2192 Stbrieuc)-"
},
{
"from_node": "egress edfa in Lannion_CAS",
"to_node": "fiber (Lannion_CAS \u2192 Stbrieuc)-F056"
},
{
"from_node": "fiber (Stbrieuc \u2192 Lannion_CAS)-F056",
"to_node": "ingress edfa in Lannion_CAS"
},
{
"from_node": "ingress edfa in Lannion_CAS",
"from_node": "fiber (Stbrieuc \u2192 Lannion_CAS)-",
"to_node": "roadm Lannion_CAS"
},
{
"from_node": "roadm Lannion_CAS",
"to_node": "egress edfa in Lannion_CAS"
"to_node": "fiber (Lannion_CAS \u2192 Morlaix)-"
},
{
"from_node": "egress edfa in Lannion_CAS",
"to_node": "fiber (Lannion_CAS \u2192 Morlaix)-F059"
},
{
"from_node": "fiber (Morlaix \u2192 Lannion_CAS)-F059",
"to_node": "ingress edfa in Lannion_CAS"
},
{
"from_node": "ingress edfa in Lannion_CAS",
"from_node": "fiber (Morlaix \u2192 Lannion_CAS)-",
"to_node": "roadm Lannion_CAS"
},
{
"from_node": "fiber (Lannion_CAS \u2192 Corlay)-F061",
"to_node": "egress edfa in Corlay"
"from_node": "fiber (Lannion_CAS \u2192 Corlay)-",
"to_node": "fiber (Corlay \u2192 Loudeac)-"
},
{
"from_node": "egress edfa in Corlay",
"to_node": "fiber (Corlay \u2192 Loudeac)-F010"
"from_node": "fiber (Loudeac \u2192 Corlay)-",
"to_node": "fiber (Corlay \u2192 Lannion_CAS)-"
},
{
"from_node": "fiber (Loudeac \u2192 Corlay)-F010",
"to_node": "ingress edfa in Corlay"
"from_node": "fiber (Corlay \u2192 Loudeac)-",
"to_node": "fused spans in Loudeac"
},
{
"from_node": "ingress edfa in Corlay",
"to_node": "fiber (Corlay \u2192 Lannion_CAS)-F061"
"from_node": "fused spans in Loudeac",
"to_node": "fiber (Loudeac \u2192 Lorient_KMA)-"
},
{
"from_node": "fiber (Corlay \u2192 Loudeac)-F010",
"to_node": "fiber (Loudeac \u2192 Lorient_KMA)-F010"
"from_node": "fiber (Lorient_KMA \u2192 Loudeac)-",
"to_node": "fused spans in Loudeac"
},
{
"from_node": "fiber (Lorient_KMA \u2192 Loudeac)-F010",
"to_node": "fiber (Loudeac \u2192 Corlay)-F010"
"from_node": "fused spans in Loudeac",
"to_node": "fiber (Loudeac \u2192 Corlay)-"
},
{
"from_node": "roadm Lorient_KMA",
"to_node": "fiber (Lorient_KMA \u2192 Loudeac)-F010"
"to_node": "fiber (Lorient_KMA \u2192 Loudeac)-"
},
{
"from_node": "fiber (Loudeac \u2192 Lorient_KMA)-F010",
"from_node": "fiber (Loudeac \u2192 Lorient_KMA)-",
"to_node": "roadm Lorient_KMA"
},
{
"from_node": "roadm Lorient_KMA",
"to_node": "fiber (Lorient_KMA \u2192 Vannes_KBE)-F054"
"to_node": "fiber (Lorient_KMA \u2192 Vannes_KBE)-"
},
{
"from_node": "fiber (Vannes_KBE \u2192 Lorient_KMA)-F054",
"from_node": "fiber (Vannes_KBE \u2192 Lorient_KMA)-",
"to_node": "roadm Lorient_KMA"
},
{
"from_node": "roadm Lorient_KMA",
"to_node": "fiber (Lorient_KMA \u2192 Vannes_KBE)-F054"
"to_node": "fiber (Lorient_KMA \u2192 Vannes_KBE)-"
},
{
"from_node": "fiber (Vannes_KBE \u2192 Lorient_KMA)-F054",
"from_node": "fiber (Vannes_KBE \u2192 Lorient_KMA)-",
"to_node": "roadm Lorient_KMA"
},
{
"from_node": "roadm Vannes_KBE",
"to_node": "fiber (Vannes_KBE \u2192 Lorient_KMA)-F054"
"to_node": "fiber (Vannes_KBE \u2192 Lorient_KMA)-"
},
{
"from_node": "fiber (Lorient_KMA \u2192 Vannes_KBE)-F054",
"from_node": "fiber (Lorient_KMA \u2192 Vannes_KBE)-",
"to_node": "roadm Vannes_KBE"
},
{
"from_node": "roadm Vannes_KBE",
"to_node": "fiber (Vannes_KBE \u2192 Lorient_KMA)-F054"
"to_node": "fiber (Vannes_KBE \u2192 Lorient_KMA)-"
},
{
"from_node": "fiber (Lorient_KMA \u2192 Vannes_KBE)-F054",
"from_node": "fiber (Lorient_KMA \u2192 Vannes_KBE)-",
"to_node": "roadm Vannes_KBE"
},
{
"from_node": "fiber (Lannion_CAS \u2192 Stbrieuc)-F056",
"to_node": "fiber (Stbrieuc \u2192 Rennes_STA)-F057"
"from_node": "fiber (Lannion_CAS \u2192 Stbrieuc)-",
"to_node": "fiber (Stbrieuc \u2192 Rennes_STA)-"
},
{
"from_node": "fiber (Rennes_STA \u2192 Stbrieuc)-F057",
"to_node": "fiber (Stbrieuc \u2192 Lannion_CAS)-F056"
"from_node": "fiber (Rennes_STA \u2192 Stbrieuc)-",
"to_node": "fiber (Stbrieuc \u2192 Lannion_CAS)-"
},
{
"from_node": "roadm Rennes_STA",
"to_node": "fiber (Rennes_STA \u2192 Stbrieuc)-F057"
"to_node": "fiber (Rennes_STA \u2192 Stbrieuc)-"
},
{
"from_node": "fiber (Stbrieuc \u2192 Rennes_STA)-F057",
"from_node": "fiber (Stbrieuc \u2192 Rennes_STA)-",
"to_node": "roadm Rennes_STA"
},
{
"from_node": "fiber (Lannion_CAS \u2192 Morlaix)-F059",
"to_node": "fiber (Morlaix \u2192 Brest_KLA)-F060"
"from_node": "fiber (Lannion_CAS \u2192 Morlaix)-",
"to_node": "fused spans in Morlaix"
},
{
"from_node": "fiber (Brest_KLA \u2192 Morlaix)-F060",
"to_node": "fiber (Morlaix \u2192 Lannion_CAS)-F059"
"from_node": "fused spans in Morlaix",
"to_node": "fiber (Morlaix \u2192 Brest_KLA)-"
},
{
"from_node": "fiber (Brest_KLA \u2192 Morlaix)-",
"to_node": "fused spans in Morlaix"
},
{
"from_node": "fused spans in Morlaix",
"to_node": "fiber (Morlaix \u2192 Lannion_CAS)-"
},
{
"from_node": "roadm Brest_KLA",
"to_node": "fiber (Brest_KLA \u2192 Morlaix)-F060"
"to_node": "fiber (Brest_KLA \u2192 Morlaix)-"
},
{
"from_node": "fiber (Morlaix \u2192 Brest_KLA)-F060",
"from_node": "fiber (Morlaix \u2192 Brest_KLA)-",
"to_node": "roadm Brest_KLA"
},
{

Binary file not shown.

View File

@@ -11,7 +11,8 @@ propagates a 96 channels comb
from gnpy.core.utils import load_json
from convert import convert_file
from gnpy.core.equipment import *
from gnpy.core.equipment import read_eqpt_library
from gnpy.core.utils import db2lin, lin2db
from argparse import ArgumentParser
from sys import exit
from pathlib import Path
@@ -81,11 +82,6 @@ def main(args):
network = network_from_json(json_data)
build_network(network)
spacing = 0.05 #THz
si = SpectralInformation() # !! SI units W, Hz
si = si.update(carriers=tuple(Channel(f, (191.3+spacing*f)*1e12,
32e9, 0.15, Power(1e-3, 0, 0)) for f in range(1,97)))
trx = [n for n in network.nodes() if isinstance(n, Transceiver)]
if args.list>=1:
print(*[el.uid for el in trx], sep='\n')
@@ -104,10 +100,17 @@ def main(args):
path = dijkstra_path(network, source, sink)
print(f'There are {len(path)} network elements between {source} and {sink}')
for el in path:
si = el(si)
print(el)
for p in range(0,1): #change range to sweep results across several powers
p=db2lin(p)*1e-3
spacing = 0.05 #THz
si = SpectralInformation() # !! SI units W, Hz
si = si.update(carriers=tuple(Channel(f, (191.3+spacing*f)*1e12,
32e9, 0.15, Power(p, 0, 0)) for f in range(1,80)))
for el in path:
si = el(si)
print(el) #remove this line when sweeping across several powers
print(f'\n Transmission result for input power = {lin2db(p*1e3)}dBm :')
print(sink)
#plot_network_graph(network, path, source, sink)

View File

@@ -34,6 +34,7 @@ class Transceiver(Node):
self.osnr_ase = None
self.osnr_nli = None
self.snr = None
self.passive = False
def _calc_snr(self, spectral_info):
ase = [c.power.ase for c in spectral_info.carriers]
@@ -67,7 +68,7 @@ class Transceiver(Node):
osnr_ase_01nm = round(np.mean(self.osnr_ase_01nm), 2)
return '\n'.join([f'{type(self).__name__} {self.uid}',
f' OSNR ASE (1nm): {np.mean(self.osnr_ase_01nm):.2f}',
f' OSNR ASE (0.1nm): {np.mean(self.osnr_ase_01nm):.2f}',
f' OSNR ASE (signal bw): {np.mean(self.osnr_ase):.2f}',
f' SNR total (signal bw): {np.mean(snr):.2f}'])
@@ -79,6 +80,34 @@ class Roadm(Node):
def __init__(self, config):
super().__init__(config)
self.loss = 20 #dB
self.passive = True
def __repr__(self):
return f'{type(self).__name__}(uid={self.uid!r}, loss={self.loss!r})'
def __str__(self):
return '\n'.join([f'{type(self).__name__} {self.uid}',
f' loss (dB): {self.loss:.2f}'])
def propagate(self, *carriers):
attenuation = db2lin(self.loss)
for carrier in carriers:
pwr = carrier.power
pwr = pwr._replace(signal=pwr.signal/attenuation,
nonlinear_interference=pwr.nli/attenuation,
amplified_spontaneous_emission=pwr.ase/attenuation)
yield carrier._replace(power=pwr)
def __call__(self, spectral_info):
carriers = tuple(self.propagate(*spectral_info.carriers))
return spectral_info.update(carriers=carriers)
class Fused(Node):
def __init__(self, config):
super().__init__(config)
self.loss = 1 #dB
self.passive = True
def __repr__(self):
return f'{type(self).__name__}(uid={self.uid!r}, loss={self.loss!r})'
@@ -111,6 +140,7 @@ class Fiber(Node):
self.dispersion = self.params.dispersion #s/m/m
self.gamma = self.params.gamma #1/W/m
self.loss = self.loss_coef * self.length #dB loss: useful for polymorphism (roadm, fiber, att)
self.passive = True
#TODO discuss factor 2 in the linear lineic attenuation
def __repr__(self):
@@ -229,10 +259,11 @@ class Edfa(Node):
self.gprofile = None
self.pin_db = None
self.pout_db = None
self.passive = False
def __repr__(self):
return (f'{type(self).__name__}(uid={self.uid!r}, '
f'type_variety={self.type_variety!r}, '
f'type_variety={self.config.type_variety!r}, '
f'interpol_dgt={self.interpol_dgt!r}, '
f'interpol_gain_ripple={self.interpol_gain_ripple!r}, '
f'interpol_nf_ripple={self.interpol_nf_ripple!r}, '

View File

@@ -109,6 +109,7 @@ def get_eqpt_params(eqpt_name):
del eqpt_config['type_variety']
except StopIteration as e:
print(f'cannot find eqpt {eqpt_name} in eqpt library')
sys.exit(1)
#TODO log it
return eqpt_config

View File

@@ -11,13 +11,13 @@ This module contains functions for constructing networks of network elements.
from networkx import DiGraph
from gnpy.core import elements
from gnpy.core.elements import Fiber, Edfa, Transceiver, Roadm
from gnpy.core.elements import Fiber, Edfa, Transceiver, Roadm, Fused
from gnpy.core.units import UNITS
MAX_SPAN_LENGTH = 125000
MAX_SPAN_LENGTH = 150000
TARGET_SPAN_LENGTH = 100000
MIN_SPAN_LENGTH = 75000
MIN_SPAN_LENGTH = 30000
def network_from_json(json_data):
@@ -90,26 +90,53 @@ def split_fiber(network, fiber):
return network
def select_edfa(ingress_span_loss):
#TODO select amplifier in eqpt_library based on gain, NF and power requirement
return "std_medium_gain"
def prev_fiber_node_generator(network, node):
"""fused spans interest:
iterate over all predecessors while they are Fiber type"""
prev_node = [n for n in network.predecessors(node)]
#fibers or fused spans so there is only 1 predecessor
iterate = len(prev_node) == 1 and (isinstance(prev_node, Fused) or isinstance(node, Fused))
if iterate:
yield prev_node[0]
yield from prev_fiber_node_generator(network, prev_node[0])
else:
StopIteration
def span_loss(network, node):
total_loss = node.loss if node.passive else 0
for n in prev_fiber_node_generator(network, node):
total_loss += n.loss
return total_loss
def add_egress_amplifier(network, node):
next_nodes = [n for n in network.successors(node)
if not (isinstance(n, Edfa) or isinstance(n, Transceiver))]
if not (isinstance(n, Transceiver) or isinstance(n, Fused))]
#no amplification for fused spans or TRX
i = 1
for next_node in next_nodes:
network.remove_edge(node, next_node)
uid = 'Edfa' + str(i)+ '_' + str(node.uid)
metadata = next_node.metadata
operational = {'gain_target': node.loss, 'tilt_target': 0}
edfa_variety_type = select_edfa(node.loss)
config = {'uid':uid, 'type': 'Edfa', 'metadata': metadata, \
'type_variety': edfa_variety_type, 'operational': operational}
new_edfa = Edfa(config)
network.add_node(new_edfa)
network.add_edge(node,new_edfa)
network.add_edge(new_edfa, next_node)
i +=1
for next_node in next_nodes:
if isinstance(next_node, Edfa):
if next_node.operational.gain_target == 0:
total_loss = span_loss(network, node)
next_node.operational.gain_target = total_loss
else:
network.remove_edge(node, next_node)
total_loss = span_loss(network, node)
print('loss', total_loss)
uid = 'Edfa' + str(i)+ '_' + str(node.uid)
metadata = next_node.metadata
operational = {'gain_target': total_loss, 'tilt_target': 0}
edfa_variety_type = select_edfa(total_loss)
config = {'uid':uid, 'type': 'Edfa', 'metadata': metadata, \
'type_variety': edfa_variety_type, 'operational': operational}
new_edfa = Edfa(config)
network.add_node(new_edfa)
network.add_edge(node,new_edfa)
network.add_edge(new_edfa, next_node)
i +=1
return network