Skip to main content

Open-source simulation of fiber optic communication systems with Python

OptiCommPy is a Python framework to simulate fiber optic communication systems, from the bits at the transmitter to the performance metrics at the receiver. It brings together physical models of optical and optoelectronic devices, linear and nonlinear fiber propagation, optical amplification, receiver digital signal processing (DSP), forward error correction (FEC) and performance metrics, so that complete IM-DD and coherent optical links can be built and studied in a few lines of code.

It is designed for students learning optical communications, researchers prototyping and benchmarking new DSP algorithms or system concepts, and engineers who need a transparent, scriptable simulation environment.

PyPI PyPI - Downloads Documentation Status DOI DOIPyPI Downloads

Contents

Why OptiCommPy?

  • End-to-end simulation: transmitter, fiber channel, amplifiers, receiver front-end, DSP, FEC and metrics in a single package, with a consistent API.
  • Physically meaningful models: devices and channels are described by their physical parameters (Vπ, extinction ratio, responsivity, noise figure, fiber loss, dispersion, nonlinearity, laser linewidth, ...).
  • Fast: performance-critical routines are compiled with Numba, and the most demanding ones (split-step fiber propagation, digital backpropagation, blind phase search) also run on NVIDIA GPUs via CuPy.
  • Transparent and hackable: plain NumPy/SciPy code that is easy to read, modify and extend, ideal for teaching and for prototyping new algorithms.
  • Peer reviewed and tested: published in the Journal of Open Source Software, with an automated test suite.

Features

Area What is included
Modulation and sources M-PAM, OOK, square M-QAM, M-PSK and APSK constellations with Gray mapping; random bits, PRBS, CAZAC (Zadoff-Chu) sequences; probabilistic constellation shaping (Maxwell-Boltzmann); NRZ, RC and RRC pulse shaping; OFDM modulation and demodulation
Transmitters WDM transmitter with multiple channels and polarization modes, optical PAM transmitter, laser model with phase noise and relative intensity noise (RIN), DAC with quantization and ENOB
Optical and optoelectronic devices Phase modulator, Mach-Zehnder modulator (MZM), IQ modulator, polarization beam splitter, 90° optical hybrid, variable optical attenuator, PIN photodiode (shot and thermal noise, bandwidth limitation), balanced photodetector, single- and dual-polarization coherent receivers with IQ imbalance and skew, ADC with jitter, quantization and ENOB
Fiber channel Linear fiber channel (loss and chromatic dispersion), nonlinear Schrödinger equation (NLSE) and Manakov models solved with the split-step Fourier method with adaptive step size, first-order perturbation models of nonlinear interference, AWGN channel
Optical amplification Simple EDFA model (gain and ASE noise) and an advanced EDFA model solving the erbium rate and propagation equations
Receiver DSP Resampling, matched filtering, Gardner clock recovery, chromatic dispersion compensation, N×N MIMO adaptive equalization (CMA, RDE, NLMS, DD-LMS, DA-RDE, RLS, DD-RLS), Manakov digital backpropagation, frequency offset estimation, carrier phase recovery (blind phase search, DD-PLL, Viterbi & Viterbi), sequence synchronization
IM-DD DSP Feedforward (FFE), decision feedback (DFE) and Volterra equalizers, maximum likelihood sequence estimation (MLSE)
Forward error correction LDPC encoding and decoding (sum-product and min-sum belief propagation, DVB-S2 codes, ALIST files) and Hamming codes
Performance metrics BER, SER, SNR, Q-factor, EVM, mutual information (MI), generalized mutual information (GMI) and normalized GMI (NGMI), log-likelihood ratios, theoretical BER/MI/GMI curves, OSNR evolution in multi-span links
Visualization Density constellation plots, eye diagrams, power spectral density, decision boundaries, animated constellations

Installation

OptiCommPy requires Python 3.10 or newer. Install the latest release from PyPI:

pip install OptiCommPy

or install the development version from GitHub:

git clone https://github.com/edsonportosilva/OptiCommPy.git
cd OptiCommPy
pip install .

GPU support (optional): to run the GPU implementations, install CuPy for your CUDA version, for example:

pip install cupy-cuda12x
Dependencies
  • numpy>=1.24.4
  • scipy>=1.13.0
  • matplotlib>=3.7.0
  • numba>=0.54.0
  • tqdm>=4.64.1
  • simple-pid>=1.0.1
  • mpl-scatter-density>=0.8
  • prettytable>=3.16.0
  • cupy-cuda12x>=13.1.0 (optional, for GPU processing)

Quick start

Simulate a 10 Gb/s NRZ-OOK transmission over 100 km of optical fiber with a direct-detection receiver, and measure its bit error rate:

import numpy as np
from optic.comm.sources import bitSource
from optic.comm.modulation import modulateGray
from optic.comm.metrics import bert
from optic.dsp.core import firFilter, pulseShape, upsample, anorm
from optic.models.devices import mzm, photodiode
from optic.models.channels import linearFiberChannel
from optic.utils import parameters, dBm2W

# 10 Gb/s NRZ-OOK over 100 km of fiber with direct detection
SpS, Rs = 16, 10e9  # samples per symbol, symbol rate
Fs = SpS * Rs       # sampling frequency

paramBits = parameters()
paramBits.nBits, paramBits.seed = 100_000, 123

paramPulse = parameters()
paramPulse.pulseType, paramPulse.SpS = "nrz", SpS

paramMZM = parameters()
paramMZM.Vpi, paramMZM.Vb = 2, -1

paramCh = parameters()
paramCh.L, paramCh.alpha, paramCh.D = 100, 0.2, 16  # km, dB/km, ps/nm/km
paramCh.Fc, paramCh.Fs = 193.1e12, Fs

paramPD = parameters()
paramPD.ideal, paramPD.B, paramPD.Fs, paramPD.seed = False, Rs, Fs, 456

# transmitter: bits -> 2-PAM symbols -> NRZ pulses -> MZM
bitsTx = bitSource(paramBits)
symbTx = modulateGray(bitsTx, 2, "pam")
sigTx = anorm(firFilter(pulseShape(paramPulse), upsample(symbTx, SpS)))
sigTxo = mzm(np.sqrt(dBm2W(3)), sigTx, paramMZM)  # 3 dBm laser

# fiber channel (loss + chromatic dispersion) and noisy photodiode
sigRx = photodiode(linearFiberChannel(sigTxo, paramCh), paramPD)

# BER and Q-factor from the samples at the center of each symbol
BER, Q = bert(sigRx[0::SpS])
print(f"BER = {BER:.2e}, Q-factor = {Q:.2f}")

The getting started notebook walks through this example step by step and extends it to BER versus received power curves.

Examples

The examples folder contains Jupyter notebooks covering the main features of the package. Most of them can be run directly in the browser with Google Colab, through the Open in Colab button at their top.

Topic Notebooks
First steps Getting started
IM-DD systems Basic OOK transmission, PAM transmission, Equalizers for IM-DD, Photodiode model
Coherent WDM systems WDM transmission, WDM transmission with amplification, Nonlinearity compensation with DBP, Perturbation models
Optical amplification Basic EDFA, OOK transmission with advanced EDFA model
DSP Core DSP functions, Clock recovery, Carrier phase recovery, Sequence synchronization
Communication theory Modulation, Sources, OFDM, FEC, Metrics
GPU processing GPU benchmark

Documentation

The full documentation, with the API reference of every module and rendered example notebooks, is available at opticommpy.readthedocs.io.

To build the documentation locally, install OptiCommPy with the documentation dependencies and run Sphinx from the root of the repository:

pip install .[docs]
sphinx-build -b html docs/source docs/build/html

Contributing

Contributions are welcome, from bug reports and documentation improvements to new models and algorithms.

  1. Open an issue to report a bug or to discuss the feature you want to implement.
  2. Fork the repository and create a new branch from the latest version of main.
  3. Follow the conventions adopted in the code (naming, NumPy-style docstrings, etc.).
  4. Add tests for your changes and make sure the test suite passes (pip install pytest, then pytest tests).
  5. Include an example of usage for new features, ideally as a notebook in the examples folder.
  6. Open a pull request.

For suggestions or questions about OptiCommPy, get in touch by e-mail (edsonporto88@gmail.com).

If OptiCommPy is useful for your work, consider supporting its development:

Sponsor

Citing OptiCommPy

If you use OptiCommPy in your research, please cite the paper:

Edson Porto da Silva, Adolfo Fernandes Herbster. "OptiCommPy: Open-source Simulation of Fiber Optic Communications with Python", Journal of Open Source Software, 9(98), 6600, (2024). https://doi.org/10.21105/joss.06600

@article{daSilva2024OptiCommPy,
  author  = {da Silva, Edson Porto and Herbster, Adolfo Fernandes},
  title   = {{OptiCommPy}: Open-source Simulation of Fiber Optic Communications with {Python}},
  journal = {Journal of Open Source Software},
  year    = {2024},
  volume  = {9},
  number  = {98},
  pages   = {6600},
  doi     = {10.21105/joss.06600}
}

License

OptiCommPy is distributed under the GNU General Public License v3.0.

Metadata

Release files for OptiCommPy 0.11.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for OptiCommPy 0.11.0
File Size Uploaded
opticommpy-0.11.0.tar.gz 77.2 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for OptiCommPy 0.11.0
File Interpreter ABI Platform
opticommpy-0.11.0-py3-none-any.whl Python 3 none any Details

Total release size: 77.4 MB

Release files / opticommpy-0.11.0.tar.gz

Download URL opticommpy-0.11.0.tar.gz
Size 77.2 MB
Tags Source
SHA-256 checksum
How to use checksums
21e727825f35e719f608297d03e00a0e5b79ebc98ae783b012be17bd3435e55c
BLAKE2b-256 checksum
How to use checksums
0e3c9d76ca51b320f26c93c2c7a117efe57ff049694a727c837a68fb48185257
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release files / opticommpy-0.11.0-py3-none-any.whl

Download URL opticommpy-0.11.0-py3-none-any.whl
Size 161.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
40d78f3a088873d9dfb3761472a564431cb119fc85be30a5709af699807b15be
BLAKE2b-256 checksum
How to use checksums
68f3d7c56c697ae8316e051165cfdd70e2ae42aebdcb50584d5d2e205383a6f6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.11.0 This release

2 release files

0.10.0

1 release file

0.9.0

1 release file

0.7.0

2 release files

0.6.0

1 release file

0.5.0

1 release file

0.4.0

1 release file

0.3.0

1 release file

0.2.0

1 release file

0.1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page