From a3b1157e383aabc383433cac3bd3983083a0d22a Mon Sep 17 00:00:00 2001 From: AndreaDAmico Date: Mon, 7 Aug 2023 18:26:32 +0200 Subject: [PATCH] Fiber latency calculation Fiber latency evaluated during propagation. The speed of ligth in fiber is evaluated as the vacuum speed of ligth divided by the core reflective index n1. The latency in the transceiver is evaluated in ms. Change-Id: I7a3638c49f346aecaf1d4897cecf96d345fdb26c --- gnpy/core/elements.py | 18 ++++++++++++- gnpy/core/info.py | 27 ++++++++++++++----- gnpy/core/parameters.py | 6 +++++ .../openroadm-v4-Stockholm-Gothenburg | 2 ++ .../openroadm-v5-Stockholm-Gothenburg | 2 ++ .../spectrum1_transmission_main_example | 2 ++ .../spectrum2_transmission_main_example | 2 ++ tests/invocation/transmission_main_example | 2 ++ .../transmission_main_example__raman | 2 ++ .../invocation/transmission_main_example_long | 2 ++ tests/invocation/transmission_saturated | 2 ++ 11 files changed, 60 insertions(+), 7 deletions(-) diff --git a/gnpy/core/elements.py b/gnpy/core/elements.py index f945c462..e545b2b3 100644 --- a/gnpy/core/elements.py +++ b/gnpy/core/elements.py @@ -87,6 +87,7 @@ class Transceiver(_Node): self.chromatic_dispersion = None self.pmd = None self.pdl = None + self.latency = None self.penalties = {} self.total_penalty = 0 self.propagated_labels = [""] @@ -106,6 +107,11 @@ class Transceiver(_Node): """ self.pdl = spectral_info.pdl + def _calc_latency(self, spectral_info): + """Updates the Transceiver property with the latency of the received channels. Latency in ms. + """ + self.latency = spectral_info.latency * 1e3 + def _calc_penalty(self, impairment_value, boundary_list): return interp(impairment_value, boundary_list['up_to_boundary'], boundary_list['penalty_value'], left=float('inf'), right=float('inf')) @@ -172,6 +178,7 @@ class Transceiver(_Node): f'chromatic_dispersion={self.chromatic_dispersion!r}, ' f'pmd={self.pmd!r}, ' f'pdl={self.pdl!r}, ' + f'latency={self.latency!r}, ' f'penalties={self.penalties!r})') def __str__(self): @@ -185,6 +192,7 @@ class Transceiver(_Node): cd = mean(self.chromatic_dispersion) pmd = mean(self.pmd) pdl = mean(self.pdl) + latency = mean(self.latency) result = '\n'.join([f'{type(self).__name__} {self.uid}', f' GSNR (0.1nm, dB): {pretty_summary_print(snr_01nm)}', @@ -193,7 +201,8 @@ class Transceiver(_Node): f' OSNR ASE (signal bw, dB): {pretty_summary_print(osnr_ase)}', f' CD (ps/nm): {cd:.2f}', f' PMD (ps): {pmd:.2f}', - f' PDL (dB): {pdl:.2f}']) + f' PDL (dB): {pdl:.2f}', + f' Latency (ms): {latency:.2f}']) cd_penalty = self.penalties.get('chromatic_dispersion') if cd_penalty is not None: @@ -212,6 +221,7 @@ class Transceiver(_Node): self._calc_cd(spectral_info) self._calc_pmd(spectral_info) self._calc_pdl(spectral_info) + self._calc_latency(spectral_info) return spectral_info @@ -596,6 +606,9 @@ class Fiber(_Node): spectral_info.chromatic_dispersion += self.chromatic_dispersion(spectral_info.frequency) spectral_info.pmd = sqrt(spectral_info.pmd ** 2 + self.pmd ** 2) + # latency + spectral_info.latency += self.params.latency + # apply the attenuation due to the fiber losses attenuation_fiber = stimulated_raman_scattering.loss_profile[:, -1] spectral_info.apply_attenuation_lin(attenuation_fiber) @@ -669,6 +682,9 @@ class RamanFiber(Fiber): spectral_info.chromatic_dispersion += self.chromatic_dispersion(spectral_info.frequency) spectral_info.pmd = sqrt(spectral_info.pmd ** 2 + self.pmd ** 2) + # latency + spectral_info.latency += self.params.latency + # apply the attenuation due to the fiber losses attenuation_fiber = stimulated_raman_scattering.loss_profile[:spectral_info.number_of_channels, -1] diff --git a/gnpy/core/info.py b/gnpy/core/info.py index 6f6fcbe8..8046c24a 100644 --- a/gnpy/core/info.py +++ b/gnpy/core/info.py @@ -27,8 +27,9 @@ class Power(namedtuple('Power', 'signal nli ase')): """carriers power in W""" -class Channel(namedtuple('Channel', - 'channel_number frequency baud_rate slot_width roll_off power chromatic_dispersion pmd pdl')): +class Channel( + namedtuple('Channel', + 'channel_number frequency baud_rate slot_width roll_off power chromatic_dispersion pmd pdl latency')): """Class containing the parameters of a WDM signal. :param channel_number: channel number in the WDM grid @@ -40,6 +41,7 @@ class Channel(namedtuple('Channel', :param chromatic_dispersion: chromatic dispersion (s/m) :param pmd: polarization mode dispersion (s) :param pdl: polarization dependent loss (dB) + :param latency: propagation latency (s) """ @@ -58,8 +60,8 @@ class SpectralInformation(object): delta_pdb_per_channel: (per frequency) per channel delta power in dbm for the actual mix of channels""" def __init__(self, frequency: array, baud_rate: array, slot_width: array, signal: array, nli: array, ase: array, - roll_off: array, chromatic_dispersion: array, pmd: array, pdl: array, delta_pdb_per_channel: array, - tx_osnr: array, ref_power: Pref, label: array): + roll_off: array, chromatic_dispersion: array, pmd: array, pdl: array, latency: array, + delta_pdb_per_channel: array, tx_osnr: array, ref_power: Pref, label: array): indices = argsort(frequency) self._frequency = frequency[indices] self._df = outer(ones(frequency.shape), frequency) - outer(frequency, ones(frequency.shape)) @@ -84,6 +86,7 @@ class SpectralInformation(object): self._chromatic_dispersion = chromatic_dispersion[indices] self._pmd = pmd[indices] self._pdl = pdl[indices] + self._latency = latency[indices] self._delta_pdb_per_channel = delta_pdb_per_channel[indices] self._tx_osnr = tx_osnr[indices] self._pref = ref_power @@ -180,6 +183,14 @@ class SpectralInformation(object): def pdl(self, pdl): self._pdl = pdl + @property + def latency(self): + return self._latency + + @latency.setter + def latency(self, latency): + self._latency = latency + @property def delta_pdb_per_channel(self): return self._delta_pdb_per_channel @@ -203,7 +214,7 @@ class SpectralInformation(object): @property def carriers(self): entries = zip(self.channel_number, self.frequency, self.baud_rate, self.slot_width, - self.roll_off, self.powers, self.chromatic_dispersion, self.pmd, self.pdl) + self.roll_off, self.powers, self.chromatic_dispersion, self.pmd, self.pdl, self.latency) return [Channel(*entry) for entry in entries] def apply_attenuation_lin(self, attenuation_lin): @@ -242,6 +253,7 @@ class SpectralInformation(object): other.chromatic_dispersion), pmd=append(self.pmd, other.pmd), pdl=append(self.pdl, other.pdl), + latency=append(self.latency, other.latency), delta_pdb_per_channel=append(self.delta_pdb_per_channel, other.delta_pdb_per_channel), tx_osnr=append(self.tx_osnr, other.tx_osnr), @@ -255,6 +267,7 @@ class SpectralInformation(object): self.chromatic_dispersion = array([c.chromatic_dispersion for c in carriers]) self.pmd = array([c.pmd for c in carriers]) self.pdl = array([c.pdl for c in carriers]) + self.latency = array([c.latency for c in carriers]) self.signal = array([c.power.signal for c in carriers]) self.nli = array([c.power.nli for c in carriers]) self.ase = array([c.power.ase for c in carriers]) @@ -272,6 +285,7 @@ def create_arbitrary_spectral_information(frequency: Union[ndarray, Iterable, fl chromatic_dispersion: Union[float, ndarray, Iterable] = 0., pmd: Union[float, ndarray, Iterable] = 0., pdl: Union[float, ndarray, Iterable] = 0., + latency: Union[float, ndarray, Iterable] = 0., ref_power: Pref = None, label: Union[str, ndarray, Iterable] = None): """This is just a wrapper around the SpectralInformation.__init__() that simplifies the creation of @@ -287,6 +301,7 @@ def create_arbitrary_spectral_information(frequency: Union[ndarray, Iterable, fl chromatic_dispersion = full(number_of_channels, chromatic_dispersion) pmd = full(number_of_channels, pmd) pdl = full(number_of_channels, pdl) + latency = full(number_of_channels, latency) nli = zeros(number_of_channels) ase = zeros(number_of_channels) delta_pdb_per_channel = full(number_of_channels, delta_pdb_per_channel) @@ -296,7 +311,7 @@ def create_arbitrary_spectral_information(frequency: Union[ndarray, Iterable, fl signal=signal, nli=nli, ase=ase, baud_rate=baud_rate, roll_off=roll_off, chromatic_dispersion=chromatic_dispersion, - pmd=pmd, pdl=pdl, + pmd=pmd, pdl=pdl, latency=latency, delta_pdb_per_channel=delta_pdb_per_channel, tx_osnr=tx_osnr, ref_power=ref_power, label=label) diff --git a/gnpy/core/parameters.py b/gnpy/core/parameters.py index 43dc5a7b..3f6811fc 100644 --- a/gnpy/core/parameters.py +++ b/gnpy/core/parameters.py @@ -158,6 +158,7 @@ class FiberParams(Parameters): self._beta3 = ((self.dispersion_slope - (4*pi*c/self.ref_wavelength**3) * self.beta2) / (2*pi*c/self.ref_wavelength**2)**2) self._effective_area = kwargs.get('effective_area') # m^2 + self._n1 = 1.468 n2 = 2.6e-20 # m^2/W if self._effective_area: self._gamma = kwargs.get('gamma', 2 * pi * n2 / (self.ref_wavelength * self._effective_area)) # 1/W/m @@ -177,6 +178,7 @@ class FiberParams(Parameters): self._loss_coef = asarray(kwargs['loss_coef']) * 1e-3 # lineic loss dB/m self._f_loss_ref = asarray(self._ref_frequency) # Hz self._lumped_losses = kwargs['lumped_losses'] if 'lumped_losses' in kwargs else [] + self._latency = self._length / (c / self._n1) # s except KeyError as e: raise ParametersError(f'Fiber configurations json must include {e}. Configuration: {kwargs}') @@ -261,6 +263,10 @@ class FiberParams(Parameters): def raman_efficiency(self): return self._raman_efficiency + @property + def latency(self): + return self._latency + def asdict(self): dictionary = super().asdict() dictionary['loss_coef'] = self.loss_coef * 1e3 diff --git a/tests/invocation/openroadm-v4-Stockholm-Gothenburg b/tests/invocation/openroadm-v4-Stockholm-Gothenburg index 0e094609..ae887a75 100644 --- a/tests/invocation/openroadm-v4-Stockholm-Gothenburg +++ b/tests/invocation/openroadm-v4-Stockholm-Gothenburg @@ -15,6 +15,7 @@ Transceiver trx_Stockholm CD (ps/nm): 0.00 PMD (ps): 0.00 PDL (dB): 0.00 + Latency (ms): 0.00 Roadm roadm_Stockholm effective loss (dB): 22.00 reference pch out (dBm): -20.00 @@ -255,6 +256,7 @@ Transceiver trx_Gothenburg CD (ps/nm): 8350.42 PMD (ps): 7.99 PDL (dB): 3.74 + Latency (ms): 2.45 Transmission result for input power = 2.00 dBm: Final GSNR (0.1 nm): 18.90 dB diff --git a/tests/invocation/openroadm-v5-Stockholm-Gothenburg b/tests/invocation/openroadm-v5-Stockholm-Gothenburg index 6547bd75..fa6d6e8d 100644 --- a/tests/invocation/openroadm-v5-Stockholm-Gothenburg +++ b/tests/invocation/openroadm-v5-Stockholm-Gothenburg @@ -15,6 +15,7 @@ Transceiver trx_Stockholm CD (ps/nm): 0.00 PMD (ps): 0.00 PDL (dB): 0.00 + Latency (ms): 0.00 Roadm roadm_Stockholm effective loss (dB): 22.00 reference pch out (dBm): -20.00 @@ -255,6 +256,7 @@ Transceiver trx_Gothenburg CD (ps/nm): 8350.42 PMD (ps): 7.99 PDL (dB): 3.74 + Latency (ms): 2.45 Transmission result for input power = 2.00 dBm: Final GSNR (0.1 nm): 19.27 dB diff --git a/tests/invocation/spectrum1_transmission_main_example b/tests/invocation/spectrum1_transmission_main_example index 7c2fef03..f5a066bb 100644 --- a/tests/invocation/spectrum1_transmission_main_example +++ b/tests/invocation/spectrum1_transmission_main_example @@ -16,6 +16,7 @@ Transceiver trx Lannion_CAS CD (ps/nm): 0.00 PMD (ps): 0.00 PDL (dB): 0.00 + Latency (ms): 0.00 Roadm roadm Lannion_CAS effective loss (dB): 20.00 reference pch out (dBm): -20.00 @@ -91,6 +92,7 @@ Transceiver trx Lorient_KMA CD (ps/nm): 2171.00 PMD (ps): 0.46 PDL (dB): 0.00 + Latency (ms): 0.64 Transmission result for input power = 0.00 dBm: Final GSNR (0.1 nm): 23.61 dB diff --git a/tests/invocation/spectrum2_transmission_main_example b/tests/invocation/spectrum2_transmission_main_example index dd405bcf..80b1c7da 100644 --- a/tests/invocation/spectrum2_transmission_main_example +++ b/tests/invocation/spectrum2_transmission_main_example @@ -16,6 +16,7 @@ Transceiver trx Lannion_CAS CD (ps/nm): 0.00 PMD (ps): 0.00 PDL (dB): 0.00 + Latency (ms): 0.00 Roadm roadm Lannion_CAS effective loss (dB): 20.00 reference pch out (dBm): -20.00 @@ -91,6 +92,7 @@ Transceiver trx Lorient_KMA CD (ps/nm): 2171.00 PMD (ps): 0.46 PDL (dB): 0.00 + Latency (ms): 0.64 Transmission result for input power = 0.00 dBm: Final GSNR (0.1 nm): 23.72 dB diff --git a/tests/invocation/transmission_main_example b/tests/invocation/transmission_main_example index 4387f1b7..81e7e35d 100644 --- a/tests/invocation/transmission_main_example +++ b/tests/invocation/transmission_main_example @@ -15,6 +15,7 @@ Transceiver Site_A CD (ps/nm): 0.00 PMD (ps): 0.00 PDL (dB): 0.00 + Latency (ms): 0.00 Fiber Span1 type_variety: SSMF length (km): 80.00 @@ -46,6 +47,7 @@ Transceiver Site_B CD (ps/nm): 1336.00 PMD (ps): 0.36 PDL (dB): 0.00 + Latency (ms): 0.39 Transmission result for input power = 0.00 dBm: Final GSNR (0.1 nm): 31.17 dB diff --git a/tests/invocation/transmission_main_example__raman b/tests/invocation/transmission_main_example__raman index 40522bd2..7b7b8145 100644 --- a/tests/invocation/transmission_main_example__raman +++ b/tests/invocation/transmission_main_example__raman @@ -15,6 +15,7 @@ Transceiver Site_A CD (ps/nm): 0.00 PMD (ps): 0.00 PDL (dB): 0.00 + Latency (ms): 0.00 RamanFiber Span1 type_variety: SSMF length (km): 80.00 @@ -48,6 +49,7 @@ Transceiver Site_B CD (ps/nm): 1336.00 PMD (ps): 0.36 PDL (dB): 0.00 + Latency (ms): 0.39 Transmission result for input power = 0.00 dBm: Final GSNR (0.1 nm): 31.44 dB diff --git a/tests/invocation/transmission_main_example_long b/tests/invocation/transmission_main_example_long index f7e6069e..0d2352e8 100644 --- a/tests/invocation/transmission_main_example_long +++ b/tests/invocation/transmission_main_example_long @@ -15,6 +15,7 @@ Transceiver Site_A CD (ps/nm): 0.00 PMD (ps): 0.00 PDL (dB): 0.00 + Latency (ms): 0.00 Roadm roadm Site A effective loss (dB): 20.00 reference pch out (dBm): -20.00 @@ -444,6 +445,7 @@ Transceiver Site_B CD (ps/nm): 20040.00 PMD (ps): 1.39 PDL (dB): 0.00 + Latency (ms): 5.88 Transmission result for input power = 0.00 dBm: Final GSNR (0.1 nm): 17.85 dB diff --git a/tests/invocation/transmission_saturated b/tests/invocation/transmission_saturated index 6560a20b..f453790e 100644 --- a/tests/invocation/transmission_saturated +++ b/tests/invocation/transmission_saturated @@ -251,6 +251,7 @@ Transceiver trx Lannion_CAS CD (ps/nm): 0.00 PMD (ps): 0.00 PDL (dB): 0.00 + Latency (ms): 0.00 Roadm roadm Lannion_CAS effective loss (dB): 23.00 reference pch out (dBm): -20.00 @@ -326,6 +327,7 @@ Transceiver trx Lorient_KMA CD (ps/nm): 2171.00 PMD (ps): 0.46 PDL (dB): 0.00 + Latency (ms): 0.64 Transmission result for input power = 3.00 dBm: Final GSNR (0.1 nm): 23.94 dB