Utilities functions
Use this module for utility functions.
>>> import opticomlib.utils as ut
Functions
|
Converts an integer to its binary representation. |
|
Converts a string to array of numbers. |
|
Get the average time of execution of a line of code. |
|
Start a timer. |
|
Stop a timer. |
|
Calculates the logarithm in base 10 of the input x and multiplies it by 10. |
|
Calculates dBm from Watts. |
|
Calculates the number value from a dB value. |
|
Calculates the power value in Watts from a dBm value. |
|
Gaussian function. |
|
Q-function. |
|
Calculate the unwrapped phase of a frequency response. |
|
Calculate the group delay of a frequency response. |
|
Calculate the dispersion of a frequency response. |
|
Plot the Bode plot of a given transfer function H (magnitude, phase and group delay). |
|
Raised cosine spectrum function. |
|
Unit of measure classifier. |
|
Normalize an array by dividing each element by the maximum value in the array. |
|
Find the nearest value in an array. |
|
This function calculates the bit error rate (BER) for an OPTICAL RECEIVER, based on a PIN photodetector, from the average input power. |
|
Calculate the ASE noise power [Watts]. |
|
Calculate the average voltages of the ON and OFF slots [Voltages]. |
|
Calculate the theoretical noise variances for OFF and ON slots, include sig-ase, ase-ase, thermal and shot noises [V^2]. |
|
Calculate the optimum threshold for binary modulation formats. |
|
Estimation of the shortest interval containing |
- opticomlib.utils.dec2bin(num: int, digits: int = 8)[source]
Converts an integer to its binary representation.
- Parameters:
num (int) – Integer to convert.
digits (int, default: 8) – Number of bits of the binary representation.
- Returns:
Binary representation of
num
of lengthdigits
.- Return type:
- Raises:
ValueError – If
num
is too large to be represented withdigits
bits.
Example
>>> dec2bin(5, 4) array([0, 1, 0, 1], dtype=uint8)
- opticomlib.utils.str2array(string: str, dtype: bool | int | float | complex | None = None)[source]
Converts a string to array of numbers. Use comma (
,
) or whitespace (``) as element separators and semicolon (
;``) as row separator. Also,i
orj
can be used to represent the imaginary unit.- Parameters:
string (
str
) – String to convert.dtype (
type
, optional) – Data type of the output array. Ifdtype
is not given, the data type is determined from the input string. Ifdtype
is given, the data output is cast to the given type. Allowed values arebool
,int
,float
andcomplex
.
- Returns:
arr – Numeric array.
- Return type:
np.ndarray
- Raises:
ValueError – If the string contains invalid characters.
Example
For binary numbers, string must contain only 0 and 1. Only in this case, sequence don’t need to be separated by commas or spaces although it is allowed.
>>> str2array('101') array([ True, False, True]) >>> str2array('1 0 1; 0 1 0') array([[ True, False, True], [False, True, False]])
Special case >>> str2array(‘1 0 1 10’) array([True, False, True, True, False]) >>> str2array(‘1 0 1 10’, dtype=int) array([ 1, 0, 1, 10]) >>> str2array(‘1 0 1 10’, dtype=float) array([ 1., 0., 1., 10.]) >>> str2array(‘1 0 1 10’, dtype=complex) array([ 1.+0.j, 0.+0.j, 1.+0.j, 10.+0.j])
For integer and float numbers >>> str2array(‘1 2 3 4’) array([1, 2, 3, 4]) >>> str2array(‘1.1 2.2 3.3 4.4’) array([1.1, 2.2, 3.3, 4.4])
For complex numbers >>> str2array(‘1+2j 3-4i’) array([1.+2.j, 3.-4.j])
- opticomlib.utils.get_time(line_of_code: str, n: int)[source]
Get the average time of execution of a line of code.
- Parameters:
line_of_code (str) – Line of code to execute.
n (int) – Number of iterations.
- Returns:
time – Average time of execution, in seconds.
- Return type:
float
Example
>>> get_time('for i in range(1000): pass', 1000) 1.1955300000010993e-05
- opticomlib.utils.tic()[source]
Start a timer. Create a global variable with the current time. Then you can use toc() to get the elapsed time.
Example
>>> tic() # wait some time >>> toc() 2.687533378601074
- opticomlib.utils.toc()[source]
Stop a timer. Get the elapsed time since the last call to tic().
- Returns:
time – Elapsed time, in seconds.
- Return type:
float
Example
>>> tic() # wait some time >>> toc() 2.687533378601074
- opticomlib.utils.db(x)[source]
Calculates the logarithm in base 10 of the input x and multiplies it by 10.
\[\text{db} = 10\log_{10}{x}\]- Parameters:
x (Number or Array_Like) – Input value (
x>=0
).- Returns:
out – dB value.
- Return type:
float
ornp.ndarray
- Raises:
TypeError – If
x
is not a number, list, tuple or ndarray.ValueError – If
x
orany(x) < 0
.
Example
>>> db(1) 0.0 >>> db([1,2,3,4]) array([0. , 3.01029996, 4.77121255, 6.02059991])
- opticomlib.utils.dbm(x)[source]
Calculates dBm from Watts.
\[\text{dbm} = 10\log_{10}{x}+30\]- Parameters:
x (Number or Array_Like) – Input value (
x>=0
).- Returns:
out – dBm value. If
x
is a number, then the output is afloat
. Ifx
is an array_like, then the output is annp.ndarray
.- Return type:
float
ornp.ndarray
- Raises:
TypeError – If
x
is not a number, list, tuple or ndarray.ValueError – If
x
orany(x) < 0
.
Example
>>> dbm(1) 30.0 >>> dbm([1,2,3,4]) array([30. , 33.01029996, 34.77121255, 36.02059991])
- opticomlib.utils.idb(x)[source]
Calculates the number value from a dB value.
\[y = 10^{\frac{x}{10}}\]- Parameters:
x (Number or Array_Like) – Input value.
- Returns:
out – Number value. If
x
is a number, then the output is afloat
. Ifx
is an array_like, then the output is annp.ndarray
.- Return type:
float
ornp.ndarray
Example
>>> idb(3) 1.9952623149688795 >>> idb([0,3,6,9]) array([1. , 1.99526231, 3.98107171, 7.94328235])
- opticomlib.utils.idbm(x)[source]
Calculates the power value in Watts from a dBm value.
\[y = 10^{(\frac{x}{10}-3)}\]- Parameters:
x (Number or Array_Like) – Input value.
- Returns:
out – Power value in Watts. If
x
is a number, then the output is afloat
. Ifx
is an array_like, then the output is annp.ndarray
.- Return type:
float
ornp.ndarray
Example
>>> idbm(0) 0.001 >>> idbm([0,3,6,9]) array([0.001 , 0.00199526, 0.00398107, 0.00794328])
- opticomlib.utils.gaus(x, mu: float = None, std: float = None)[source]
Gaussian function.
\[\text{gaus}(x) = \frac{1}{\sigma\sqrt{2\pi}}e^{-\frac{(x-\mu)^2}{2\sigma^2}}\]- Parameters:
x (Number or Array_Like) – Input value.
mu (
float
, default: 0) – Mean.std (
float
, default: 1) – Standard deviation.
- Returns:
out – Gaussian function value. If
x
is a number, then the output is afloat
. Ifx
is an array_like, then the output is annp.ndarray
.- Return type:
float
ornp.ndarray
Examples
>>> gaus(0, 0, 1) 0.3989422804014327 >>> gaus([0,1,2,3], 0, 1) array([0.39894228, 0.24197072, 0.05399097, 0.00443185])
from opticomlib import gaus import matplotlib.pyplot as plt import numpy as np x = np.linspace(-5, 5, 1000) y = gaus(x, 0, 1) plt.figure(figsize=(8, 5)) plt.plot(x, y, 'r', lw=2) plt.ylabel('y') plt.xlabel('x') plt.grid(alpha=0.3) plt.show()
(
Source code
,png
,hires.png
,pdf
)
- opticomlib.utils.Q(x)[source]
Q-function.
\[Q(x) = \frac{1}{2}\text{erfc}\left( \frac{x}{\sqrt{2}} \right)\]- Parameters:
x (Numper or Array_Like) – Input value.
- Returns:
out – Q(x) values. If
x
is a number, then the output is afloat
. Ifx
is an array_like, then the output is annp.ndarray
.- Return type:
float
ornp.ndarray
Examples
>>> Q(0) 0.5 >>> Q([0,1,2,3]) array([0.5 , 0.15865525, 0.02275013, 0.0013499 ])
from opticomlib import Q import matplotlib.pyplot as plt import numpy as np x = np.linspace(-5, 5, 1000) plt.figure(figsize=(8, 5)) plt.plot(x, Q(x), 'r', lw=3, label='Q(x)') plt.plot(x, Q(-x), 'b', lw=3, label='Q(-x)') plt.ylabel('y') plt.xlabel('x') plt.legend() plt.grid() plt.show()
(
Source code
,png
,hires.png
,pdf
)
- opticomlib.utils.phase(H: ndarray)[source]
Calculate the unwrapped phase of a frequency response.
- Parameters:
H (
np.ndarray
) – Frequency response of a system.- Returns:
phase – Unwrapped phase in radians.
- Return type:
np.ndarray
Examples
from opticomlib import phase import matplotlib.pyplot as plt import numpy as np t = np.linspace(-5, 5, 1000) y = np.exp(1j*t**2) phi = phase(y) plt.figure(figsize=(8, 5)) plt.plot(t, phi, 'r', lw=2) plt.ylabel('phase [rad]') plt.xlabel('t') plt.grid(alpha=0.3) plt.show()
(
Source code
,png
,hires.png
,pdf
)
- opticomlib.utils.tau_g(H: ndarray, fs: float)[source]
Calculate the group delay of a frequency response.
- Parameters:
H (
np.ndarray
) – Frequency response of a system.fs (
float
) – Sampling frequency of the system.
- Returns:
tau – Group delay of the system, in [ps].
- Return type:
np.ndarray
Examples
from opticomlib import tau_g import matplotlib.pyplot as plt import numpy as np t = np.linspace(-5, 5, 1000) y = np.exp(1j*t**2) phi = tau_g(y, 1e2) plt.figure(figsize=(8, 5)) plt.plot(t[:-1], phi, 'r', lw=2) plt.ylabel(r'$\tau_g$ [ps]') plt.xlabel('t') plt.grid(alpha=0.3) plt.show()
(
Source code
,png
,hires.png
,pdf
)
- opticomlib.utils.dispersion(H: ndarray, fs: float, f0: float)[source]
Calculate the dispersion of a frequency response.
- Parameters:
H (
np.ndarray
) – Frequency response of a system.fs (
float
) – Sampling frequency of the system.f0 (
float
) – Center frequency of the system.
- Returns:
D – Cumulative dispersion of the system, in [ps/nm].
- Return type:
np.ndarray
- opticomlib.utils.bode(H: ndarray, fs: float, f0: float = None, xaxis: Literal['f', 'w', 'lambda'] = 'f', disp: bool = False, yscale: Literal['linear', 'db'] = 'linear', ret: bool = False, retAxes: bool = False, show_: bool = True, style: Literal['dark', 'light'] = 'dark', xlim: tuple = None)[source]
Plot the Bode plot of a given transfer function H (magnitude, phase and group delay).
- Parameters:
H (
np.ndarray
) – The transfer function.fs (
float
) – The sampling frequency.f0 (
float
, default: None) – The center frequency. If not None, dispersion are also plotted.xaxis (
str
, default: ‘f’) – The x-axis (frequency, angular velocity, wavelength).disp (
bool
, default: False) – Whether to plot the dispersion.ret (
bool
, default: False) – Whether to return the plotted data.show (
bool
, default: True) – Whether to display the plot.style (
str
, default: ‘dark’) – The plot style.
- Returns:
(f, H, phase, tau_g) – A tuple containing the frequency, magnitude, phase, and group delay if
ret=True
.- Return type:
np.ndarray
- Raises:
ValueError – If style is not “dark” or “light”.
Example
>>> from opticomlib import bode >>> H, phase, tau_g = bode(H, fs, ret=True, show_=False)
- opticomlib.utils.rcos(x, alpha, T)[source]
Raised cosine spectrum function.
- Parameters:
x (Number or Array_Like) – Input values.
alpha (
float
) – Roll-off factor.T (
float
) – Symbol period.
- Returns:
Raised cosine function.
- Return type:
np.ndarray
Example
https://en.wikipedia.org/wiki/Raised-cosine_filter
from opticomlib import rcos import matplotlib.pyplot as plt import numpy as np T = 1 x = np.linspace(-1.5/T, 1.5/T, 1000) plt.figure(figsize=(8, 5)) for alpha in [0, 0.25, 0.5, 1]: plt.plot(x, rcos(x, alpha, T), label=r'$\alpha$ = {}'.format(alpha)) plt.ylabel('y') plt.xlabel('x') plt.legend() plt.grid(alpha=0.3) plt.show()
(
Source code
,png
,hires.png
,pdf
)
- opticomlib.utils.si(x, unit: Literal['m', 's'] = 's', k: int = 1)[source]
Unit of measure classifier.
- Parameters:
x (int | float) – Number to classify.
unit (str, default: 's') – Unit of measure. Valid options are {‘s’, ‘m’, ‘Hz’, ‘rad’, ‘bit’, ‘byte’, ‘W’, ‘V’, ‘A’, ‘F’, ‘H’, ‘Ohm’}.
k (int, default: 1) – Precision of the output.
- Returns:
String with number and unit.
- Return type:
str
Example
>>> si(0.002, 's') '2.0 ms' >>> si(1e9, 'Hz') '1.0 GHz'
- opticomlib.utils.norm(x)[source]
Normalize an array by dividing each element by the maximum value in the array.
- Parameters:
x (Array_Like) – Input array to be normalized.
- Returns:
out – Normalized array.
- Return type:
np.ndarray
- Raises:
ValueError – If
x
is not an array_like.
- opticomlib.utils.nearest(x, a)[source]
Find the nearest value in an array.
- Parameters:
x (Array_Like) – Input array.
a (Number) – Value to find.
- Returns:
out – Nearest value in the array.
- Return type:
Number
- Raises:
ValueError – If
x
is not an array_like. Ifa
is not a number.
- opticomlib.utils.p_ase(amplify=True, wavelength=1.55e-06, G=None, NF=None, BW_opt=None)[source]
Calculate the ASE noise power [Watts].
- Parameters:
amplify (bool, default: True) – If use an EDFA or not at the receiver (before PIN).
wavelength (float, default: 1550e-9) – Wavelength of the signal.
G (float) – Gain of EDFA, in [dB]. Only used if amplify=True. This parameter is mandatory.
NF (float) – Noise Figure of EDFA, in [dB]. Only used if amplify=True. Mandatory.
BW_opt (float) – Bandwidth of optical filter that is placed after the EDFA, in [Hz]. Only used if amplify=True. Mandatory.
- Returns:
p_ase – ASE optical noise power, in [W].
- Return type:
float
- opticomlib.utils.average_voltages(P_avg, modulation: Literal['ook', 'ppm'], M=None, ER=inf, amplify=True, wavelength=1.55e-06, G=None, NF=None, BW_opt=None, r=1.0, R_L=50)[source]
Calculate the average voltages of the ON and OFF slots [Voltages].
- Parameters:
P_avg (float) – Average Received input optical Power (in [dBm]).
modulation (Literal['ook', 'ppm']) – Kind of modulation format {‘ook’, ‘ppm’}, more modulations in future…
M (int) – Order of M-ary PPM (a power of 2). Only needed if modulation=’ppm’.
ER (float, default: np.inf) – Extinction Ratio of the input optical signal, in [dB].
amplify (bool, default: True) – If use an EDFA or not at the receiver (before PIN).
wavelength (float, default: 1550e-9) – Wavelength of the signal.
G (float) – Gain of EDFA, in [dB]. Only used if amplify=True. This parameter is mandatory.
NF (float) – Noise Figure of EDFA, in [dB]. Only used if amplify=True. Mandatory.
BW_opt (float) – Bandwidth of optical filter that is placed after the EDFA, in [Hz]. Only used if amplify=True. Mandatory.
r (float, default: 1.0) – Responsivity of photo-detector.
R_L (float, default: 50) – Load resistance of photo-detector, in [Ω].
- Returns:
mu (np.ndarray) – Average voltage of ON and OFF slots. mu[0] is the OFF slot and mu[1] is the ON slot.
mu_ASE (float) – ASE voltage offset.
- opticomlib.utils.noise_variances(P_avg, modulation: Literal['ook', 'ppm'], M=None, ER=inf, amplify=True, wavelength=1.55e-06, G=None, NF=None, BW_opt=None, r=1.0, BW_el=5000000000.0, R_L=50, T=300, NF_el=0)[source]
Calculate the theoretical noise variances for OFF and ON slots, include sig-ase, ase-ase, thermal and shot noises [V^2]. If
amplify=False
only thermal and shot are calculated.- Parameters:
P_avg (float) – Average Received input optical Power (in [dBm]).
modulation (Literal['ook', 'ppm']) – Kind of modulation format {‘ook’, ‘ppm’}, more modulations in future…
M (int) – Order of M-ary PPM (a power of 2). Only needed if modulation=’ppm’.
ER (float) – Extinction Ratio of the input optical signal, in [dB].
amplify (bool) – If use an EDFA or not at the receiver (before PIN). Default: False.
wavelength (float) – Central frequency of communication, in [Hz]. Only used if amplify=True. Default: 1550 nm.
G (float) – Gain of EDFA, in [dB]. Only used if amplify=True. This parameter is mandatory.
NF (float) – Noise Figure of EDFA, in [dB]. Only used if amplify=True. Mandatory.
BW_opt (float) – Bandwidth of optical filter that is placed after the EDFA, in [Hz]. Only used if amplify=True. Mandatory.
r (float) – Responsivity of photo-detector. Default: 1.0 [A/W]
BW_el (float) – Bandwidth of photo-detector or electrical filter, in [Hz]. Default: 5e9 [Hz].
R_L (float) – Load resistance of photo-detector, in [Ω]. Default: 50 [Ω].
T (float) – Temperature of photo-detector, in [K]. Default: 300 [K].
NF_el (float) – Equivalent Noise Figure of electric circuit, in [dB]. Default: 0 [dB]
- opticomlib.utils.optimum_threshold(mu0, mu1, S0, S1, modulation: Literal['ook', 'ppm'], M=None)[source]
Calculate the optimum threshold for binary modulation formats.
- Parameters:
mu0 (float) – Average voltage of OFF slot.
mu1 (float) – Average voltage of ON slot.
S0 (float) – Noise variance of OFF slot.
S1 (float) – Noise variance of ON slot.
modulation (str) – Modulation format
M (int) – PPM order
- Returns:
threshold – Optimum threshold value.
- Return type:
float
- opticomlib.utils.theory_BER(P_avg, modulation: Literal['ook', 'ppm'], M=None, decision=None, threshold=None, ER=inf, amplify=False, f0=193414500000000.0, G=None, NF=None, BW_opt=None, r=1.0, BW_el=5000000000.0, R_L=50, T=300, NF_el=0)[source]
This function calculates the bit error rate (BER) for an OPTICAL RECEIVER, based on a PIN photodetector, from the average input power. It also allows consider the effects of an EDFA amplifier in the results.
If
amplify==False
, thermal and shot noise of PIN will be consider in BER calculation. Ifamplify==True
, signal-ase and ase-ase beating noises generated by the EDFA are consider too.In addition, parameter
NF_el != 0
(electrical noise figure) can be used to represent another sources of noise after detection, like electrical amplifiers, etc.- Parameters:
P_avg (float) – Average Received input optical Power (in [dBm]).
modulation (Literal['ook', 'ppm']) – Kind of modulation format {‘ook’, ‘ppm’}, more modulations in future…
M (int) – Order of M-ary PPM (a power of 2). Only needed if modulation=’ppm’.
decision (Literal['hard', 'soft']) – Kind of PPM decision. ‘hard’ decision use the optimum threshold to separate ON and OFF slots. ‘soft’ decision use the Maximum a Posteriori (MAP) and it outperform ‘hard’ decision. Only needed if modulation=’ppm’.
threshold (float) – Threshold for decision. Only needed if (modulation=’ook’) or (modulation=’ppm and decision=’hard’). Value must be in (0, 1), without include edges. By default optimum threshold is used.
ER (float) – Extinction Ratio of the input optical signal, in [dB].
amplify (bool) – If use an EDFA or not at the receiver (before PIN). Default: False.
f0 (float) – Central frequency of communication, in [Hz]. Only used if amplify=True. Default: 193.4 THz corresponding to 1550 nm.
G (float) – Gain of EDFA, in [dB]. Only used if amplify=True. This parameter is mandatory.
NF (float) – Noise Figure of EDFA, in [dB]. Only used if amplify=True. Mandatory.
BW_opt (float) – Bandwidth of optical filter that is placed after the EDFA, in [Hz]. Only used if amplify=True. Mandatory.
r (float) – Responsivity of photo-detector. Default: 1.0 [A/W]
BW_el (float) – Bandwidth of photo-detector or electrical filter, in [Hz]. Default: 5e9 [Hz].
R_L (float) – Load resistance of photo-detector, in [Ω]. Default: 50 [Ω].
T (float) – Temperature of photo-detector, in [K]. Default: 300 [K].
NF_el (float) – Equivalent Noise Figure of electric circuit, in [dB]. Default: 0 [dB]
- Returns:
BER – Theoretical Bit Error rate of the system specified.
- Return type:
float
Notes
The bandwidths are used only for the determination of the noise contribution to the BER value, i.e. the signal distortion due to these bandwidth is not taken into account. Therefore, the bandwidths
BW_el
andBW_opt
are not considered to affect the transmitted signal.Example
from opticomlib import theory_BER import matplotlib.pyplot as plt import numpy as np x = np.linspace(-40, -20, 1000) # Average input optical power [dB] plt.figure(figsize=(8, 6)) plt.semilogy(x, theory_BER(P_avg=x, modulation='ook'), label='OOK') plt.semilogy(x, theory_BER(P_avg=x, modulation='ppm', M=4, decision='soft'), label='4-PPM (soft)') plt.semilogy(x, theory_BER(P_avg=x, modulation='ppm', M=4, decision='hard'), label='4-PPM (hard)') plt.xlabel(r'$P_{avg}$') plt.ylabel('BER') plt.legend() plt.grid(alpha=0.3) plt.ylim(1e-9,) plt.show()
(
Source code
,png
,hires.png
,pdf
)
- opticomlib.utils.shortest_int(data: ndarray, percent: float = 50) tuple[float, float] [source]
Estimation of the shortest interval containing
percent
of the samples in ‘data’.- Parameters:
data (ndarray) – Array of data.
- Returns:
The shortest interval containing 50% of the samples in ‘data’.
- Return type:
tuple[float, float]