Skip to main content
Ctrl+K

Comnumpy

  • Getting Started
  • Examples
  • Documentation
  • GitHub
  • Getting Started
  • Examples
  • Documentation
  • GitHub

Section Navigation

Contents:

  • AWGN Chain Tutorial
  • OFDM Chain Tutorial
  • PAPR in OFDM Communication
  • MIMO Chain Tutorial
  • Optical Fiber Link Simulation Tutorial
  • Examples
  • Optical Fiber Link Simulation Tutorial

Optical Fiber Link Simulation Tutorial#

This tutorial demonstrates how to simulate a nonlinear optical fiber communication system using the comnumpy library. You will learn how to:

  • Build a simulation chain with QAM modulation, pulse shaping, and fiber propagation.

  • Visualize received signals before and after linear and nonlinear equalization.

  • Apply digital back-propagation (DBP) for nonlinear compensation.

  • Compute Symbol Error Rate (SER) to quantify performance.

This tutorial is ideal for engineers or students interested in optical communications and nonlinear fiber effects.

Prerequisites#

Ensure you have the following Python libraries installed:

  • numpy

  • matplotlib

  • comnumpy

Note that the simulation can be computationally intensive and may take some time to run depending on your machine.

Simulation Setup#

1. Import Libraries#

First, import necessary Python libraries and components from comnumpy:

import numpy as np
import matplotlib.pyplot as plt
from comnumpy.core import Sequential, Recorder
from comnumpy.core.generators import SymbolGenerator
from comnumpy.core.mappers import SymbolMapper
from comnumpy.core.utils import get_alphabet, hard_projector
from comnumpy.core.processors import Upsampler, Downsampler, Amplifier
from comnumpy.core.filters import SRRCFilter, BWFilter
from comnumpy.core.metrics import compute_ser
from comnumpy.optical.links import FiberLink
from comnumpy.optical.dbp import DBP

img_dir = "../../docs/examples/img/"

2. Define System Parameters#

Set key parameters such as modulation order, oversampling factors, fiber link properties, and noise figure:

M = 16
modulation = "QAM"
alphabet = get_alphabet(modulation, M)
N_s = 2**9  # number of symbols
oversampling_sim = 6  # number of samples/symbol for simulated channel
oversampling_dsp = 2  # number of samples/symbol for dsp processing
NF_dB = 5  # noise figure in dB
rolloff = 0.1
StPS = 500
StPS_DBP = 100
R_s = 10.7*(10**9)  # baud rate
L_span = 80  # in km
N_span = 25
dBm = -3

# compute simulation parameter
N = N_s*oversampling_sim   # signal length in number of samples
fs = R_s*oversampling_sim
oversampling_ratio = int(oversampling_sim/oversampling_dsp)
fs2 = R_s*oversampling_dsp
Po = (1e-3) * (10**(0.1*dBm))
amp = np.sqrt(Po)

3. Create Communication Chain#

Build a processing chain consisting of symbol generation, mapping, pulse shaping (SRRC filter), amplification, fiber propagation via FiberLink, and final filtering/downsampling:

# create a communication chain
chain = Sequential([
                SymbolGenerator(M),
                Recorder(name="data_tx"),
                SymbolMapper(alphabet),
                Recorder(name="signal_tx"),
                Upsampler(oversampling_sim, scale=np.sqrt(oversampling_sim)),
                SRRCFilter(rolloff, oversampling_sim, method="fft"),
                Amplifier(amp),
                FiberLink(N_spans=N_span, L_span=L_span, StPS=StPS, NF_dB=NF_dB, fs=fs, name="link"),
                BWFilter(1/oversampling_sim),
                Downsampler(oversampling_ratio)
                ])

This simulates the full transmission over an optical fiber with nonlinear effects and noise.

The optical channel (Fiber_Link) is modeled as a concatenation of multiple spans of standard single-mode fiber (SMF), denoted by N_span. Each span has a fixed length L_span (typically 80 km) and is followed by an Erbium-Doped Fiber Amplifier (EDFA) which compensates for the fiber loss and introduces amplified spontaneous emission noise (characterized by the noise figure NF_dB).

Within each fiber span, the signal undergoes chromatic dispersion as well as nonlinear Kerr effects (simulated using Split Step Fourier Method), which distort the signal amplitude and phase. This complex interplay between dispersion and nonlinearity significantly affects system performance and motivates the use of advanced digital signal processing techniques.

4. Run Simulation and Extract Signals#

Execute the chain to obtain the received signal. Extract transmitted data and signal for analysis. Then, plot the received constellation diagram to inspect signal quality at the receiver input.

# perform simulation
y_rx = chain(N)

# extract signal
s_tx = chain["data_tx"].get_data()
x_tx = chain["signal_tx"].get_data()

# plot signal
plt.figure()
plt.plot(np.real(y_rx), np.imag(y_rx), ".")
plt.title(f"Received Signal (oversampling={oversampling_dsp}, {dBm}dBm)")
plt.savefig(f"{img_dir}/one_shot_NLI_fig1.png")

5. Visualize Received Signal#

../_images/one_shot_NLI_fig1.png

6. Perform Linear and Nonlinear Compensation#

Apply two compensation strategies using Digital Back-Propagation (DBP):

  • Linear equalization only : compensates for linear impairments such as chromatic dispersion and attenuation.

  • Nonlinear equalization with Digital Back Propagation (DBP): performs full Digital Back-Propagation (DBP), which mitigates nonlinear fiber effects by numerically inverting the propagation through the fiber using a reversed Split-Step Fourier Method..

Note that after compensation, the received signal may experience a residual phase rotation. Therefore, for each compensation technique, phase correction is applied before computing the Symbol Error Rate (SER).


# perform compensation
for num_compensator in range(2):

    if num_compensator == 0:
        use_only_linear = True
        technique_name = "linear equalization"
    else:
        use_only_linear = False
        technique_name = "nonlinear equalization"

    receiver = Sequential([
                    DBP(N_span, L_span, StPS_DBP, step_type="linear", use_only_linear=use_only_linear, fs=fs/oversampling_ratio, name="dbp"),
                    SRRCFilter(rolloff, oversampling_dsp, method="fft", scale=1/np.sqrt(oversampling_dsp)),
                    Downsampler(oversampling_dsp),
                    Amplifier(1/amp),
                    Recorder(name="signal_rx_compensated")
            ])

    # apply conventional chain
    x_rx = receiver(y_rx)

    # perform phase correction and evaluate metric
    theta_est = np.angle(np.sum(np.conj(x_rx)*x_tx))
    x_rx_phase_compensated = np.exp(1j*theta_est) * x_rx
    s_rx = hard_projector(x_rx_phase_compensated, alphabet)
    ser = compute_ser(s_tx, s_rx)

    # plot signal
    plt.figure()
    plt.plot(np.real(x_rx), np.imag(x_rx), ".", label="before phase correction")
    plt.plot(np.real(x_rx_phase_compensated), np.imag(x_rx_phase_compensated), ".", label="after phase correction")
    plt.legend()
    plt.title(f"{technique_name} (SER={ser:.3f})")
../_images/one_shot_NLI_fig2.png ../_images/one_shot_NLI_fig3.png

Conclusion#

This tutorial showed how to:

  • Model an optical fiber communication system with nonlinear effects.

  • Use SRRC filtering and oversampling to shape signals.

  • Simulate fiber propagation with noise and nonlinearities.

  • Apply linear and nonlinear compensation techniques (DBP).

  • Quantify performance improvements via SER metrics.

The simulation provides valuable insights into advanced fiber-optic communication design and compensation methods using the comnumpy framework.

previous

MIMO Chain Tutorial

next

Documentation

On this page
  • Prerequisites
  • Simulation Setup
  • 1. Import Libraries
  • 2. Define System Parameters
  • 3. Create Communication Chain
  • 4. Run Simulation and Extract Signals
  • 5. Visualize Received Signal
  • 6. Perform Linear and Nonlinear Compensation
  • Conclusion

This Page

  • Show Source

© Copyright 2025, V. Choqueuse.

Created using Sphinx 8.2.3.

Built with the PyData Sphinx Theme 0.16.1.