From 8795c357ae12639f6f7626c7b814bccf5089b7c0 Mon Sep 17 00:00:00 2001 From: EstherLerouzic Date: Mon, 2 Jul 2018 17:23:58 +0100 Subject: [PATCH 1/8] Implementation of connector losses in the propagation function - connector losses can be part of the json description or not in any case a connector loss in and out is now part of the fiber class. if not present the default value is 0.0 dB - propagate function in Fiber class now has a first attenuation propagation step. output conn loos is integrated in the initial loop function. Signed-off-by: EstherLerouzic --- examples/meshTopologyExampleV2.json | 64 +++++++++++++++++++------- examples/meshTopologyExampleV2.xls | Bin 13824 -> 14336 bytes examples/transmission_main_example.py | 2 +- gnpy/core/convert.py | 8 +++- gnpy/core/elements.py | 35 ++++++++++++-- 5 files changed, 85 insertions(+), 24 deletions(-) diff --git a/examples/meshTopologyExampleV2.json b/examples/meshTopologyExampleV2.json index e0b46b29..dc972f62 100644 --- a/examples/meshTopologyExampleV2.json +++ b/examples/meshTopologyExampleV2.json @@ -205,7 +205,9 @@ "params": { "length": 20.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -221,7 +223,9 @@ "params": { "length": 50.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -237,7 +241,9 @@ "params": { "length": 60.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -253,7 +259,9 @@ "params": { "length": 10.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -269,7 +277,9 @@ "params": { "length": 60.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -285,7 +295,9 @@ "params": { "length": 65.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -301,7 +313,9 @@ "params": { "length": 40.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -317,7 +331,9 @@ "params": { "length": 35.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -333,7 +349,9 @@ "params": { "length": 20.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -349,7 +367,9 @@ "params": { "length": 50.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -365,7 +385,9 @@ "params": { "length": 60.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -381,7 +403,9 @@ "params": { "length": 10.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -397,7 +421,9 @@ "params": { "length": 60.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -413,7 +439,9 @@ "params": { "length": 65.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -429,7 +457,9 @@ "params": { "length": 40.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -445,7 +475,9 @@ "params": { "length": 35.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } } ], diff --git a/examples/meshTopologyExampleV2.xls b/examples/meshTopologyExampleV2.xls index b9320a07fd0404a787422d9595e8d5b453c817a3..a47e87a5aabfe4fae4e8a983f1242f851849bba5 100644 GIT binary patch delta 1481 zcmaJ>O=#0#7=FL}H0e*0mbA`xZmDr?l?}EPJO~aZ;tryNiHCvUtT1r8ZgaD!4C#gp zL=cqkA`H>X4j#7%9=v!Mdh{|c+JkrXEC^cPH_Q4ZQ%q>+^F815yg$kNt<0`0JRUOg z5L{`11DhkZl*{45?{>RQzk|X5f>)E)*_N^+G3I@Y&Bpo`ZPKZ5Zf5Sr(i#}>!*^2Q z%*};cQ)^(smm;4w*4ehl%(gnw$XFnu;vS@c;oUL>mXK*B1(wk_%*P-Gjg;Uu0M_y* zvR{>K4&(y5GIUVUIb{@}z&|(-_(OY)C(1*^4O8eSZa5FpgyY71-@ApZs$dA2KXF_~ z_TBLTvfP7JNfd?x?uO&FeurN!o#k`(p|K-S1Sp>_yBBBb(@Vwi>D$E%^Yz-?!1(-P zy*BHXhpXjNIXDWX|83*Xi_6VQs9Z{$hcLD4wI#}uL57wtumTFS(gLg4zA&$W1`TXC zUGzG1yu*AP;w~tm_m!Z&1OY%YePNovIeh+@4%ZmLQD%WIr7;ko*-3v5f;DU<=zQ3< zNA@%Ef9%Fse>o(5hgH{RI^V3=7&RJ!GTOgJ<>}r_caUi+)@#9W{yo>-LtB4A0uz;J zt%G)VJnC^Kh}9x2^-Jv4QDfn~>!ahlu>fbschw_0J&2p{b@JpIkFfE8oeJ1QgryuP z=Z#*cN!nzDO-3@J?@?q#<7L5KovDZ}710^KZZCJk*X`A12wfAy8xbLyTR;Z@rDpoV zOb3M0I?Q~U#qFa^O&(XUKCSc z|9A;unwLsi@H8*)QUa?u+tq}?bo|&MOy9%P(D8-y<3cGkkT^iFk`)8!&yV-Hd{yDy zB|C$)n3$}ngW1&6b0!M@UkOPLZZ!64^>1P$zFies+!Gv~B@hJe-j}{6)bquQcpkrJH zK2BX1pTZTf>Me=!(p01EC?`sqEP_*#L{d`*?UV|J&M=;MSqb*x7rlmKKeohe`OmOj zTbwUG)@o1{ixZ=JE-YVLZ(g|_gpFh2oDY)_(sC+Z7OyAnb?S)*sFoKAOdIgtRkdoM zLElnX#}@l}g$>-0B%gv5w6PZ&w80k6B%g+K07l{jGSqCG0JtL^9r2+$?`v>fc09{m zuy`I50dP?bJfFkq;a}wA*^hn%B{ok9U7P@a zAcN@{{-ZP{!h=UdZ{kvt8;KE>zu_n>^`F3W z{Pn!z>G(hA6vnu4Jfkq(4?lrP4zCjT3*`_%n9vvM0Uj2Vo}?V2i}fYFM%xdw^oj@R zUUOva3>=)C;~lFA>qvL|=%QwyIytoO_TGGdB5pP+*4Hoj#!R}$!~^|s^s(`dvr(}= N{fKuDM8Bs^?H})bmrnoy diff --git a/examples/transmission_main_example.py b/examples/transmission_main_example.py index 3606ca3a..36f20cda 100755 --- a/examples/transmission_main_example.py +++ b/examples/transmission_main_example.py @@ -63,7 +63,7 @@ def main(network, equipment, source, sink): Channel(f, (191.3 + spacing * f) * 1e12, 32e9, 0.15, Power(p, 0, 0)) for f in range(1,97) ]) - print(f'\nPorpagating with input power = {lin2db(p*1e3):.2f}dBm :') + print(f'\nPropagating with input power = {lin2db(p*1e3):.2f}dBm :') for el in path: si = el(si) print(el) #remove this line when sweeping across several powers diff --git a/gnpy/core/convert.py b/gnpy/core/convert.py index e93bd0df..1d66d0b7 100755 --- a/gnpy/core/convert.py +++ b/gnpy/core/convert.py @@ -156,7 +156,9 @@ def convert_file(input_filename, filter_region=[]): 'type_variety': x.east_fiber, 'params': {'length': round(x.east_distance, 3), 'length_units': x.distance_units, - 'loss_coef': x.east_lineic} + 'loss_coef': x.east_lineic, + 'connector_loss_in':x.east_con_in, + 'connector_loss_out':x.east_con_out} } for x in links] + [{'uid': f'fiber ({x.to_city} → {x.from_city})-{x.west_cable}', @@ -166,7 +168,9 @@ def convert_file(input_filename, filter_region=[]): 'type_variety': x.west_fiber, 'params': {'length': round(x.west_distance, 3), 'length_units': x.distance_units, - 'loss_coef': x.west_lineic} + 'loss_coef': x.west_lineic, + 'connector_loss_in':x.west_con_in, + 'connector_loss_out':x.west_con_out} } # missing ILA construction for x in links] + [{'uid': f'egress edfa in {e.from_city} to {e.to_city}', diff --git a/gnpy/core/elements.py b/gnpy/core/elements.py index f5eb6736..c457254f 100644 --- a/gnpy/core/elements.py +++ b/gnpy/core/elements.py @@ -134,17 +134,24 @@ class Fused(Node): carriers = tuple(self.propagate(*spectral_info.carriers)) return spectral_info.update(carriers=carriers) -FiberParams = namedtuple('FiberParams', 'type_variety length loss_coef length_units dispersion gamma') +FiberParams = namedtuple('FiberParams', 'type_variety length loss_coef length_units connector_loss_in connector_loss_out dispersion gamma') class Fiber(Node): def __init__(self, *args, params=None, **kwargs): + print(params) if params is None: params = {} + if 'connector_loss_in' not in params : + # test added to ensure backward compatibility in case loss was not in the json + params['connector_loss_in'] = 0.0 + params['connector_loss_out'] = 0.0 super().__init__(*args, params=FiberParams(**params), **kwargs) self.type_variety = self.params.type_variety self.length = self.params.length * UNITS[self.params.length_units] # in m self.loss_coef = self.params.loss_coef * 1e-3 # lineic loss dB/m self.lin_loss_coef = self.params.loss_coef / (20 * log10(exp(1))) + self.connector_loss_in = self.params.connector_loss_in + self.connector_loss_out = self.params.connector_loss_out self.dispersion = self.params.dispersion # s/m/m self.gamma = self.params.gamma # 1/W/m # TODO|jla: discuss factor 2 in the linear lineic attenuation @@ -157,7 +164,8 @@ class Fiber(Node): return '\n'.join([f'{type(self).__name__} {self.uid}', f' type_variety: {self.type_variety}', f' length (m): {self.length:.2f}', - f' loss (dB): {self.loss:.2f}']) + f' loss (dB): {self.loss:.2f}', + f' conn loss (dB) in: {self.connector_loss_in:.2f} out: {self.connector_loss_out:.2f}']) @property def loss(self): @@ -242,12 +250,29 @@ class Fiber(Node): return carrier_nli def propagate(self, *carriers): + + # apply connector_att_in on all carriers before computing gn analytics premiere partie pas bonne + attenuation = db2lin(self.connector_loss_in) + + chan = [] + 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) + carrier = carrier._replace(power=pwr) + chan.append(carrier) + + carriers = tuple(f for f in chan) + + # propagate in the fiber and apply attenuation out + attenuation = db2lin(self.connector_loss_out) for carrier in carriers: pwr = carrier.power carrier_nli = self._gn_analytic(carrier, *carriers) - pwr = pwr._replace(signal=pwr.signal/self.lin_attenuation, - nonlinear_interference=(pwr.nli+carrier_nli)/self.lin_attenuation, - amplified_spontaneous_emission=pwr.ase/self.lin_attenuation) + pwr = pwr._replace(signal=pwr.signal/self.lin_attenuation/attenuation, + nonlinear_interference=(pwr.nli+carrier_nli)/self.lin_attenuation/attenuation, + amplified_spontaneous_emission=pwr.ase/self.lin_attenuation/attenuation) yield carrier._replace(power=pwr) def __call__(self, spectral_info): From f36a610e523672bd27aecefe78fb05d7a601f55c Mon Sep 17 00:00:00 2001 From: EstherLerouzic Date: Mon, 2 Jul 2018 18:30:40 +0100 Subject: [PATCH 2/8] adding connector loss on the "loss" property of fiber class Signed-off-by: EstherLerouzic --- gnpy/core/elements.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gnpy/core/elements.py b/gnpy/core/elements.py index c457254f..5ed72403 100644 --- a/gnpy/core/elements.py +++ b/gnpy/core/elements.py @@ -165,12 +165,12 @@ class Fiber(Node): f' type_variety: {self.type_variety}', f' length (m): {self.length:.2f}', f' loss (dB): {self.loss:.2f}', - f' conn loss (dB) in: {self.connector_loss_in:.2f} out: {self.connector_loss_out:.2f}']) + f' (includes conn loss (dB) in: {self.connector_loss_in:.2f} out: {self.connector_loss_out:.2f})']) @property def loss(self): # dB loss: useful for polymorphism (roadm, fiber, att) - return self.loss_coef * self.length + return self.loss_coef * self.length + self.connector_loss_in + self.connector_loss_out @property def passive(self): From 4845d9005e09b054a38f95b9358a3200bbff8483 Mon Sep 17 00:00:00 2001 From: EstherLerouzic Date: Tue, 3 Jul 2018 12:52:50 +0100 Subject: [PATCH 3/8] Update tests after having inserted connector losses in json previous json did not have connector losses input: this commits updates the json expected files with the additional connector losse in parameters . Signed-off-by: EstherLerouzic --- tests/CORONET_Global_Topology_expected.json | 1088 ++++++++++++----- tests/excelTestFile_expected.json | 64 +- tests/meshTopologyExampleV2Eqpt_expected.json | 72 +- tests/meshTopologyExampleV2_expected.json | 72 +- tests/parsers_test.py | 5 +- 5 files changed, 975 insertions(+), 326 deletions(-) diff --git a/tests/CORONET_Global_Topology_expected.json b/tests/CORONET_Global_Topology_expected.json index 7b696206..383b8e23 100644 --- a/tests/CORONET_Global_Topology_expected.json +++ b/tests/CORONET_Global_Topology_expected.json @@ -1237,7 +1237,9 @@ "params": { "length": 336.951, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1253,7 +1255,9 @@ "params": { "length": 761.209, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1269,7 +1273,9 @@ "params": { "length": 277.065, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1285,7 +1291,9 @@ "params": { "length": 234.221, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1301,7 +1309,9 @@ "params": { "length": 1133.443, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1317,7 +1327,9 @@ "params": { "length": 647.737, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1333,7 +1345,9 @@ "params": { "length": 436.949, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1349,7 +1363,9 @@ "params": { "length": 943.536, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1365,7 +1381,9 @@ "params": { "length": 690.608, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1381,7 +1399,9 @@ "params": { "length": 210.729, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1397,7 +1417,9 @@ "params": { "length": 436.324, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1413,7 +1435,9 @@ "params": { "length": 7035.611, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1429,7 +1453,9 @@ "params": { "length": 266.228, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1445,7 +1471,9 @@ "params": { "length": 439.238, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1461,7 +1489,9 @@ "params": { "length": 554.111, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1477,7 +1507,9 @@ "params": { "length": 282.049, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1493,7 +1525,9 @@ "params": { "length": 143.553, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1509,7 +1543,9 @@ "params": { "length": 179.195, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1525,7 +1561,9 @@ "params": { "length": 384.819, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1541,7 +1579,9 @@ "params": { "length": 67.179, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1557,7 +1597,9 @@ "params": { "length": 3505.95, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1573,7 +1615,9 @@ "params": { "length": 2070.724, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1589,7 +1633,9 @@ "params": { "length": 500.152, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1605,7 +1651,9 @@ "params": { "length": 147.35, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1621,7 +1669,9 @@ "params": { "length": 1146.124, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1637,7 +1687,9 @@ "params": { "length": 1284.465, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1653,7 +1705,9 @@ "params": { "length": 623.015, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1669,7 +1723,9 @@ "params": { "length": 729.017, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1685,7 +1741,9 @@ "params": { "length": 880.042, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1701,7 +1759,9 @@ "params": { "length": 848.858, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1717,7 +1777,9 @@ "params": { "length": 352.383, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1733,7 +1795,9 @@ "params": { "length": 582.464, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1749,7 +1813,9 @@ "params": { "length": 738.94, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1765,7 +1831,9 @@ "params": { "length": 79.923, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1781,7 +1849,9 @@ "params": { "length": 381.913, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1797,7 +1867,9 @@ "params": { "length": 528.58, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1813,7 +1885,9 @@ "params": { "length": 1136.2, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1829,7 +1903,9 @@ "params": { "length": 336.434, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1845,7 +1921,9 @@ "params": { "length": 126.626, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1861,7 +1939,9 @@ "params": { "length": 379.311, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1877,7 +1957,9 @@ "params": { "length": 430.182, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1893,7 +1975,9 @@ "params": { "length": 159.883, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1909,7 +1993,9 @@ "params": { "length": 459.145, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1925,7 +2011,9 @@ "params": { "length": 165.326, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1941,7 +2029,9 @@ "params": { "length": 357.573, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1957,7 +2047,9 @@ "params": { "length": 193.215, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1973,7 +2065,9 @@ "params": { "length": 177.493, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -1989,7 +2083,9 @@ "params": { "length": 777.051, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2005,7 +2101,9 @@ "params": { "length": 238.963, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2021,7 +2119,9 @@ "params": { "length": 191.244, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2037,7 +2137,9 @@ "params": { "length": 294.714, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2053,7 +2155,9 @@ "params": { "length": 432.731, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2069,7 +2173,9 @@ "params": { "length": 553.958, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2085,7 +2191,9 @@ "params": { "length": 366.936, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2101,7 +2209,9 @@ "params": { "length": 5457.525, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2117,7 +2227,9 @@ "params": { "length": 1402.141, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2133,7 +2245,9 @@ "params": { "length": 920.337, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2149,7 +2263,9 @@ "params": { "length": 731.272, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2165,7 +2281,9 @@ "params": { "length": 107.244, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2181,7 +2299,9 @@ "params": { "length": 964.453, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2197,7 +2317,9 @@ "params": { "length": 505.749, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2213,7 +2335,9 @@ "params": { "length": 717.001, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2229,7 +2353,9 @@ "params": { "length": 496.199, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2245,7 +2371,9 @@ "params": { "length": 386.671, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2261,7 +2389,9 @@ "params": { "length": 289.941, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2277,7 +2407,9 @@ "params": { "length": 690.409, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2293,7 +2425,9 @@ "params": { "length": 131.097, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2309,7 +2443,9 @@ "params": { "length": 317.897, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2325,7 +2461,9 @@ "params": { "length": 186.271, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2341,7 +2479,9 @@ "params": { "length": 125.56, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2357,7 +2497,9 @@ "params": { "length": 1480.406, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2373,7 +2515,9 @@ "params": { "length": 8856.6, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2389,7 +2533,9 @@ "params": { "length": 966.177, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2405,7 +2551,9 @@ "params": { "length": 4921.459, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2421,7 +2569,9 @@ "params": { "length": 9808.616, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2437,7 +2587,9 @@ "params": { "length": 9767.013, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2453,7 +2605,9 @@ "params": { "length": 1650.406, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2469,7 +2623,9 @@ "params": { "length": 246.577, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2485,7 +2641,9 @@ "params": { "length": 314.032, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2501,7 +2659,9 @@ "params": { "length": 470.866, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2517,7 +2677,9 @@ "params": { "length": 418.438, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2533,7 +2695,9 @@ "params": { "length": 495.9, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2549,7 +2713,9 @@ "params": { "length": 700.005, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2565,7 +2731,9 @@ "params": { "length": 261.343, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2581,7 +2749,9 @@ "params": { "length": 411.692, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2597,7 +2767,9 @@ "params": { "length": 7079.447, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2613,7 +2785,9 @@ "params": { "length": 29.362, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2629,7 +2803,9 @@ "params": { "length": 223.845, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2645,7 +2821,9 @@ "params": { "length": 150.677, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2661,7 +2839,9 @@ "params": { "length": 295.118, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2677,7 +2857,9 @@ "params": { "length": 473.802, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2693,7 +2875,9 @@ "params": { "length": 1263.619, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2709,7 +2893,9 @@ "params": { "length": 1497.358, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2725,7 +2911,9 @@ "params": { "length": 377.836, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2741,7 +2929,9 @@ "params": { "length": 8829.358, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2757,7 +2947,9 @@ "params": { "length": 397.115, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2773,7 +2965,9 @@ "params": { "length": 129.825, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2789,7 +2983,9 @@ "params": { "length": 568.334, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2805,7 +3001,9 @@ "params": { "length": 561.327, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2821,7 +3019,9 @@ "params": { "length": 7415.841, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2837,7 +3037,9 @@ "params": { "length": 4692.708, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2853,7 +3055,9 @@ "params": { "length": 653.359, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2869,7 +3073,9 @@ "params": { "length": 24.214, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2885,7 +3091,9 @@ "params": { "length": 199.575, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2901,7 +3109,9 @@ "params": { "length": 204.152, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2917,7 +3127,9 @@ "params": { "length": 136.06, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2933,7 +3145,9 @@ "params": { "length": 298.656, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2949,7 +3163,9 @@ "params": { "length": 383.669, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2965,7 +3181,9 @@ "params": { "length": 132.649, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2981,7 +3199,9 @@ "params": { "length": 1135.717, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -2997,7 +3217,9 @@ "params": { "length": 25.72, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3013,7 +3235,9 @@ "params": { "length": 12461.707, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3029,7 +3253,9 @@ "params": { "length": 193.359, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3045,7 +3271,9 @@ "params": { "length": 275.793, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3061,7 +3289,9 @@ "params": { "length": 193.409, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3077,7 +3307,9 @@ "params": { "length": 574.675, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3093,7 +3325,9 @@ "params": { "length": 222.458, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3109,7 +3343,9 @@ "params": { "length": 473.565, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3125,7 +3361,9 @@ "params": { "length": 937.74, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3141,7 +3379,9 @@ "params": { "length": 1221.189, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3157,7 +3397,9 @@ "params": { "length": 279.082, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3173,7 +3415,9 @@ "params": { "length": 9349.706, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3189,7 +3433,9 @@ "params": { "length": 190.145, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3205,7 +3451,9 @@ "params": { "length": 145.266, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3221,7 +3469,9 @@ "params": { "length": 920.026, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3237,7 +3487,9 @@ "params": { "length": 823.4, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3253,7 +3505,9 @@ "params": { "length": 77.163, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3269,7 +3523,9 @@ "params": { "length": 446.99, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3285,7 +3541,9 @@ "params": { "length": 223.775, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3301,7 +3559,9 @@ "params": { "length": 444.207, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3317,7 +3577,9 @@ "params": { "length": 1391.085, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3333,7 +3595,9 @@ "params": { "length": 7562.331, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3349,7 +3613,9 @@ "params": { "length": 144.06, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3365,7 +3631,9 @@ "params": { "length": 2537.345, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3381,7 +3649,9 @@ "params": { "length": 394.094, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3397,7 +3667,9 @@ "params": { "length": 669.297, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3413,7 +3685,9 @@ "params": { "length": 336.951, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3429,7 +3703,9 @@ "params": { "length": 761.209, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3445,7 +3721,9 @@ "params": { "length": 277.065, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3461,7 +3739,9 @@ "params": { "length": 234.221, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3477,7 +3757,9 @@ "params": { "length": 1133.443, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3493,7 +3775,9 @@ "params": { "length": 647.737, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3509,7 +3793,9 @@ "params": { "length": 436.949, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3525,7 +3811,9 @@ "params": { "length": 943.536, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3541,7 +3829,9 @@ "params": { "length": 690.608, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3557,7 +3847,9 @@ "params": { "length": 210.729, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3573,7 +3865,9 @@ "params": { "length": 436.324, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3589,7 +3883,9 @@ "params": { "length": 7035.611, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3605,7 +3901,9 @@ "params": { "length": 266.228, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3621,7 +3919,9 @@ "params": { "length": 439.238, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3637,7 +3937,9 @@ "params": { "length": 554.111, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3653,7 +3955,9 @@ "params": { "length": 282.049, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3669,7 +3973,9 @@ "params": { "length": 143.553, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3685,7 +3991,9 @@ "params": { "length": 179.195, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3701,7 +4009,9 @@ "params": { "length": 384.819, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3717,7 +4027,9 @@ "params": { "length": 67.179, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3733,7 +4045,9 @@ "params": { "length": 3505.95, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3749,7 +4063,9 @@ "params": { "length": 2070.724, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3765,7 +4081,9 @@ "params": { "length": 500.152, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3781,7 +4099,9 @@ "params": { "length": 147.35, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3797,7 +4117,9 @@ "params": { "length": 1146.124, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3813,7 +4135,9 @@ "params": { "length": 1284.465, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3829,7 +4153,9 @@ "params": { "length": 623.015, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3845,7 +4171,9 @@ "params": { "length": 729.017, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3861,7 +4189,9 @@ "params": { "length": 880.042, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3877,7 +4207,9 @@ "params": { "length": 848.858, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3893,7 +4225,9 @@ "params": { "length": 352.383, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3909,7 +4243,9 @@ "params": { "length": 582.464, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3925,7 +4261,9 @@ "params": { "length": 738.94, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3941,7 +4279,9 @@ "params": { "length": 79.923, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3957,7 +4297,9 @@ "params": { "length": 381.913, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3973,7 +4315,9 @@ "params": { "length": 528.58, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -3989,7 +4333,9 @@ "params": { "length": 1136.2, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4005,7 +4351,9 @@ "params": { "length": 336.434, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4021,7 +4369,9 @@ "params": { "length": 126.626, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4037,7 +4387,9 @@ "params": { "length": 379.311, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4053,7 +4405,9 @@ "params": { "length": 430.182, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4069,7 +4423,9 @@ "params": { "length": 159.883, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4085,7 +4441,9 @@ "params": { "length": 459.145, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4101,7 +4459,9 @@ "params": { "length": 165.326, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4117,7 +4477,9 @@ "params": { "length": 357.573, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4133,7 +4495,9 @@ "params": { "length": 193.215, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4149,7 +4513,9 @@ "params": { "length": 177.493, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4165,7 +4531,9 @@ "params": { "length": 777.051, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4181,7 +4549,9 @@ "params": { "length": 238.963, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4197,7 +4567,9 @@ "params": { "length": 191.244, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4213,7 +4585,9 @@ "params": { "length": 294.714, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4229,7 +4603,9 @@ "params": { "length": 432.731, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4245,7 +4621,9 @@ "params": { "length": 553.958, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4261,7 +4639,9 @@ "params": { "length": 366.936, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4277,7 +4657,9 @@ "params": { "length": 5457.525, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4293,7 +4675,9 @@ "params": { "length": 1402.141, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4309,7 +4693,9 @@ "params": { "length": 920.337, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4325,7 +4711,9 @@ "params": { "length": 731.272, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4341,7 +4729,9 @@ "params": { "length": 107.244, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4357,7 +4747,9 @@ "params": { "length": 964.453, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4373,7 +4765,9 @@ "params": { "length": 505.749, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4389,7 +4783,9 @@ "params": { "length": 717.001, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4405,7 +4801,9 @@ "params": { "length": 496.199, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4421,7 +4819,9 @@ "params": { "length": 386.671, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4437,7 +4837,9 @@ "params": { "length": 289.941, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4453,7 +4855,9 @@ "params": { "length": 690.409, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4469,7 +4873,9 @@ "params": { "length": 131.097, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4485,7 +4891,9 @@ "params": { "length": 317.897, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4501,7 +4909,9 @@ "params": { "length": 186.271, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4517,7 +4927,9 @@ "params": { "length": 125.56, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4533,7 +4945,9 @@ "params": { "length": 1480.406, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4549,7 +4963,9 @@ "params": { "length": 8856.6, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4565,7 +4981,9 @@ "params": { "length": 966.177, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4581,7 +4999,9 @@ "params": { "length": 4921.459, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4597,7 +5017,9 @@ "params": { "length": 9808.616, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4613,7 +5035,9 @@ "params": { "length": 9767.013, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4629,7 +5053,9 @@ "params": { "length": 1650.406, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4645,7 +5071,9 @@ "params": { "length": 246.577, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4661,7 +5089,9 @@ "params": { "length": 314.032, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4677,7 +5107,9 @@ "params": { "length": 470.866, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4693,7 +5125,9 @@ "params": { "length": 418.438, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4709,7 +5143,9 @@ "params": { "length": 495.9, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4725,7 +5161,9 @@ "params": { "length": 700.005, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4741,7 +5179,9 @@ "params": { "length": 261.343, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4757,7 +5197,9 @@ "params": { "length": 411.692, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4773,7 +5215,9 @@ "params": { "length": 7079.447, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4789,7 +5233,9 @@ "params": { "length": 29.362, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4805,7 +5251,9 @@ "params": { "length": 223.845, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4821,7 +5269,9 @@ "params": { "length": 150.677, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4837,7 +5287,9 @@ "params": { "length": 295.118, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4853,7 +5305,9 @@ "params": { "length": 473.802, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4869,7 +5323,9 @@ "params": { "length": 1263.619, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4885,7 +5341,9 @@ "params": { "length": 1497.358, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4901,7 +5359,9 @@ "params": { "length": 377.836, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4917,7 +5377,9 @@ "params": { "length": 8829.358, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4933,7 +5395,9 @@ "params": { "length": 397.115, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4949,7 +5413,9 @@ "params": { "length": 129.825, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4965,7 +5431,9 @@ "params": { "length": 568.334, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4981,7 +5449,9 @@ "params": { "length": 561.327, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -4997,7 +5467,9 @@ "params": { "length": 7415.841, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5013,7 +5485,9 @@ "params": { "length": 4692.708, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5029,7 +5503,9 @@ "params": { "length": 653.359, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5045,7 +5521,9 @@ "params": { "length": 24.214, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5061,7 +5539,9 @@ "params": { "length": 199.575, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5077,7 +5557,9 @@ "params": { "length": 204.152, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5093,7 +5575,9 @@ "params": { "length": 136.06, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5109,7 +5593,9 @@ "params": { "length": 298.656, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5125,7 +5611,9 @@ "params": { "length": 383.669, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5141,7 +5629,9 @@ "params": { "length": 132.649, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5157,7 +5647,9 @@ "params": { "length": 1135.717, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5173,7 +5665,9 @@ "params": { "length": 25.72, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5189,7 +5683,9 @@ "params": { "length": 12461.707, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5205,7 +5701,9 @@ "params": { "length": 193.359, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5221,7 +5719,9 @@ "params": { "length": 275.793, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5237,7 +5737,9 @@ "params": { "length": 193.409, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5253,7 +5755,9 @@ "params": { "length": 574.675, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5269,7 +5773,9 @@ "params": { "length": 222.458, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5285,7 +5791,9 @@ "params": { "length": 473.565, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5301,7 +5809,9 @@ "params": { "length": 937.74, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5317,7 +5827,9 @@ "params": { "length": 1221.189, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5333,7 +5845,9 @@ "params": { "length": 279.082, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5349,7 +5863,9 @@ "params": { "length": 9349.706, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5365,7 +5881,9 @@ "params": { "length": 190.145, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5381,7 +5899,9 @@ "params": { "length": 145.266, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5397,7 +5917,9 @@ "params": { "length": 920.026, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5413,7 +5935,9 @@ "params": { "length": 823.4, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5429,7 +5953,9 @@ "params": { "length": 77.163, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5445,7 +5971,9 @@ "params": { "length": 446.99, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5461,7 +5989,9 @@ "params": { "length": 223.775, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5477,7 +6007,9 @@ "params": { "length": 444.207, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5493,7 +6025,9 @@ "params": { "length": 1391.085, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5509,7 +6043,9 @@ "params": { "length": 7562.331, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5525,7 +6061,9 @@ "params": { "length": 144.06, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5541,7 +6079,9 @@ "params": { "length": 2537.345, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5557,7 +6097,9 @@ "params": { "length": 394.094, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -5573,7 +6115,9 @@ "params": { "length": 669.297, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } } ], diff --git a/tests/excelTestFile_expected.json b/tests/excelTestFile_expected.json index 8c42bd8c..73cf845f 100644 --- a/tests/excelTestFile_expected.json +++ b/tests/excelTestFile_expected.json @@ -181,7 +181,9 @@ "params": { "length": 20.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -197,7 +199,9 @@ "params": { "length": 50.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -213,7 +217,9 @@ "params": { "length": 60.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -229,7 +235,9 @@ "params": { "length": 10.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -245,7 +253,9 @@ "params": { "length": 60.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -261,7 +271,9 @@ "params": { "length": 65.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -277,7 +289,9 @@ "params": { "length": 40.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -293,7 +307,9 @@ "params": { "length": 35.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -309,7 +325,9 @@ "params": { "length": 20.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -325,7 +343,9 @@ "params": { "length": 50.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -341,7 +361,9 @@ "params": { "length": 60.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -357,7 +379,9 @@ "params": { "length": 10.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -373,7 +397,9 @@ "params": { "length": 60.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -389,7 +415,9 @@ "params": { "length": 65.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -405,7 +433,9 @@ "params": { "length": 40.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -421,7 +451,9 @@ "params": { "length": 35.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { diff --git a/tests/meshTopologyExampleV2Eqpt_expected.json b/tests/meshTopologyExampleV2Eqpt_expected.json index 10807dfc..fa4b083d 100644 --- a/tests/meshTopologyExampleV2Eqpt_expected.json +++ b/tests/meshTopologyExampleV2Eqpt_expected.json @@ -253,7 +253,9 @@ "params": { "length": 20.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -269,7 +271,9 @@ "params": { "length": 50.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -285,7 +289,9 @@ "params": { "length": 60.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -301,7 +307,9 @@ "params": { "length": 10.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -317,7 +325,9 @@ "params": { "length": 60.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -333,7 +343,9 @@ "params": { "length": 65.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -349,7 +361,9 @@ "params": { "length": 40.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -365,7 +379,9 @@ "params": { "length": 35.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -381,7 +397,9 @@ "params": { "length": 80.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -397,7 +415,9 @@ "params": { "length": 20.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -413,7 +433,9 @@ "params": { "length": 50.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -429,7 +451,9 @@ "params": { "length": 60.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -445,7 +469,9 @@ "params": { "length": 10.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -461,7 +487,9 @@ "params": { "length": 60.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -477,7 +505,9 @@ "params": { "length": 65.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -493,7 +523,9 @@ "params": { "length": 40.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -509,7 +541,9 @@ "params": { "length": 35.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -525,7 +559,9 @@ "params": { "length": 80.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { diff --git a/tests/meshTopologyExampleV2_expected.json b/tests/meshTopologyExampleV2_expected.json index d97897e2..c34448d1 100644 --- a/tests/meshTopologyExampleV2_expected.json +++ b/tests/meshTopologyExampleV2_expected.json @@ -253,7 +253,9 @@ "params": { "length": 20.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -269,7 +271,9 @@ "params": { "length": 50.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -285,7 +289,9 @@ "params": { "length": 60.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -301,7 +307,9 @@ "params": { "length": 10.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -317,7 +325,9 @@ "params": { "length": 60.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -333,7 +343,9 @@ "params": { "length": 65.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -349,7 +361,9 @@ "params": { "length": 40.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -365,7 +379,9 @@ "params": { "length": 35.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -381,7 +397,9 @@ "params": { "length": 80.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -397,7 +415,9 @@ "params": { "length": 20.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -413,7 +433,9 @@ "params": { "length": 50.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -429,7 +451,9 @@ "params": { "length": 60.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -445,7 +469,9 @@ "params": { "length": 10.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -461,7 +487,9 @@ "params": { "length": 60.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -477,7 +505,9 @@ "params": { "length": 65.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -493,7 +523,9 @@ "params": { "length": 40.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -509,7 +541,9 @@ "params": { "length": 35.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } }, { @@ -525,7 +559,9 @@ "params": { "length": 80.0, "length_units": "km", - "loss_coef": 0.2 + "loss_coef": 0.2, + "connector_loss_in": 0.5, + "connector_loss_out": 0.5 } } ], diff --git a/tests/parsers_test.py b/tests/parsers_test.py index a5c69505..60bcf745 100644 --- a/tests/parsers_test.py +++ b/tests/parsers_test.py @@ -38,9 +38,10 @@ network_test_filenames = { 'tests/meshTopologyExampleV2Eqpt.xls' : 'tests/meshTopologyExampleV2Eqpt_expected.json'} @pytest.mark.parametrize("inputfile",excel_filename) def test_excel_json_generation(inputfile) : - convert_file(Path(inputfile)) + json_filename = convert_file(Path(inputfile)) + print(json_filename) # actual - json_filename = f'{inputfile[:-3]}json' + # json_filename = f'{inputfile[:-3]}json' # expected expected_filename = network_test_filenames[inputfile] From 15bc5db2ed7e822fc0a6d9ab2a558920356bd4c2 Mon Sep 17 00:00:00 2001 From: EstherLerouzic Date: Wed, 4 Jul 2018 16:45:28 +0100 Subject: [PATCH 4/8] adding test on the propagation on a link example test verifies that OSNR and SNR computed values are consistant including connector loss and input power variation onto 2 example links: 1 and 5 spans Signed-off-by: EstherLerouzic --- examples/transmission_main_example.py | 2 +- gnpy/core/elements.py | 1 - tests/LinkforTest.json | 261 ++++++++++++++++++++++++++ tests/propagation_test.py | 101 ++++++++++ 4 files changed, 363 insertions(+), 2 deletions(-) create mode 100644 tests/LinkforTest.json create mode 100644 tests/propagation_test.py diff --git a/examples/transmission_main_example.py b/examples/transmission_main_example.py index 36f20cda..2b6ba111 100755 --- a/examples/transmission_main_example.py +++ b/examples/transmission_main_example.py @@ -91,7 +91,7 @@ if __name__ == '__main__': # logger.info(equipment) network = load_network(args.filename, equipment) - print(network) + # print(network) transceivers = {n.uid: n for n in network.nodes() if isinstance(n, Transceiver)} diff --git a/gnpy/core/elements.py b/gnpy/core/elements.py index 5ed72403..0b90b1c5 100644 --- a/gnpy/core/elements.py +++ b/gnpy/core/elements.py @@ -138,7 +138,6 @@ FiberParams = namedtuple('FiberParams', 'type_variety length loss_coef length_un class Fiber(Node): def __init__(self, *args, params=None, **kwargs): - print(params) if params is None: params = {} if 'connector_loss_in' not in params : diff --git a/tests/LinkforTest.json b/tests/LinkforTest.json new file mode 100644 index 00000000..ae3c76a3 --- /dev/null +++ b/tests/LinkforTest.json @@ -0,0 +1,261 @@ +{ + "elements": [ + { + "uid": "trx A", + "metadata": { + "location": { + "city": "A", + "region": "", + "latitude": 0, + "longitude": 0 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx B", + "metadata": { + "location": { + "city": "B", + "region": "", + "latitude": 0, + "longitude": 0 + } + }, + "type": "Transceiver" + }, + { + "uid": "trx F", + "metadata": { + "location": { + "city": "F", + "region": "", + "latitude": 0, + "longitude": 0 + } + }, + "type": "Transceiver" + }, + { + "uid": "fiber (A \u2192 B)-", + "metadata": { + "location": { + "latitude": 0.0, + "longitude": 0.0 + } + }, + "type": "Fiber", + "type_variety": "SSMF", + "params": { + "length": 80.0, + "length_units": "km", + "loss_coef": 0.2, + "connector_loss_in": 1.00, + "connector_loss_out": 1.00 + } + }, + { + "uid": "fiber (B \u2192 C)-", + "metadata": { + "location": { + "latitude": 0.0, + "longitude": 0.0 + } + }, + "type": "Fiber", + "type_variety": "SSMF", + "params": { + "length": 80.0, + "length_units": "km", + "loss_coef": 0.2, + "connector_loss_in": 1.00, + "connector_loss_out": 1.00 + } + }, + { + "uid": "fiber (C \u2192 D)-", + "metadata": { + "location": { + "latitude": 0.0, + "longitude": 0.0 + } + }, + "type": "Fiber", + "type_variety": "SSMF", + "params": { + "length": 80.0, + "length_units": "km", + "loss_coef": 0.2, + "connector_loss_in": 1.00, + "connector_loss_out": 1.00 + } + }, + { + "uid": "fiber (D \u2192 E)-", + "metadata": { + "location": { + "latitude": 0.0, + "longitude": 0.0 + } + }, + "type": "Fiber", + "type_variety": "SSMF", + "params": { + "length": 80.0, + "length_units": "km", + "loss_coef": 0.2, + "connector_loss_in": 1.00, + "connector_loss_out": 1.00 + } + }, + { + "uid": "fiber (E \u2192 F)-", + "metadata": { + "location": { + "latitude": 0.0, + "longitude": 0.0 + } + }, + "type": "Fiber", + "type_variety": "SSMF", + "params": { + "length": 80.0, + "length_units": "km", + "loss_coef": 0.2, + "connector_loss_in": 1.00, + "connector_loss_out": 1.00 + } + }, + { + "uid": "Edfa1", + "type": "Edfa", + "type_variety": "std_medium_gain", + "operational": { + "gain_target": 18, + "tilt_target": 0 + }, + "metadata": { + "location": { + "region": "", + "latitude": 2, + "longitude": 0 + } + } + }, + { + "uid": "Edfa2", + "type": "Edfa", + "type_variety": "std_medium_gain", + "operational": { + "gain_target": 18, + "tilt_target": 0 + }, + "metadata": { + "location": { + "region": "", + "latitude": 2, + "longitude": 0 + } + } + }, + { + "uid": "Edfa3", + "type": "Edfa", + "type_variety": "std_medium_gain", + "operational": { + "gain_target": 18, + "tilt_target": 0 + }, + "metadata": { + "location": { + "region": "", + "latitude": 2, + "longitude": 0 + } + } + }, + { + "uid": "Edfa4", + "type": "Edfa", + "type_variety": "std_medium_gain", + "operational": { + "gain_target": 18, + "tilt_target": 0 + }, + "metadata": { + "location": { + "region": "", + "latitude": 2, + "longitude": 0 + } + } + }, + { + "uid": "Edfa5", + "type": "Edfa", + "type_variety": "std_medium_gain", + "operational": { + "gain_target": 18, + "tilt_target": 0 + }, + "metadata": { + "location": { + "region": "", + "latitude": 2, + "longitude": 0 + } + } + } + + ], + "connections": [ + { + "from_node": "fiber (A \u2192 B)-", + "to_node": "Edfa1" + }, + { + "from_node": "Edfa1", + "to_node": "fiber (B \u2192 C)-" + }, + { + "from_node": "fiber (B \u2192 C)-", + "to_node": "Edfa2" + }, + { + "from_node": "Edfa2", + "to_node": "fiber (C \u2192 D)-" + }, + { + "from_node": "fiber (C \u2192 D)-", + "to_node": "Edfa3" + }, + { + "from_node": "Edfa3", + "to_node": "fiber (D \u2192 E)-" + }, + { + "from_node": "fiber (D \u2192 E)-", + "to_node": "Edfa4" + }, + { + "from_node": "Edfa4", + "to_node": "fiber (E \u2192 F)-" + }, + { + "from_node": "fiber (E \u2192 F)-", + "to_node": "Edfa5" + }, + { + "from_node": "Edfa5", + "to_node": "trx F" + }, + { + "from_node": "trx A", + "to_node": "fiber (A \u2192 B)-" + }, + { + "from_node": "Edfa1", + "to_node": "trx B" + } + ] +} diff --git a/tests/propagation_test.py b/tests/propagation_test.py new file mode 100644 index 00000000..debc8dbb --- /dev/null +++ b/tests/propagation_test.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# @Author: Jean-Luc Auge +# @Date: 2018-02-02 14:06:55 + +from gnpy.core.elements import Edfa +import numpy as np +from json import load, dumps +import pytest +from gnpy.core.elements import Transceiver, Fiber, Edfa +from gnpy.core.utils import lin2db, db2lin +from gnpy.core.info import create_input_spectral_information, SpectralInformation, Channel, Power +from gnpy.core.equipment import load_equipment +from gnpy.core.network import build_network, load_network +from pathlib import Path +from networkx import dijkstra_path +from numpy import mean + +#network_file_name = 'tests/test_network.json' +network_file_name = Path(__file__).parent.parent / 'tests/LinkforTest.json' +#network_file_name = Path(__file__).parent.parent / 'examples/edfa_example_network.json' +eqpt_library_name = Path(__file__).parent.parent / 'examples/eqpt_config.json' + +@pytest.fixture(params=[(96, 0.05e12), (60, 0.075e12), (45, 0.1e12), (2, 0.1e12)], + ids=['50GHz spacing', '75GHz spacing', '100GHz spacing', '2 channels']) +# TODO in elements.py code: pytests doesn't pass with 1 channel: interpolate fail +def nch_and_spacing(request): + """parametrize channel count vs channel spacing (Hz)""" + yield request.param + +def propagation(input_power, connector_loss_in, connector_loss_out,dest): + equipment = load_equipment(eqpt_library_name) + network = load_network(network_file_name,equipment) + + # parametrize the network elements with the con losses and adapt gain + # (assumes all spans are identical) + for e in network.nodes(): + if isinstance(e, Fiber): + loss = e.loss_coef * e.length + e.connector_loss_in = connector_loss_in + e.connector_loss_out = connector_loss_out + if isinstance(e, Edfa): + e.operational.gain_target = loss + connector_loss_in + connector_loss_out + + transceivers = {n.uid: n for n in network.nodes() if isinstance(n, Transceiver)} + + p = input_power + p=db2lin(p)*1e-3 + spacing = 0.05 # THz + si = SpectralInformation() # SI units: W, Hz + si = si.update(carriers=[ + Channel(f, (191.3 + spacing * f) * 1e12, 32e9, 0.15, Power(p, 0, 0)) + for f in range(1,80) + ]) + source = next(transceivers[uid] for uid in transceivers if uid == 'trx A') + sink = next(transceivers[uid] for uid in transceivers if uid == dest) + path = dijkstra_path(network, source, sink) + # print(f'\nPropagating with input power = {lin2db(p*1e3):.2f}dBm :') + for el in path: + si = el(si) + if isinstance(el, Edfa): + nf = mean(el.nf) + print(el) #remove this line when sweeping across several powers + # print(f'\nTransmission result for input power = {lin2db(p*1e3):.2f}dBm :') + print(f'pw: {input_power} conn in: {connector_loss_in} con out: {connector_loss_out} ' + + f'OSNR@0.1nm: {round(mean(sink.osnr_ase_01nm),2)} SNR@bandwitdth: {round(mean(sink.snr),2)}') + return sink , nf + +test = {'a':(-1,1,0),'b':(-1,1,1),'c':(0,1,0),'d':(1,1,1)} +expected = {'a':(-2,0,0),'b':(-2,0,1),'c':(-1,0,0),'d':(0,0,1)} + +@pytest.mark.parametrize("dest",['trx B','trx F']) +@pytest.mark.parametrize("osnr_test", ['a','b','c','d']) +def test_snr(osnr_test, dest): + pw = test[osnr_test][0] + conn_in = test[osnr_test][1] + conn_out =test[osnr_test][2] + sink,nf = propagation(pw,conn_in,conn_out,dest) + osnr = round(mean(sink.osnr_ase),3) + nli = 1.0/db2lin(round(mean(sink.snr),3)) - 1.0/db2lin(osnr) + pw = expected[osnr_test][0] + conn_in = expected[osnr_test][1] + conn_out = expected[osnr_test][2] + sink,exp_nf = propagation(pw,conn_in,conn_out,dest) + expected_osnr = round(mean(sink.osnr_ase),3) + expected_nli = 1.0/db2lin(round(mean(sink.snr),3)) - 1.0/db2lin(expected_osnr) + # compare OSNR taking into account nf change of amps + osnr_diff = abs(osnr - expected_osnr + nf - exp_nf) + nli_diff = abs((nli-expected_nli)/nli) + assert osnr_diff <0.01 and nli_diff<0.01 + + +if __name__ == '__main__': + from logging import getLogger, basicConfig, INFO + logger = getLogger(__name__) + basicConfig(level=INFO) + + #logger.info(f'Running {test}') + for a in test : + test_snr(a,'trx F') + print('\n') From b9518ca987bd5516b3d26c2845dc261a3907836e Mon Sep 17 00:00:00 2001 From: EstherLerouzic Date: Thu, 5 Jul 2018 15:48:11 +0100 Subject: [PATCH 5/8] Starting: adding path_requests_run functions to the "core" package - Path_request class is updated to be more generic and reuseable in transmission main example. json processing linked to the yang modelling is kept in the pat_request_run, while path_request class only contains useful attributes - adding functions in info and request python files in core directory Signed-off-by: EstherLerouzic --- examples/path_requests_run.py | 135 +++++-------------------- gnpy/core/info.py | 7 ++ gnpy/core/request.py | 180 ++++++++++++++++++++++++++++++++++ 3 files changed, 212 insertions(+), 110 deletions(-) create mode 100644 gnpy/core/request.py diff --git a/examples/path_requests_run.py b/examples/path_requests_run.py index f3f05980..fb8961aa 100644 --- a/examples/path_requests_run.py +++ b/examples/path_requests_run.py @@ -30,7 +30,8 @@ from gnpy.core.network import load_network, build_network from gnpy.core.equipment import load_equipment from gnpy.core.elements import Transceiver, Roadm, Edfa, Fused from gnpy.core.utils import db2lin, lin2db -from gnpy.core.info import create_input_spectral_information, SpectralInformation, Channel, Power +from gnpy.core.info import create_input_spectral_information, SpectralInformation, Channel, Power, load_SI +from gnpy.core.request import Path_request, Result_element from copy import copy, deepcopy from numpy import log10 @@ -46,114 +47,6 @@ parser.add_argument('-v', '--verbose', action='count') parser.add_argument('-o', '--output', default=None) -class Path_request(): - def __init__(self,jsondata,tspjsondata): - self.request_id = jsondata['request-id'] - self.source = jsondata['src-tp-id'] - self.destination = jsondata['dst-tp-id'] - # retrieving baudrate out of transponder type and mode (format) - self.tsp = jsondata['path-constraints']['te-bandwidth']['trx_type'] - self.tsp_mode = jsondata['path-constraints']['te-bandwidth']['trx_mode'] - # for debug - # print(tsp) - try: - baudrate = next(m['baudrate'] - for t in tspjsondata if t['type_variety'] == self.tsp - for m in t['mode'] if m['format'] == self.tsp_mode) - except StopIteration: - msg = f'could not find tsp : {self.tsp} with mode: {self.tsp_mode} in eqpt library' - logger.critical(msg) - raise ValueError(msg) - self.baudrate = baudrate - - nodes_list = jsondata['optimizations']['explicit-route-include-objects'] - self.nodes_list = [n['unnumbered-hop']['node-id'] for n in nodes_list] - # create a list for individual loose capability for each node ... - # even if convert_service_sheet fills it with the same value - self.loose_list = [n['unnumbered-hop']['hop-type'] for n in nodes_list] - - self.spacing = jsondata['path-constraints']['te-bandwidth']['spacing'] - self.power = jsondata['path-constraints']['te-bandwidth']['output-power'] - self.nb_channel = jsondata['path-constraints']['te-bandwidth']['max-nb-of-channel'] - - def __str__(self): - return '\n\t'.join([ f'{type(self).__name__} {self.request_id}', - f'source: {self.source}', - f'destination: {self.destination}']) - def __repr__(self): - return '\n\t'.join([ f'{type(self).__name__} {self.request_id}', - f'source: {self.source}', - f'destination: {self.destination}', - f'trx type: {self.tsp}', - f'baudrate: {self.baudrate}', - f'spacing: {self.spacing}', - f'power: {self.power}' - '\n']) - - -class Result_element(Element): - def __init__(self,path_request,computed_path): - self.path_id = int(path_request.request_id) - self.path_request = path_request - 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])) - else: - hop_type.append('not recorded') - self.hop_type = hop_type - uid = property(lambda self: repr(self)) - @property - def pathresult(self): - return { - 'path-id': self.path_id, - 'path-properties':{ - 'path-metric': [ - { - 'metric-type': 'SNR@bandwidth', - 'accumulative-value': round(mean(self.computed_path[-1].snr),2) - }, - { - 'metric-type': 'SNR@0.1nm', - 'accumulative-value': round(mean(self.computed_path[-1].snr+10*log10(self.path_request.baudrate/12.5)),2) - } - ], - 'path-srlgs': { - 'usage': 'not used yet', - 'values': 'not used yet' - }, - 'path-route-objects': [ - { - 'path-route-object': { - 'index': self.computed_path.index(n), - 'unnumbered-hop': { - 'node-id': n.uid, - 'link-tp-id': n.uid, - 'hop-type': self.hop_type[self.computed_path.index(n)], - 'direction': 'not used' - }, - 'label-hop': { - 'te-label': { - 'generic': 'not used yet', - 'direction': 'not used yet' - } - } - } - } for n in self.computed_path - ] - } - } - - @property - def json(self): - return self.pathresult - -def load_SI(filename): - with open(filename) as f: - json_data = loads(f.read()) - return json_data['SI'][0] - def load_Transceiver(filename): with open(filename) as f: json_data = loads(f.read()) @@ -162,9 +55,31 @@ def load_Transceiver(filename): def requests_from_json(json_data,eqpt_filename): requests_list = [] tspjsondata = load_Transceiver(eqpt_filename) + for req in json_data['path-request']: #print(f'{req}') - requests_list.append(Path_request(req,tspjsondata)) + params = {} + params['request_id'] = req['request-id'] + params['source'] = req['src-tp-id'] + params['destination'] = req['dst-tp-id'] + params['trx_type'] = req['path-constraints']['te-bandwidth']['trx_type'] + params['trx_mode'] = req['path-constraints']['te-bandwidth']['trx_mode'] + try: + extra_params = next(m + for t in tspjsondata if t['type_variety'] == params['trx_type'] + for m in t['mode'] if m['format'] == params['trx_mode']) + except StopIteration : + msg = f'could not find tsp : {params} with mode: {params} in eqpt library' + raise ValueError(msg) + nd_list = req['optimizations']['explicit-route-include-objects'] + params['nodes_list'] = [n['unnumbered-hop']['node-id'] for n in nd_list] + params['loose_list'] = [n['unnumbered-hop']['hop-type'] for n in nd_list] + params['spacing'] = req['path-constraints']['te-bandwidth']['spacing'] + params['power'] = req['path-constraints']['te-bandwidth']['output-power'] + params['nb_channel'] = req['path-constraints']['te-bandwidth']['max-nb-of-channel'] + + params.update(extra_params) + requests_list.append(Path_request(**params)) return requests_list diff --git a/gnpy/core/info.py b/gnpy/core/info.py index 4f7b6ea7..167f9ebb 100644 --- a/gnpy/core/info.py +++ b/gnpy/core/info.py @@ -11,6 +11,8 @@ This module contains classes for modelling SpectralInformation. from collections import namedtuple from numpy import array from gnpy.core.utils import lin2db +from json import loads +from gnpy.core.utils import load_json class ConvenienceAccess: @@ -56,6 +58,11 @@ def create_input_spectral_information(f_min, roll_off, baudrate, power, spacing, baudrate, roll_off, Power(power, 0, 0)) for f in range(1,nb_channel+1))) return si +def load_SI(filename): + with open(filename) as f: + json_data = loads(f.read()) + return next(m for m in json_data['SI']) + if __name__ == '__main__': si = SpectralInformation( Channel(1, 193.95e12, 32e9, 0.15, # 193.95 THz, 32 Gbaud diff --git a/gnpy/core/request.py b/gnpy/core/request.py new file mode 100644 index 00000000..dcd839fa --- /dev/null +++ b/gnpy/core/request.py @@ -0,0 +1,180 @@ +#!/usr/bin/env python3 +# TelecomInfraProject/gnpy/examples +# Module name : path_requests_run.py +# Version : +# License : BSD 3-Clause Licence +# Copyright (c) 2018, Telecom Infra Project + +""" +@author: esther.lerouzic +@author: jeanluc-auge +read json request file in accordance with: + Yang model for requesting Path Computation + draft-ietf-teas-yang-path-computation-01.txt. +and returns path results in terms of path and feasibility + +""" + +from sys import exit +from argparse import ArgumentParser +from pathlib import Path +from collections import namedtuple +from logging import getLogger, basicConfig, CRITICAL, DEBUG, INFO +from json import dumps, loads +from networkx import (draw_networkx_nodes, draw_networkx_edges, + draw_networkx_labels, dijkstra_path, NetworkXNoPath) +from numpy import mean +from examples.convert_service_sheet import convert_service_sheet, Request_element, Element +from gnpy.core.utils import load_json +from gnpy.core.network import load_network, build_network +from gnpy.core.equipment import load_equipment +from gnpy.core.elements import Transceiver, Roadm, Edfa, Fused +from gnpy.core.utils import db2lin, lin2db +from gnpy.core.info import create_input_spectral_information, SpectralInformation, Channel, Power, load_SI +from copy import copy, deepcopy +from numpy import log10 + + +RequestParams = namedtuple('RequestParams','request_id source destination trx_type'+ +' trx_mode nodes_list loose_list spacing power nb_channel format baudrate OSNR bit_rate') + +class Path_request: + def __init__(self, *args, **params): + params = RequestParams(**params) + self.request_id = params.request_id + self.source = params.source + self.destination = params.destination + self.tsp = params.trx_type + self.tsp_mode = params.trx_mode + # retrieve baudrate out of transponder type and mode (format) + + self.baudrate = params.baudrate + self.nodes_list = params.nodes_list + self.loose_list = params.loose_list + self.spacing = params.spacing + self.power = params.power + self.nb_channel = params.nb_channel + +# class Path_request(Request): +# def __init__(self,*args, params=None, **kwargs): +# if params is None: +# params = {} +# super().__init__(*args, params=RequestParams(**params), **kwargs) + + def __str__(self): + return '\n\t'.join([ f'{type(self).__name__} {self.request_id}', + f'source: {self.source}', + f'destination: {self.destination}']) + def __repr__(self): + return '\n\t'.join([ f'{type(self).__name__} {self.request_id}', + f'source: {self.source}', + f'destination: {self.destination}', + f'trx type: {self.tsp}', + f'baudrate: {self.baudrate}', + f'spacing: {self.spacing}', + f'power: {self.power}' + '\n']) + +# class Path_request(): +# def __init__(self,jsondata,tspjsondata): +# self.request_id = jsondata['request-id'] +# self.source = jsondata['src-tp-id'] +# self.destination = jsondata['dst-tp-id'] +# # retrieving baudrate out of transponder type and mode (format) +# self.tsp = jsondata['path-constraints']['te-bandwidth']['trx_type'] +# self.tsp_mode = jsondata['path-constraints']['te-bandwidth']['trx_mode'] +# # for debug +# # print(tsp) +# try: +# baudrate = next(m['baudrate'] +# for t in tspjsondata if t['type_variety'] == self.tsp +# for m in t['mode'] if m['format'] == self.tsp_mode) +# except StopIteration: +# msg = f'could not find tsp : {self.tsp} with mode: {self.tsp_mode} in eqpt library' +# logger.critical(msg) +# raise ValueError(msg) +# self.baudrate = baudrate + +# nodes_list = jsondata['optimizations']['explicit-route-include-objects'] +# self.nodes_list = [n['unnumbered-hop']['node-id'] for n in nodes_list] +# # create a list for individual loose capability for each node ... +# # even if convert_service_sheet fills it with the same value +# self.loose_list = [n['unnumbered-hop']['hop-type'] for n in nodes_list] + +# self.spacing = jsondata['path-constraints']['te-bandwidth']['spacing'] +# self.power = jsondata['path-constraints']['te-bandwidth']['output-power'] +# self.nb_channel = jsondata['path-constraints']['te-bandwidth']['max-nb-of-channel'] + +# def __str__(self): +# return '\n\t'.join([ f'{type(self).__name__} {self.request_id}', +# f'source: {self.source}', +# f'destination: {self.destination}']) +# def __repr__(self): +# return '\n\t'.join([ f'{type(self).__name__} {self.request_id}', +# f'source: {self.source}', +# f'destination: {self.destination}', +# f'trx type: {self.tsp}', +# f'baudrate: {self.baudrate}', +# f'spacing: {self.spacing}', +# f'power: {self.power}' +# '\n']) + + +class Result_element(Element): + def __init__(self,path_request,computed_path): + self.path_id = int(path_request.request_id) + self.path_request = path_request + 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])) + else: + hop_type.append('not recorded') + self.hop_type = hop_type + uid = property(lambda self: repr(self)) + @property + def pathresult(self): + return { + 'path-id': self.path_id, + 'path-properties':{ + 'path-metric': [ + { + 'metric-type': 'SNR@bandwidth', + 'accumulative-value': round(mean(self.computed_path[-1].snr),2) + }, + { + 'metric-type': 'SNR@0.1nm', + 'accumulative-value': round(mean(self.computed_path[-1].snr+10*log10(self.path_request.baudrate/12.5)),2) + } + ], + 'path-srlgs': { + 'usage': 'not used yet', + 'values': 'not used yet' + }, + 'path-route-objects': [ + { + 'path-route-object': { + 'index': self.computed_path.index(n), + 'unnumbered-hop': { + 'node-id': n.uid, + 'link-tp-id': n.uid, + 'hop-type': self.hop_type[self.computed_path.index(n)], + 'direction': 'not used' + }, + 'label-hop': { + 'te-label': { + 'generic': 'not used yet', + 'direction': 'not used yet' + } + } + } + } for n in self.computed_path + ] + } + } + + @property + def json(self): + return self.pathresult + From 6d49769df9994e68ba7b9f87d5baefebf5ca7ecf Mon Sep 17 00:00:00 2001 From: EstherLerouzic Date: Thu, 5 Jul 2018 18:33:04 +0100 Subject: [PATCH 6/8] Refactor path_request_run and integration of functions to transmission - use load_equipment instead of load_SI - integrate the pathrequest class into transmission main Signed-off-by: EstherLerouzic --- examples/path_requests_run.py | 21 ++++------ examples/transmission_main_example.py | 47 +++++++++++++++++----- gnpy/core/info.py | 5 --- gnpy/core/request.py | 57 +++------------------------ 4 files changed, 51 insertions(+), 79 deletions(-) diff --git a/examples/path_requests_run.py b/examples/path_requests_run.py index fb8961aa..9f6d4f59 100644 --- a/examples/path_requests_run.py +++ b/examples/path_requests_run.py @@ -30,7 +30,7 @@ from gnpy.core.network import load_network, build_network from gnpy.core.equipment import load_equipment from gnpy.core.elements import Transceiver, Roadm, Edfa, Fused from gnpy.core.utils import db2lin, lin2db -from gnpy.core.info import create_input_spectral_information, SpectralInformation, Channel, Power, load_SI +from gnpy.core.info import create_input_spectral_information, SpectralInformation, Channel, Power from gnpy.core.request import Path_request, Result_element from copy import copy, deepcopy from numpy import log10 @@ -47,14 +47,9 @@ parser.add_argument('-v', '--verbose', action='count') parser.add_argument('-o', '--output', default=None) -def load_Transceiver(filename): - with open(filename) as f: - json_data = loads(f.read()) - return json_data['Transceiver'] - -def requests_from_json(json_data,eqpt_filename): +def requests_from_json(json_data,equipment): requests_list = [] - tspjsondata = load_Transceiver(eqpt_filename) + tsp_lib = equipment['Transceiver'] for req in json_data['path-request']: #print(f'{req}') @@ -66,8 +61,7 @@ def requests_from_json(json_data,eqpt_filename): params['trx_mode'] = req['path-constraints']['te-bandwidth']['trx_mode'] try: extra_params = next(m - for t in tspjsondata if t['type_variety'] == params['trx_type'] - for m in t['mode'] if m['format'] == params['trx_mode']) + for m in tsp_lib[params['trx_type']].mode if m['format'] == params['trx_mode']) except StopIteration : msg = f'could not find tsp : {params} with mode: {params} in eqpt library' raise ValueError(msg) @@ -103,7 +97,8 @@ def compute_path(network, pathreqlist): edfa = [n for n in network.nodes() if isinstance(n, Edfa)] # TODO include also fused in the element check : too difficult because of direction # fused = [n for n in network.nodes() if isinstance(n, Fused)] - sidata = load_SI(args.eqpt_filename) + sidata = equipment['SI']['default'] + for pathreq in pathreqlist: pathreq.nodes_list.append(pathreq.destination) #we assume that the destination is a strict constraint @@ -148,7 +143,7 @@ def compute_path(network, pathreqlist): # for debug # print(f'{pathreq.baudrate} {pathreq.power} {pathreq.spacing} {pathreq.nb_channel}') si = create_input_spectral_information( - sidata['f_min'], sidata['roll_off'], + sidata.f_min, sidata.roll_off, pathreq.baudrate, pathreq.power, pathreq.spacing, pathreq.nb_channel) for el in total_path: si = el(si) @@ -182,7 +177,7 @@ if __name__ == '__main__': equipment = load_equipment(args.eqpt_filename) network = load_network(args.network_filename,equipment) build_network(network, equipment=equipment) - pths = requests_from_json(data, args.eqpt_filename) + pths = requests_from_json(data, equipment) print(pths) test = compute_path(network,pths) diff --git a/examples/transmission_main_example.py b/examples/transmission_main_example.py index 2b6ba111..b4eb6706 100755 --- a/examples/transmission_main_example.py +++ b/examples/transmission_main_example.py @@ -20,7 +20,8 @@ from networkx import (draw_networkx_nodes, draw_networkx_edges, from gnpy.core import load_network, build_network from gnpy.core.elements import Transceiver, Fiber, Edfa, Roadm -from gnpy.core.info import SpectralInformation, Channel, Power +from gnpy.core.info import create_input_spectral_information, SpectralInformation, Channel, Power +from gnpy.core.request import Path_request, RequestParams logger = getLogger(__name__) @@ -48,21 +49,29 @@ def plot_results(network, path, source, sink): show() -def main(network, equipment, source, sink): +def main(network, equipment, source, sink, req = None): build_network(network, equipment=equipment) + + sidata = equipment['SI']['default'] + + print(sidata) + print('\n\n\n') path = dijkstra_path(network, source, sink) spans = [s.length for s in path if isinstance(s, Fiber)] print(f'\nThere are {len(spans)} fiber spans over {sum(spans):.0f}m between {source.uid} and {sink.uid}') print(f'\nNow propagating between {source.uid} and {sink.uid}:') - + for p in range(0, 1): #change range to sweep results across several powers in dBm p=db2lin(p)*1e-3 spacing = 0.05 # THz - si = SpectralInformation() # SI units: W, Hz - si = si.update(carriers=[ - Channel(f, (191.3 + spacing * f) * 1e12, 32e9, 0.15, Power(p, 0, 0)) - for f in range(1,97) - ]) + # si = SpectralInformation() # SI units: W, Hz + si = create_input_spectral_information( + sidata.f_min, sidata.roll_off, + req.baudrate, p, req.spacing, req.nb_channel) + # si = si.update(carriers=[ + # Channel(f, (191.3 + spacing * f) * 1e12, 32e9, 0.15, Power(p, 0, 0)) + # for f in range(1,97) + # ]) print(f'\nPropagating with input power = {lin2db(p*1e3):.2f}dBm :') for el in path: si = el(si) @@ -135,7 +144,27 @@ if __name__ == '__main__': logger.info(f'source = {args.source!r}') logger.info(f'sink = {args.sink!r}') - path = main(network, equipment, source, sink) + + params = {} + params['request_id'] = 0 + params['source'] = args.source + params['destination'] = args.sink + params['trx_type'] = 'vendorA_trx-type1' + params['trx_mode'] = 'PS_SP64_1' + params['nodes_list'] = [] + params['loose_list'] = [] + params['spacing'] = 50e9 + params['power'] = -1 + params['nb_channel'] = 80 + try: + extra_params = next(m + for m in equipment['Transceiver'][params['trx_type']].mode if m['format'] == params['trx_mode']) + except StopIteration : + msg = f'could not find tsp : {params} with mode: {params} in eqpt library' + raise ValueError(msg) + params.update(extra_params) + req = Path_request(**params) + path = main(network, equipment, source, sink,req) if args.plot: plot_results(network, path, source, sink) diff --git a/gnpy/core/info.py b/gnpy/core/info.py index 167f9ebb..df8edea5 100644 --- a/gnpy/core/info.py +++ b/gnpy/core/info.py @@ -58,11 +58,6 @@ def create_input_spectral_information(f_min, roll_off, baudrate, power, spacing, baudrate, roll_off, Power(power, 0, 0)) for f in range(1,nb_channel+1))) return si -def load_SI(filename): - with open(filename) as f: - json_data = loads(f.read()) - return next(m for m in json_data['SI']) - if __name__ == '__main__': si = SpectralInformation( Channel(1, 193.95e12, 32e9, 0.15, # 193.95 THz, 32 Gbaud diff --git a/gnpy/core/request.py b/gnpy/core/request.py index dcd839fa..9b24d099 100644 --- a/gnpy/core/request.py +++ b/gnpy/core/request.py @@ -30,7 +30,7 @@ from gnpy.core.network import load_network, build_network from gnpy.core.equipment import load_equipment from gnpy.core.elements import Transceiver, Roadm, Edfa, Fused from gnpy.core.utils import db2lin, lin2db -from gnpy.core.info import create_input_spectral_information, SpectralInformation, Channel, Power, load_SI +from gnpy.core.info import create_input_spectral_information, SpectralInformation, Channel, Power from copy import copy, deepcopy from numpy import log10 @@ -54,12 +54,10 @@ class Path_request: self.spacing = params.spacing self.power = params.power self.nb_channel = params.nb_channel - -# class Path_request(Request): -# def __init__(self,*args, params=None, **kwargs): -# if params is None: -# params = {} -# super().__init__(*args, params=RequestParams(**params), **kwargs) + self.format = params.format + self.OSNR = params.OSNR + self.bit_rate = params.bit_rate + def __str__(self): return '\n\t'.join([ f'{type(self).__name__} {self.request_id}', @@ -75,51 +73,6 @@ class Path_request: f'power: {self.power}' '\n']) -# class Path_request(): -# def __init__(self,jsondata,tspjsondata): -# self.request_id = jsondata['request-id'] -# self.source = jsondata['src-tp-id'] -# self.destination = jsondata['dst-tp-id'] -# # retrieving baudrate out of transponder type and mode (format) -# self.tsp = jsondata['path-constraints']['te-bandwidth']['trx_type'] -# self.tsp_mode = jsondata['path-constraints']['te-bandwidth']['trx_mode'] -# # for debug -# # print(tsp) -# try: -# baudrate = next(m['baudrate'] -# for t in tspjsondata if t['type_variety'] == self.tsp -# for m in t['mode'] if m['format'] == self.tsp_mode) -# except StopIteration: -# msg = f'could not find tsp : {self.tsp} with mode: {self.tsp_mode} in eqpt library' -# logger.critical(msg) -# raise ValueError(msg) -# self.baudrate = baudrate - -# nodes_list = jsondata['optimizations']['explicit-route-include-objects'] -# self.nodes_list = [n['unnumbered-hop']['node-id'] for n in nodes_list] -# # create a list for individual loose capability for each node ... -# # even if convert_service_sheet fills it with the same value -# self.loose_list = [n['unnumbered-hop']['hop-type'] for n in nodes_list] - -# self.spacing = jsondata['path-constraints']['te-bandwidth']['spacing'] -# self.power = jsondata['path-constraints']['te-bandwidth']['output-power'] -# self.nb_channel = jsondata['path-constraints']['te-bandwidth']['max-nb-of-channel'] - -# def __str__(self): -# return '\n\t'.join([ f'{type(self).__name__} {self.request_id}', -# f'source: {self.source}', -# f'destination: {self.destination}']) -# def __repr__(self): -# return '\n\t'.join([ f'{type(self).__name__} {self.request_id}', -# f'source: {self.source}', -# f'destination: {self.destination}', -# f'trx type: {self.tsp}', -# f'baudrate: {self.baudrate}', -# f'spacing: {self.spacing}', -# f'power: {self.power}' -# '\n']) - - class Result_element(Element): def __init__(self,path_request,computed_path): self.path_id = int(path_request.request_id) From e9aa4d5601b3c061a61409c37fa3c75aab516867 Mon Sep 17 00:00:00 2001 From: EstherLerouzic Date: Fri, 6 Jul 2018 17:32:56 +0100 Subject: [PATCH 7/8] Integration of Path_request_run functionalities into transmisson_main_example creation of modular functions to be called use of the same propagate function in both examples Signed-off-by: EstherLerouzic --- examples/path_requests_run.py | 98 +++++++++++++-------------- examples/transmission_main_example.py | 39 ++++------- gnpy/core/request.py | 52 ++++++++++++++ tests/propagation_test.py | 7 +- 4 files changed, 117 insertions(+), 79 deletions(-) diff --git a/examples/path_requests_run.py b/examples/path_requests_run.py index 9f6d4f59..89ebeb02 100644 --- a/examples/path_requests_run.py +++ b/examples/path_requests_run.py @@ -31,7 +31,7 @@ from gnpy.core.equipment import load_equipment from gnpy.core.elements import Transceiver, Roadm, Edfa, Fused from gnpy.core.utils import db2lin, lin2db from gnpy.core.info import create_input_spectral_information, SpectralInformation, Channel, Power -from gnpy.core.request import Path_request, Result_element +from gnpy.core.request import Path_request, Result_element, compute_constrained_path, propagate from copy import copy, deepcopy from numpy import log10 @@ -87,67 +87,66 @@ def load_requests(filename,eqpt_filename): json_data = loads(f.read()) return json_data +# def compute_constrained_path(network, req): +# trx = [n for n in network.nodes() if isinstance(n, Transceiver)] +# roadm = [n for n in network.nodes() if isinstance(n, Roadm)] +# edfa = [n for n in network.nodes() if isinstance(n, Edfa)] + +# source = next(el for el in trx if el.uid == req.source) +# # start the path with its source +# total_path = [source] +# for n in req.nodes_list: +# # print(n) +# try : +# node = next(el for el in trx if el.uid == n) +# except StopIteration: +# try: +# node = next(el for el in roadm if el.uid == f'roadm {n}') +# except StopIteration: +# try: +# 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: \ +# not a trx, roadm, edfa or fused element' +# logger.critical(msg) +# raise ValueError(msg) +# # extend path list without repeating source -> skip first element in the list +# try: +# total_path.extend(dijkstra_path(network, source, node)[1:]) +# source = node +# except NetworkXNoPath: +# # for debug +# # print(req.loose_list) +# # print(req.nodes_list.index(n)) +# if req.loose_list[req.nodes_list.index(n)] == 'loose': +# print(f'could not find a path from {source.uid} to loose node : {n} in network topology') +# print(f'node {n} is skipped') +# else: +# msg = f'could not find a path from {source.uid} to node : {n} in network topology' +# logger.critical(msg) +# raise ValueError(msg) +# return total_path + def compute_path(network, pathreqlist): # temporary : repeats calls from transmission_main_example # to be merged when ready path_res_list = [] - trx = [n for n in network.nodes() if isinstance(n, Transceiver)] - roadm = [n for n in network.nodes() if isinstance(n, Roadm)] - edfa = [n for n in network.nodes() if isinstance(n, Edfa)] - # TODO include also fused in the element check : too difficult because of direction - # fused = [n for n in network.nodes() if isinstance(n, Fused)] - sidata = equipment['SI']['default'] - + for pathreq in pathreqlist: pathreq.nodes_list.append(pathreq.destination) #we assume that the destination is a strict constraint pathreq.loose_list.append('strict') print(f'Computing path from {pathreq.source} to {pathreq.destination}') print(f'with explicit path: {pathreq.nodes_list}') - - source = next(el for el in trx if el.uid == pathreq.source) - # start the path with its source - total_path = [source] - for n in pathreq.nodes_list: - # print(n) - try : - node = next(el for el in trx if el.uid == n) - except StopIteration: - try: - node = next(el for el in roadm if el.uid == f'roadm {n}') - except StopIteration: - try: - 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: \ - not a trx, roadm, edfa or fused element' - logger.critical(msg) - raise ValueError(msg) - # extend path list without repeating source -> skip first element in the list - try: - total_path.extend(dijkstra_path(network, source, node)[1:]) - source = node - except NetworkXNoPath: - # for debug - # print(pathreq.loose_list) - # print(pathreq.nodes_list.index(n)) - if pathreq.loose_list[pathreq.nodes_list.index(n)] == 'loose': - print(f'could not find a path from {source.uid} to loose node : {n} in network topology') - print(f'node {n} is skipped') - else: - msg = f'could not find a path from {source.uid} to node : {n} in network topology' - logger.critical(msg) - raise ValueError(msg) + total_path = compute_constrained_path(network, pathreq) + # for debug # print(f'{pathreq.baudrate} {pathreq.power} {pathreq.spacing} {pathreq.nb_channel}') - si = create_input_spectral_information( - sidata.f_min, sidata.roll_off, - pathreq.baudrate, pathreq.power, pathreq.spacing, pathreq.nb_channel) - for el in total_path: - si = el(si) - # print(el) + + total_path = propagate(total_path,pathreq,equipment, show=False) + # we record the last tranceiver object in order to have th whole # information about spectrum. Important Note: since transceivers # attached to roadms are actually logical elements to simulate @@ -156,7 +155,6 @@ def compute_path(network, pathreqlist): # we use deepcopy: to ensure each propagation is recorded and not # overwritten - # path_res_list.append(deepcopy(destination)) path_res_list.append(deepcopy(total_path)) return path_res_list diff --git a/examples/transmission_main_example.py b/examples/transmission_main_example.py index b4eb6706..c7355546 100755 --- a/examples/transmission_main_example.py +++ b/examples/transmission_main_example.py @@ -21,7 +21,7 @@ from networkx import (draw_networkx_nodes, draw_networkx_edges, from gnpy.core import load_network, build_network from gnpy.core.elements import Transceiver, Fiber, Edfa, Roadm from gnpy.core.info import create_input_spectral_information, SpectralInformation, Channel, Power -from gnpy.core.request import Path_request, RequestParams +from gnpy.core.request import Path_request, RequestParams, compute_constrained_path, propagate logger = getLogger(__name__) @@ -52,31 +52,16 @@ def plot_results(network, path, source, sink): def main(network, equipment, source, sink, req = None): build_network(network, equipment=equipment) - sidata = equipment['SI']['default'] - - print(sidata) - print('\n\n\n') - path = dijkstra_path(network, source, sink) + path = compute_constrained_path(network,req) spans = [s.length for s in path if isinstance(s, Fiber)] print(f'\nThere are {len(spans)} fiber spans over {sum(spans):.0f}m between {source.uid} and {sink.uid}') print(f'\nNow propagating between {source.uid} and {sink.uid}:') for p in range(0, 1): #change range to sweep results across several powers in dBm - p=db2lin(p)*1e-3 - spacing = 0.05 # THz - # si = SpectralInformation() # SI units: W, Hz - si = create_input_spectral_information( - sidata.f_min, sidata.roll_off, - req.baudrate, p, req.spacing, req.nb_channel) - # si = si.update(carriers=[ - # Channel(f, (191.3 + spacing * f) * 1e12, 32e9, 0.15, Power(p, 0, 0)) - # for f in range(1,97) - # ]) - print(f'\nPropagating with input power = {lin2db(p*1e3):.2f}dBm :') - for el in path: - si = el(si) - print(el) #remove this line when sweeping across several powers - print(f'\nTransmission result for input power = {lin2db(p*1e3):.2f}dBm :') + req.power = db2lin(p)*1e-3 + print(f'\nPropagating with input power = {lin2db(req.power*1e3):.2f}dBm :') + propagate(path,req,equipment,show=True) + print(f'\nTransmission result for input power = {lin2db(req.power*1e3):.2f}dBm :') print(sink) return path @@ -147,15 +132,15 @@ if __name__ == '__main__': params = {} params['request_id'] = 0 - params['source'] = args.source - params['destination'] = args.sink + params['source'] = source.uid + params['destination'] = sink.uid params['trx_type'] = 'vendorA_trx-type1' params['trx_mode'] = 'PS_SP64_1' - params['nodes_list'] = [] - params['loose_list'] = [] + params['nodes_list'] = [sink.uid] + params['loose_list'] = ['strict'] params['spacing'] = 50e9 - params['power'] = -1 - params['nb_channel'] = 80 + params['power'] = 0 + params['nb_channel'] = 97 try: extra_params = next(m for m in equipment['Transceiver'][params['trx_type']].mode if m['format'] == params['trx_mode']) diff --git a/gnpy/core/request.py b/gnpy/core/request.py index 9b24d099..b045960c 100644 --- a/gnpy/core/request.py +++ b/gnpy/core/request.py @@ -131,3 +131,55 @@ class Result_element(Element): def json(self): return self.pathresult +def compute_constrained_path(network, req): + trx = [n for n in network.nodes() if isinstance(n, Transceiver)] + roadm = [n for n in network.nodes() if isinstance(n, Roadm)] + edfa = [n for n in network.nodes() if isinstance(n, Edfa)] + + source = next(el for el in trx if el.uid == req.source) + # start the path with its source + total_path = [source] + for n in req.nodes_list: + # print(n) + try : + node = next(el for el in trx if el.uid == n) + except StopIteration: + try: + node = next(el for el in roadm if el.uid == f'roadm {n}') + except StopIteration: + try: + 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: \ + not a trx, roadm, edfa or fused element' + logger.critical(msg) + raise ValueError(msg) + # extend path list without repeating source -> skip first element in the list + try: + total_path.extend(dijkstra_path(network, source, node)[1:]) + source = node + except NetworkXNoPath: + # for debug + # print(req.loose_list) + # print(req.nodes_list.index(n)) + if req.loose_list[req.nodes_list.index(n)] == 'loose': + print(f'could not find a path from {source.uid} to loose node : {n} in network topology') + print(f'node {n} is skipped') + else: + msg = f'could not find a path from {source.uid} to node : {n} in network topology' + logger.critical(msg) + raise ValueError(msg) + return total_path + +def propagate(path,req,equipment, show=False): + default_si_data = equipment['SI']['default'] + si = create_input_spectral_information( + default_si_data.f_min, default_si_data.roll_off, + req.baudrate, req.power, req.spacing, req.nb_channel) + # TODO : use tsp f_min instead of default + for el in path: + si = el(si) + if show : + print(el) + return path \ No newline at end of file diff --git a/tests/propagation_test.py b/tests/propagation_test.py index debc8dbb..7fc5576d 100644 --- a/tests/propagation_test.py +++ b/tests/propagation_test.py @@ -58,10 +58,13 @@ def propagation(input_power, connector_loss_in, connector_loss_out,dest): # print(f'\nPropagating with input power = {lin2db(p*1e3):.2f}dBm :') for el in path: si = el(si) - if isinstance(el, Edfa): - nf = mean(el.nf) + # if isinstance(el, Edfa): + # nf = mean(el.nf) print(el) #remove this line when sweeping across several powers # print(f'\nTransmission result for input power = {lin2db(p*1e3):.2f}dBm :') + edfa_sample = next(el for el in path if isinstance(el, Edfa)) + nf = mean(edfa_sample.nf) + print(f'pw: {input_power} conn in: {connector_loss_in} con out: {connector_loss_out} ' + f'OSNR@0.1nm: {round(mean(sink.osnr_ase_01nm),2)} SNR@bandwitdth: {round(mean(sink.snr),2)}') return sink , nf From 55393ca9eb8bbf8103885cbe7fe99dc85bebefa6 Mon Sep 17 00:00:00 2001 From: EstherLerouzic Date: Mon, 9 Jul 2018 10:24:34 +0100 Subject: [PATCH 8/8] implement the use of TSP f_min - tsp fmin is used instead of default SI value Signed-off-by: EstherLerouzic --- examples/path_requests_run.py | 48 ++------------------------- examples/transmission_main_example.py | 4 ++- gnpy/core/request.py | 12 +++---- 3 files changed, 11 insertions(+), 53 deletions(-) diff --git a/examples/path_requests_run.py b/examples/path_requests_run.py index 89ebeb02..e61ed3c8 100644 --- a/examples/path_requests_run.py +++ b/examples/path_requests_run.py @@ -59,11 +59,12 @@ def requests_from_json(json_data,equipment): params['destination'] = req['dst-tp-id'] params['trx_type'] = req['path-constraints']['te-bandwidth']['trx_type'] params['trx_mode'] = req['path-constraints']['te-bandwidth']['trx_mode'] + params['frequency'] = tsp_lib[params['trx_type']].frequency try: - extra_params = next(m + extra_params = next(m for m in tsp_lib[params['trx_type']].mode if m['format'] == params['trx_mode']) except StopIteration : - msg = f'could not find tsp : {params} with mode: {params} in eqpt library' + msg = f'could not find tsp : {params["trx_type"]} with mode: {params["trx_mode"]} in eqpt library' raise ValueError(msg) nd_list = req['optimizations']['explicit-route-include-objects'] params['nodes_list'] = [n['unnumbered-hop']['node-id'] for n in nd_list] @@ -87,50 +88,7 @@ def load_requests(filename,eqpt_filename): json_data = loads(f.read()) return json_data -# def compute_constrained_path(network, req): -# trx = [n for n in network.nodes() if isinstance(n, Transceiver)] -# roadm = [n for n in network.nodes() if isinstance(n, Roadm)] -# edfa = [n for n in network.nodes() if isinstance(n, Edfa)] - -# source = next(el for el in trx if el.uid == req.source) -# # start the path with its source -# total_path = [source] -# for n in req.nodes_list: -# # print(n) -# try : -# node = next(el for el in trx if el.uid == n) -# except StopIteration: -# try: -# node = next(el for el in roadm if el.uid == f'roadm {n}') -# except StopIteration: -# try: -# 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: \ -# not a trx, roadm, edfa or fused element' -# logger.critical(msg) -# raise ValueError(msg) -# # extend path list without repeating source -> skip first element in the list -# try: -# total_path.extend(dijkstra_path(network, source, node)[1:]) -# source = node -# except NetworkXNoPath: -# # for debug -# # print(req.loose_list) -# # print(req.nodes_list.index(n)) -# if req.loose_list[req.nodes_list.index(n)] == 'loose': -# print(f'could not find a path from {source.uid} to loose node : {n} in network topology') -# print(f'node {n} is skipped') -# else: -# msg = f'could not find a path from {source.uid} to node : {n} in network topology' -# logger.critical(msg) -# raise ValueError(msg) -# return total_path - def compute_path(network, pathreqlist): - # temporary : repeats calls from transmission_main_example - # to be merged when ready path_res_list = [] diff --git a/examples/transmission_main_example.py b/examples/transmission_main_example.py index c7355546..342bb3c7 100755 --- a/examples/transmission_main_example.py +++ b/examples/transmission_main_example.py @@ -141,9 +141,11 @@ if __name__ == '__main__': params['spacing'] = 50e9 params['power'] = 0 params['nb_channel'] = 97 + params['frequency'] = equipment['Transceiver'][params['trx_type']].frequency try: extra_params = next(m - for m in equipment['Transceiver'][params['trx_type']].mode if m['format'] == params['trx_mode']) + for m in equipment['Transceiver'][params['trx_type']].mode + if m['format'] == params['trx_mode']) except StopIteration : msg = f'could not find tsp : {params} with mode: {params} in eqpt library' raise ValueError(msg) diff --git a/gnpy/core/request.py b/gnpy/core/request.py index b045960c..756a04cd 100644 --- a/gnpy/core/request.py +++ b/gnpy/core/request.py @@ -36,24 +36,23 @@ from numpy import log10 RequestParams = namedtuple('RequestParams','request_id source destination trx_type'+ -' trx_mode nodes_list loose_list spacing power nb_channel format baudrate OSNR bit_rate') +' trx_mode nodes_list loose_list spacing power nb_channel frequency format baudrate OSNR bit_rate') class Path_request: def __init__(self, *args, **params): params = RequestParams(**params) self.request_id = params.request_id - self.source = params.source + self.source = params.source self.destination = params.destination self.tsp = params.trx_type self.tsp_mode = params.trx_mode - # retrieve baudrate out of transponder type and mode (format) - - self.baudrate = params.baudrate + self.baudrate = params.baudrate self.nodes_list = params.nodes_list self.loose_list = params.loose_list self.spacing = params.spacing self.power = params.power self.nb_channel = params.nb_channel + self.frequency = params.frequency self.format = params.format self.OSNR = params.OSNR self.bit_rate = params.bit_rate @@ -175,9 +174,8 @@ def compute_constrained_path(network, req): def propagate(path,req,equipment, show=False): default_si_data = equipment['SI']['default'] si = create_input_spectral_information( - default_si_data.f_min, default_si_data.roll_off, + req.frequency['min'], default_si_data.roll_off, req.baudrate, req.power, req.spacing, req.nb_channel) - # TODO : use tsp f_min instead of default for el in path: si = el(si) if show :