Source code for ofiber.noise

# pylint: disable=invalid-name
# pylint: disable=no-member

"""
Useful routines for noise in optical communications.

See <https://ofiber.readthedocs.io> for usage examples.

Based on chapter 13 of A. Ghatak, K. Thyagarajan, An Introduction to
Fiber Optics, Cambridge University Press, 1998
"""

import scipy.special
import numpy as np

__all__ = ('shot_noise',
           'thermal_noise',
           'NEP',
           'best_APD_gain',
           'BER_at_SNR',
           'SNR_at_BER',
           'thermal_min_power',
           'quantum_min_power')


[docs] def shot_noise(I0, Idark, bandwidth, M=1, x=0): """ Return the noise current associated with shot/poisson noise. Args: I0: current (A) Idark: dark current (A) M: APD Gain factor (--) x: excess noise (0.3 for Si, 0.7 for InGaAs, 1.0 for Ge APDs) Returns: shot_noise (A) """ q = 1.602e-19 # Coulomb return np.sqrt(2 * q * (I0 / M + Idark) * bandwidth * M**(2 + x))
[docs] def thermal_noise(T, Rload, bandwidth): """ Return the noise current associated with thermal processes. Args: T: temperature (Kelvin) Rload: resistance (Ohms) BW: bandwidth (Hz) Returns: thermal_noise (A) """ k = 1.38e-23 # J/K return np.sqrt(4 * k * T * bandwidth / Rload)
[docs] def NEP(Responsivity, Rload, Idark, T): """ Return noise equivalent power. Args: responsivity: photodetector response (A/W) Rload: resistance (Ohms) Idark: dark current (A) T: temperature (Kelvin) Returns: power (W/sqrt(Hz)) """ q = 1.602e-19 # Coulomb k = 1.38e-23 # J/K return 1 / Responsivity * np.sqrt(4 * k * T / Rload + 2 * q * Idark)
[docs] def best_APD_gain(I0, Rload, Idark, x, T): """ Return best gain for an avalanche photodiode. Args: I0: current (A) Rload: load resistance (Ohms) Idark: dark current (A) x: excess noise (0.3 for Si, 0.7 for InGaAs, 1.0 for Ge APDs) T: Temperature Returns: optimal gain (--) """ q = 1.602e-19 # Coulomb k = 1.38e-23 # J/K return (4 * k * T / (x * q * Rload * (I0 + Idark)))**(1 / (x + 2))
[docs] def BER_at_SNR(snr): """ Return the bit error rate for a particular signal-to-noise ratio. Args: snr: signal to noise ratio (--) Returns: bit error rate (--) """ return 0.5 * scipy.special.erfc(np.sqrt(snr / 8))
[docs] def SNR_at_BER(ber): """ Return the necessary signal-to-noise ratio to achieve specified BER. Args: ber: bit error rate (--) Returns: signal to noise ratio (--) """ return 8 * scipy.special.erfcinv(2 * ber)**2
[docs] def thermal_min_power(bitrate, responsivity, capacitance, T, snr): """ Return the minimum optical power needed to achieve a signal-to-noise of 1. The assumption is that thermal noise dominates. Args: bitrate: bits per second (Hz) responsivity: photodetector response (A/W) capacitance: photodetector capacitance (Farads) T: temperature (Kelvin) snr: signal to noise ratio (--) Returns: optical power (W) """ k = 1.38e-23 # J/K val = 2 * np.pi * k * T * capacitance * snr return bitrate / responsivity * np.sqrt(val)
[docs] def quantum_min_power(bitrate, ber, lambda0): """ Return the minimum optical power needed to achieve a bit error rate. Args: bitrate: bits per second (Hz) ber: bit error rate (--) lambda0: wavelength in vacuum (m) Returns: optical power (W) """ h = 6.626e-34 # J*s c = 2.998e8 # m/s nu = c / lambda0 # Hz Np = -np.log(2 * ber) return h * nu * Np * bitrate