Skip to main content
Ctrl+K

comnum

  • Getting started
  • Tutorials
  • User guide
  • Gallery of classical results
  • Why the results can be trusted
  • Maturity
    • Comparisons with other libraries
    • Why comnum
    • Benchmarks against other libraries
    • Classical performance
    • API reference
  • GitHub
  • Getting started
  • Tutorials
  • User guide
  • Gallery of classical results
  • Why the results can be trusted
  • Maturity
  • Comparisons with other libraries
  • Why comnum
  • Benchmarks against other libraries
  • Classical performance
  • API reference
  • GitHub

Section Navigation

  • Foundations
    • Constellations and Gray labels
    • Bit error rate of M-QAM over AWGN
    • M-PSK over AWGN with the Python runner
    • BPSK over flat Rayleigh fading
    • Information rates of QAM
  • Coding and shaping
    • Channel coding: from convolutional codes to the finite-length limit
    • Hu, Eleftheriou & Arnold 2005, Fig. 5: a regular PEG code of length 504
    • 5G NR channel codes: LDPC and polar
    • Probabilistic shaping: the rate gain and probabilistic amplitude shaping
  • Waveforms
    • PAPR of OFDM: the CCDF and its closed forms
    • PAPR reduction techniques
    • OFDM with impairments: imperfect channel estimates and nonlinear amplifiers
    • Proakis & Salehi 2008, Sec. 3.3-2: MSK has the error rate of BPSK
    • Thompson et al. 2008, Fig. 2: the CE-OFDM phase demodulator
    • CE-OFDM receivers, spectrum and bandwidth
    • The LoRa modulation: error rates, spectrum and interference
    • Filtered multicarrier and OTFS
  • MIMO
    • MIMO detection: linear, successive cancellation and maximum likelihood
    • Transmit diversity: Alamouti and space-time block codes
    • Alamouti 1998, Fig. 4: transmit diversity against MRRC
    • Ergodic capacity of MIMO channels
    • Large MIMO: message passing (LAMA and OAMP)
    • Biguesh & Gershman 2006, Fig. 4: LS, scaled LS, relaxed MMSE and LMMSE
  • Optical
    • Chromatic dispersion and its compensation
    • Nonlinear fibre propagation and digital back-propagation
    • Häger & Pfister 2021, Fig. 5: linear equalisation and back-propagation
    • WDM nonlinearity: the GN model and digital back-propagation
    • Raman amplification: pumps, gain flattening and the hybrid link
    • Mach–Zehnder and IQ modulators
    • Optical wireless: an LED-lit room and a turbulent free-space link
  • Hardware impairments
    • Power amplifiers and digital predistortion
    • DAC and ADC: quantisation, clipping and jitter
  • Receiver DSP
    • Nyquist pulse shaping and the eye diagram
    • OFDM over multipath: channel estimation
    • OFDM synchronisation and MIMO-OFDM
    • Blind receiver: modulation recognition, SNR and symbol rate
  • Metrics and analysis
    • Analysing a link: variants, probes and signals
  • Systems and standards
    • DVB-S2: MODCODs, constellations and frame error rates
    • 5G NR: numerology, synchronisation block and reference signals
    • DVB-S: the error rate after the Viterbi decoder against Table 3
    • DVB-T: the frame and the error rate after the Viterbi decoder against Annex A
    • CCSDS: the codes of telemetry against the normal approximation
    • 5G NR PDSCH: TS 38.101-4 test 1-2 against the RAN4 alignment
  • Simulation and specifications
    • A coherent receiver as a chain of blocks
    • Wireless links as chains: diversity, OFDM channel estimation, coded modulation
    • Recorded signals: SigMF in, blind receiver out
    • Coverage of the confidence intervals of an error rate
  • Gallery of classical results
  • Optical
  • Raman amplification: pumps, gain flattening and the hybrid link

Note

Go to the end to download the full example code.

Raman amplification: pumps, gain flattening and the hybrid link#

The pumps of a distributed Raman amplifier transfer their power to the signals about 13 THz below them, all along the span. comnum.raman_profile() solves the coupled power equations of stimulated Raman scattering (Bromage 2004) for the signals and any number of co- and counter-propagating pumps, with the measured gain spectrum of standard single-mode fibre.

Power profiles. One channel at −10 dBm over 100 km. Without pump the power decays by 0.2 dB/km. A co-propagating pump amplifies the beginning of the span, where the signal is strong, and a counter-propagating pump amplifies the end, where it is weak. The counter-pump therefore keeps the signal away from both the high powers of the nonlinear regime and the low powers of the noise.

Gain flattening. A single pump gives the shape of the Raman gain: 6 dB of ripple over the C band. Five counter-pumps from 1420 to 1490 nm, whose gain spectra overlap, give 15 dB of on-off gain within 0.8 dB over 40 channels. The pumps also amplify each other: the shortest ones feed the longest ones. Without pump, inter-channel stimulated Raman scattering alone tilts a wide WDM spectrum: the high-frequency channels feed the low-frequency ones.

The hybrid link. Five channels over three spans of 100 km. An EDFA with an ideal gain-flattening filter restores every channel after each span, with or without a counter-pump of 500 mW at 1450 nm. The pump compensates 18.5 of the 20 dB of loss of the span, so the noise falls by 7.7 dB. It also raises the power at the end of the span, so the nonlinear interference grows and the optimal launch power drops by 3.2 dB. The optimal SNR still gains 4.4 dB. Gaussian symbols simulated by the Manakov equation with the power profiles of the spans follow the GN model with the same profiles (specs/raman_wdm.yaml, within 0.21 dB). tests/oracle/test_gnpy_oracle.py checks the profiles, the noise and the nonlinear interference against GNPy.

import matplotlib.pyplot as plt
import numpy as np
from _gallery_utils import SPECS

import comnum
from comnum.plot import BACKGROUND, BLUE, GREY, INK, RUST

The power of one channel along a span of 100 km, by direction of pumping.

span = comnum.FiberParams(span_km=100)
cases = [
    ("no pump", [], GREY, ":"),
    (
        "co-pump 500 mW",
        [{"wavelength_nm": 1450, "power_mw": 500, "direction": "co"}],
        RUST,
        "-",
    ),
    (
        "counter-pump 500 mW",
        [{"wavelength_nm": 1450, "power_mw": 500, "direction": "counter"}],
        BLUE,
        "-",
    ),
    (
        "250 mW each way",
        [
            {"wavelength_nm": 1450, "power_mw": 250, "direction": "co"},
            {"wavelength_nm": 1450, "power_mw": 250, "direction": "counter"},
        ],
        INK,
        "--",
    ),
]
fig, ax = plt.subplots()
for label, pumps, color, style in cases:
    p = comnum.raman_profile(span, [0.0], -10.0, {"pumps": pumps})
    ax.plot(p["z_km"], p["power_dbm"][0], style, color=color, label=label)
ax.set(xlabel="distance (km)", ylabel="channel power (dBm)", xlim=(0, 100),
       title="One channel at −10 dBm over 100 km of standard fibre")  # fmt: skip
ax.legend(loc="lower left")
fig.tight_layout()
One channel at −10 dBm over 100 km of standard fibre

On-off gain over the C band: one pump against five, and the ISRS tilt without pump.

c_band = comnum.FiberParams(span_km=100, fc_hz=193.5e12)
rel = list(np.arange(-20, 20) * 100e9 + 50e9)
wavelengths = 299_792_458.0 / (193.5e12 + np.array(rel)) * 1e9
one = [{"wavelength_nm": 1450, "power_mw": 500, "direction": "counter"}]
five = [
    {"wavelength_nm": w, "power_mw": p, "direction": "counter"}
    for w, p in [(1420, 209), (1434, 188), (1448, 85), (1462, 90), (1490, 114)]
]
fig, ax = plt.subplots()
for label, pumps, color in [("one pump, 1450 nm, 500 mW", one, RUST),
                            ("five pumps, 1420 to 1490 nm, 686 mW", five, BLUE)]:  # fmt: skip
    p = comnum.raman_profile(c_band, rel, -3.0, {"pumps": pumps, "step_km": 0.5})
    ax.plot(wavelengths, p["on_off_gain_db"], marker="o", markersize=4, markeredgecolor=BACKGROUND,
            color=color, label=f"{label}: {np.ptp(p['on_off_gain_db']):.1f} dB ripple")  # fmt: skip
p = comnum.raman_profile(c_band, rel, 3.0, {"pumps": []})
ax.plot(wavelengths, p["on_off_gain_db"], color=GREY, linestyle=":",
        label="no pump, ISRS of 40 × 3 dBm")  # fmt: skip
ax.set(xlabel="wavelength (nm)", ylabel="on-off gain (dB)", ylim=(-2, 20),
       title="Counter-pumped 100 km span, 40 channels at 100 GHz")  # fmt: skip
ax.legend(loc="center")
fig.tight_layout()
Counter-pumped 100 km span, 40 channels at 100 GHz

The SNR of the centre channel of the hybrid link against the launch power, simulated and GN model with the Raman power profiles.

link = comnum.Chain.from_spec(SPECS / "raman_wdm.yaml")
powers = [-10.0, -6.0, -2.0, 2.0]
res = link.run(grid={"pump_mw": [0.0, 500.0], "power_dbm": powers}, stop={"max_trials": 4})
fine = np.linspace(-12, 4, 17)
freqs = comnum.wdm_grid(5, 50e9)
fiber = comnum.FiberParams(
    n_spans=3, span_km=100, alpha_db_km=0.2, d_ps_nm_km=16, gamma_w_km=1.3, nf_db=5
)
fig, ax = plt.subplots()
for pump, color, marker, label in [(0.0, GREY, "s", "EDFA only"),
                                   (500.0, BLUE, "o", "counter-pump 500 mW + EDFA")]:  # fmt: skip
    raman = {"pumps": [{"wavelength_nm": 1450, "power_mw": pump, "direction": "counter"}]}
    gn = [comnum.gn_model(fiber, freqs, p, 32e9, rolloff=0.1, raman=raman)["snr_db"] for p in fine]
    ax.plot(fine, gn, color=color, label=f"{label}, GN model")
    _, snr = res.series("power_dbm", "snr_db", pump_mw=pump)
    ax.plot(powers, snr, marker=marker, linestyle="none", color=color, markeredgecolor=BACKGROUND,
            label=f"{label}, Manakov")  # fmt: skip
ax.set(xlabel="launch power per channel (dBm)", ylabel="SNR (dB)", ylim=(10, 30),
       title="5 × 32 GBd DP, 3 × 100 km, Gaussian symbols")  # fmt: skip
ax.legend(loc="lower right", fontsize="small")
fig.tight_layout()
5 × 32 GBd DP, 3 × 100 km, Gaussian symbols

Total running time of the script: (1 minutes 9.635 seconds)

Download Jupyter notebook: plot_05_raman_amplification.ipynb

Download Python source code: plot_05_raman_amplification.py

Download zipped: plot_05_raman_amplification.zip

Gallery generated by Sphinx-Gallery

previous

WDM nonlinearity: the GN model and digital back-propagation

next

Mach–Zehnder and IQ modulators

Show Source

© Copyright 2022-2026, Vincent Choqueuse.

Created using Sphinx 9.1.1.

Built with the PyData Sphinx Theme 0.24.0.