comnum.blocks#
The blocks of the registry of declarative links as classes, for comnum.Chain.
One class per entry of comnum.spec_blocks(), named in CamelCase (awgn_ebn0 →
AwgnEbn0), with the parameters of the block as keyword arguments and its
documentation as docstring. A parameter given as comnum.var("name") takes the value
of the grid variable name; a parameter left out takes the default of the block (the
specification lists the parameters given only). needs and gives are the facts
of the frame a block reads and adds (see comnum.spec_check_link()).
This file is generated by tools/gen_blocks.py from the registry of the extension:
do not edit it (python tools/gen_blocks.py regenerates it, --check verifies it);
at import, a warning names the blocks that differ from the extension.
Example
>>> from comnum import blocks as B
>>> B.AwgnEbn0(ebn0_db=10).spec()
{'type': 'awgn_ebn0', 'ebn0_db': 10}
>>> B.AwgnEbn0.needs, B.AwgnEbn0.gives
(('samples', 'constellation'), ('noise',))
Classes
|
Adaptive FIR equaliser, output at 1 sample per symbol; the n × n butterfly over the polarisations or antennas. |
|
Analogue-to-digital converter: front-end bandwidth, clock jitter, ENOB noise and uniform quantisation with clipping. |
|
Add white Gaussian noise for an SNR in a bandwidth. |
|
Add white Gaussian noise for an E_b/N_0 (matched-filter definition). |
|
Blind phase search, unwrapped with a period of π/2, and correction. |
|
A measured recording as the source: one segment per trial, the reference sequence not yet aligned. |
|
Chromatic-dispersion compensation in the frequency domain. |
|
Clustered delay line of 3GPP TR 38.901 between uniform linear arrays (one tap per cluster, random ray phases and coupling); records the taps for a genie-aided receiver. |
|
CE-OFDM receiver back to the symbols: the arctangent phase demodulator, the linear and enhanced receivers of Ahmed and Zeidler (2015) or GAMP (López Morales et al. 2022); records ser_theory and ber_theory when esn0_db is given. |
|
Constant-envelope OFDM modulator (Thompson et al. 2008): K symbols per block on the bins 1..K of an N = 2J(K + 1) DFT, exp(j2πh x). |
|
Carrier frequency offset. |
|
Blind modulation classification at one sample per symbol, by fourth-order cumulants or by likelihood; records class (the index of the decided candidate), correct (1 if it is the transmitted alphabet) and snr_m2m4_db (M2M4 for the decided alphabet). |
|
Sampling clock offset: the samples at m (1 + ζ) T (cubic interpolation). |
|
CPM detector (maximum-likelihood sequence detection over the phase trellis, or one-symbol differential detection) back to the symbols. |
|
Continuous-phase modulator of the symbols of a real constellation (CPFSK, MSK, GMSK, raised-cosine CPM): a unit-envelope signal at sps samples per symbol. |
|
Digital-to-analogue converter: uniform quantisation with clipping and output bandwidth. |
|
Digital back-propagation by the split-step method. |
|
Decision-directed phase-locked loop. |
|
Reduce the samples per symbol. |
|
Bit LLRs of the received symbols, with the noise variance of every symbol (from the receiver, or the noise block). |
|
Save the samples at this point of the link for the first trials (by index) of every condition, as SigMF recordings <dir>/<campaign>/<condition>/<label>_<trial>.sigmf-meta and -data (one per stream, suffixed _s<stream> after the first). |
|
DVB-S2 receiver of frame-aligned PLFRAMEs: descrambling, demapping, decoding. |
|
DVB-S2 transmitter: BBFRAME, BCH and LDPC, bit interleaving, mapping, PL framing. |
|
Erbium-doped fibre amplifier with ASE. |
|
Deinterleave and decode the LLRs into the information bits. |
|
Draw the information bits of the coded blocks and encode them (the first block of a coded link). |
|
Linear fibre (loss and dispersion, OptiCommPy linearFiberChannel). |
|
Linear channel with complex taps. |
|
Frequency-offset estimation by the M-th power and correction; records foe_hz. |
|
Delay and rotation on known symbols, output aligned on the transmitted symbols; records delay and quality. |
|
Gardner clock recovery at 2 samples per symbol. |
|
Dual-polarisation nonlinear propagation over the link (Manakov equation, split step with the phase at the middle of the step or OptiCommPy's trapezoidal one), EDFAs with ASE. |
|
Dual-polarisation digital back-propagation of the link (Manakov equation, coefficients negated). |
|
Map the coded bits on a constellation (Gray labels, the last symbol padded with random bits). |
|
Filter with a receive pulse at the current samples per symbol. |
|
Detect a single-carrier link over flat fading with the known channel; output the symbols and their noise variances. |
|
Spread the symbols over n_tx antennas: spatial multiplexing (power 1/n_tx per antenna) or Alamouti's code. |
|
Declare the receiver's posterior: the noise variance of the aligned samples; records sigma2. |
|
Scale the samples to a mean power. |
|
Demodulate the OFDM grids, estimate the channel and detect every data resource element; output the symbols and their noise variances. |
|
Map every antenna's symbols on resource grids with pilots and OFDM-modulate them (power K/(LN) per sample). |
|
PAS receiver: bit LLRs with the amplitude priors, LDPC decoding, dematching (the parameters of pas_encode). |
|
Probabilistic amplitude shaping: CCDM-shaped amplitudes, an LDPC code whose parity bits are the signs, square QAM (the first block of a link). |
|
Wiener phase noise. |
|
Random rotation of the polarisations and polarisation-mode dispersion of a dual-polarisation signal, a new realisation every trial. |
|
Measure metrics at this point of the link; reported as <label>.<metric> (label: probe by default). |
|
Upsample and filter with a transmit pulse, then normalise to unit power. |
|
Flat fading y = H x on every antenna; records the channel for a genie-aided receiver. |
|
Align the periodic reference of a capture on the received symbols (circular correlation); records offset and quality. |
|
Band-limited resampling of the block (FFT) to a number of samples per symbol. |
|
Receiver IQ imbalance [Re y; Im y] = T [Re x; Im x]. |
|
Draw the bits and symbols of a block (Gray labels of OptiCommPy). |
|
Split-step Fourier propagation over the link, one polarisation. |
|
Tapped-delay-line multipath fading with Clarke/Jakes Doppler; records the taps for a genie-aided receiver. |
|
Transmitter IQ imbalance y = x + β x*. |
|
Viterbi–Viterbi phase estimation and correction. |
|
Bring the channel under test to baseband and keep its band (ideal low-pass by resampling). |
|
WDM transmitter: the channel under test and independently modulated neighbours on the grid of OptiCommPy's simpleWDMTx. |
- class comnum.blocks.AdaptiveEqualizer(*, algorithm: str | list | Var = 'cma', n_taps: int | Var = 15, mu: float | list | Var = 0.001, passes: int | Var = 1, update_rule: str | Var | None = None, kikuchi: int | Var | None = None)#
Adaptive FIR equaliser, output at 1 sample per symbol; the n × n butterfly over the polarisations or antennas.
Needs: samples, constellation. Gives: nothing.
- Parameters:
algorithm (str | list) – cma, rde, nlms, dd-lms, or a schedule [[algorithm, symbols], …]; default cma
n_taps (int) – taps; default 15
mu (float | list) – step size, or one per stage of the schedule (the last one holds for the following stages); default 1e-3
passes (int) – passes over the block; default 1
update_rule (str) – the update rule of every stage instead of that of its algorithm: sign for the sign-error update; one of lms, nlms, sign; default none
kikuchi (int) – 2 × 2: Kikuchi’s initialisation against the singularity, output 0 alone during this number of symbols, then output 1 as its unitary complement; records correlation and singular; default none
- gives = ()#
- needs = ('samples', 'constellation')#
- param_names = ('algorithm', 'n_taps', 'mu', 'passes', 'update_rule', 'kikuchi')#
- class comnum.blocks.Adc(*, bits: int | Var, full_scale: float | Var | None = None, loading: float | Var | None = None, enob: float | Var | None = None, jitter_s: float | Var = 0.0, bandwidth_hz: float | Var | None = None)#
Analogue-to-digital converter: front-end bandwidth, clock jitter, ENOB noise and uniform quantisation with clipping.
Needs: samples. Gives: nothing.
- Parameters:
bits (int) – resolution N (1 to 24) [bits]; required
full_scale (float) – full scale A of each dimension (levels ±(A - Δ/2), Δ = 2A/2^N); default loading × RMS
loading (float) – full scale in RMS values of one dimension of the samples (an automatic gain control); default optimal for a Gaussian input
enob (float) – effective number of bits (≤ bits); default bits
jitter_s (float) – RMS sampling-clock jitter [s]; default 0.0
bandwidth_hz (float) – 3 dB bandwidth of the front end (Gaussian) [Hz]; default unlimited
- gives = ()#
- needs = ('samples',)#
- param_names = ('bits', 'full_scale', 'loading', 'enob', 'jitter_s', 'bandwidth_hz')#
- class comnum.blocks.Awgn(*, snr_db: float | Var, reference: str | Var = 'signal', bandwidth_hz: float | Var | None = None)#
Add white Gaussian noise for an SNR in a bandwidth.
Needs: samples. Gives: noise.
- Parameters:
- gives = ('noise',)#
- needs = ('samples',)#
- param_names = ('snr_db', 'reference', 'bandwidth_hz')#
- class comnum.blocks.AwgnEbn0(*, ebn0_db: float | Var)#
Add white Gaussian noise for an E_b/N_0 (matched-filter definition).
Needs: samples, constellation. Gives: noise.
- Parameters:
ebn0_db (float) – E_b/N_0 [dB]; required
- gives = ('noise',)#
- needs = ('samples', 'constellation')#
- param_names = ('ebn0_db',)#
- class comnum.blocks.Bps(*, n: int | Var = 35, b: int | Var = 64)#
Blind phase search, unwrapped with a period of π/2, and correction.
Needs: samples, constellation. Gives: nothing.
- gives = ()#
- needs = ('samples', 'constellation')#
- param_names = ('n', 'b')#
- class comnum.blocks.Capture(*, file: str | Var, channel: int | Var = 0, datatype: str | Var | None = None, fs: float | Var | None = None, symbol_rate: float | Var, constellation: str | dict | Var = '16-QAM', reference: str | Var, segment: int | Var | None = None, offset: str | int | Var = 'random')#
A measured recording as the source: one segment per trial, the reference sequence not yet aligned.
Needs: nothing. Gives: bits, symbols, constellation, samples, capture.
- Parameters:
file (str) – SigMF (.sigmf-meta/.sigmf-data or a .sigmf archive), NPY (.npy) or raw samples, relative to the specification; required
channel (int) – the channel of a multi-channel SigMF recording; default 0
datatype (str) – data type of a raw file: cf32_le, ci16_le, cf64_le, ci8, cu8, …; default none
fs (float) – sampling rate; required when the file does not record it [Hz]; default from file
symbol_rate (float) – symbol rate [Bd]; required
constellation (str | dict) – the transmitted constellation; keys kind, m; default 16-QAM
reference (str) – one period of the transmitted symbols (.npy complex) or indices (.npy or text integers); required
segment (int) – samples per trial; default whole file
offset (str | int) – first sample of a segment: random (drawn per trial) or an integer; default random
- gives = ('bits', 'symbols', 'constellation', 'samples', 'capture')#
- needs = ()#
- param_names = ('file', 'channel', 'datatype', 'fs', 'symbol_rate', 'constellation', 'reference', 'segment', 'offset')#
- class comnum.blocks.Cdc(*, fiber: dict | Var | None = None, length_km: float | Var | None = None)#
Chromatic-dispersion compensation in the frequency domain.
Needs: samples. Gives: nothing.
- Parameters:
fiber (dict) – fibre parameters, merged over the
fiberof the specification (see FiberParams); itsramanmapping adds Raman pumps and ISRS; keys alpha_db_km, d_ps_nm_km, gamma_w_km, span_km, n_spans, fc_hz, nf_db, slope_ps_nm2_km, raman; default spec fiberlength_km (float) – compensated length [km]; default total
- gives = ()#
- needs = ('samples',)#
- param_names = ('fiber', 'length_km')#
- class comnum.blocks.Cdl(*, profile: str | Var = 'CDL-A', delay_spread_s: float | Var = 1e-07, n_rx: int | Var = 1, spacing_wavelengths: float | Var = 0.5, velocity_mps: float | Var = 0.0, fc_hz: float | Var = 3500000000.0)#
Clustered delay line of 3GPP TR 38.901 between uniform linear arrays (one tap per cluster, random ray phases and coupling); records the taps for a genie-aided receiver.
Needs: samples. Gives: csi.
- Parameters:
profile (str) – the profile of TR 38.901 Tables 7.7.1-1 to 7.7.1-5 (A, B, C: NLOS; D, E: LOS); one of CDL-A, CDL-B, CDL-C, CDL-D, CDL-E; default CDL-A
delay_spread_s (float) – desired RMS delay spread (TR 38.901 §7.7.3) [s]; default 100e-9
n_rx (int) – receive antennas, a vertical uniform linear array; default 1
spacing_wavelengths (float) – element spacing of both arrays [wavelengths]; default 0.5
velocity_mps (float) – speed of the receiver along the array axis; 0 for a channel constant over the trial [m/s]; default 0.0
fc_hz (float) – carrier frequency (the wavelength of the Doppler shifts) [Hz]; default 3.5e9
- gives = ('csi',)#
- needs = ('samples',)#
- param_names = ('profile', 'delay_spread_s', 'n_rx', 'spacing_wavelengths', 'velocity_mps', 'fc_hz')#
- class comnum.blocks.CeOfdmRx(*, n_subcarriers: int | Var = 64, oversampling: int | Var = 4, h: float | Var, n_cp: int | Var = 0, unwrap: str | Var | None = None, receiver: str | Var = 'arctangent', esn0_db: float | Var | None = None)#
CE-OFDM receiver back to the symbols: the arctangent phase demodulator, the linear and enhanced receivers of Ahmed and Zeidler (2015) or GAMP (López Morales et al. 2022); records ser_theory and ber_theory when esn0_db is given.
Needs: samples, constellation. Gives: nothing.
- Parameters:
n_subcarriers (int) – data subcarriers K (as the modulator); default 64
oversampling (int) – oversampling factor J (as the modulator); default 4
h (float) – modulation index (as the modulator); required
n_cp (int) – cyclic prefix (as the modulator) [samples]; default 0
unwrap (str) – none (principal phase) or stream (unwrapped along the stream, the phase unwrapper of the paper); one of none, stream; default none
receiver (str) – arctangent (phase demodulator), linear (Im r) or enhanced (Im r (2 - Re r)) of Ahmed and Zeidler 2015, or gamp (near-optimum message passing, needs esn0_db); one of arctangent, linear, enhanced, gamp; default arctangent
esn0_db (float) – E_s/N_0 of the channel per data symbol: records ser_theory and ber_theory (the linear regime for arctangent and gamp, where it is the optimum asymptotic rate of QPSK; Bussgang’s analysis for linear and enhanced), and sets the noise variance of gamp [dB]; default none
- gives = ()#
- needs = ('samples', 'constellation')#
- param_names = ('n_subcarriers', 'oversampling', 'h', 'n_cp', 'unwrap', 'receiver', 'esn0_db')#
- class comnum.blocks.CeOfdmTx(*, n_subcarriers: int | Var = 64, oversampling: int | Var = 4, h: float | Var, n_cp: int | Var = 0)#
Constant-envelope OFDM modulator (Thompson et al. 2008): K symbols per block on the bins 1..K of an N = 2J(K + 1) DFT, exp(j2πh x).
Needs: samples. Gives: nothing.
- Parameters:
- gives = ()#
- needs = ('samples',)#
- param_names = ('n_subcarriers', 'oversampling', 'h', 'n_cp')#
- class comnum.blocks.Cfo(*, offset_hz: float | Var | None = None, omega_rad: float | Var | None = None, centred: bool | Var = False)#
Carrier frequency offset.
Needs: samples. Gives: nothing.
- Parameters:
- gives = ()#
- needs = ('samples',)#
- param_names = ('offset_hz', 'omega_rad', 'centred')#
- class comnum.blocks.Classify(*, candidates: list | Var | None = None, method: str | Var = 'ml')#
Blind modulation classification at one sample per symbol, by fourth-order cumulants or by likelihood; records class (the index of the decided candidate), correct (1 if it is the transmitted alphabet) and snr_m2m4_db (M2M4 for the decided alphabet).
Needs: samples. Gives: nothing.
- Parameters:
candidates (list) – the candidate alphabets; default [BPSK, QPSK, 8-PSK, 16-QAM, 64-QAM]
method (str) – cumulants (Swami & Sadler 2000, normalised by the received power: for high SNR) or ml (likelihood, the scale and the noise estimated by M2M4 under every candidate); one of cumulants, ml; default ml
- gives = ()#
- needs = ('samples',)#
- param_names = ('candidates', 'method')#
- class comnum.blocks.ClockOffset(*, ppm: float | Var)#
Sampling clock offset: the samples at m (1 + ζ) T (cubic interpolation).
Needs: samples. Gives: nothing.
- Parameters:
ppm (float) – the relative offset ζ = (T’ - T)/T of the sampling period of the receiver, positive for a slower clock [ppm]; required
- gives = ()#
- needs = ('samples',)#
- param_names = ('ppm',)#
- class comnum.blocks.CpmRx(*, h: str | Var = '1/2', pulse: str | Var = 'rec', length: int | Var = 1, bt: float | Var = 0.3, sps: int | Var = 4, detector: str | Var = 'ml', rx_bt: float | Var | None = None, precode: bool | Var = False)#
CPM detector (maximum-likelihood sequence detection over the phase trellis, or one-symbol differential detection) back to the symbols.
Needs: samples, constellation. Gives: nothing.
- Parameters:
h (str) – as cpm_tx; default 1/2
pulse (str) – as cpm_tx; one of rec, rc, gmsk; default rec
length (int) – as cpm_tx; default 1
bt (float) – as cpm_tx; default 0.3
sps (int) – as cpm_tx; default 4
detector (str) – ml (Viterbi over the phase trellis, coherent) or differential (sign of the one-symbol phase increment, after a Gaussian low-pass of rx_bt); one of ml, differential; default ml
rx_bt (float) – bandwidth–time product of the receive low-pass of the differential detector (none: no filter); default none
precode (bool) – as cpm_tx (with the ml detector); default false
- gives = ()#
- needs = ('samples', 'constellation')#
- param_names = ('h', 'pulse', 'length', 'bt', 'sps', 'detector', 'rx_bt', 'precode')#
- class comnum.blocks.CpmTx(*, h: str | Var = '1/2', pulse: str | Var = 'rec', length: int | Var = 1, bt: float | Var = 0.3, sps: int | Var = 4, precode: bool | Var = False)#
Continuous-phase modulator of the symbols of a real constellation (CPFSK, MSK, GMSK, raised-cosine CPM): a unit-envelope signal at sps samples per symbol.
Needs: samples, constellation. Gives: nothing.
- Parameters:
h (str) – modulation index p/q, as a fraction (1/2 with a rectangular pulse of length 1 is MSK); default 1/2
pulse (str) – frequency pulse: rectangular (1REC is CPFSK), raised cosine, or Gaussian (GMSK, with bt); one of rec, rc, gmsk; default rec
length (int) – length L of the pulse in symbols; default 1
bt (float) – bandwidth–time product of the Gaussian pulse; default 0.3
sps (int) – samples per symbol; default 4
precode (bool) – MSK precoding (binary, h 1/2, rec, length 1): the bits are the boundary signs of the equivalent OQPSK signal, and cpm_rx reads them from the phase states of the ML path, with the BER of BPSK; default false
- gives = ()#
- needs = ('samples', 'constellation')#
- param_names = ('h', 'pulse', 'length', 'bt', 'sps', 'precode')#
- class comnum.blocks.Dac(*, bits: int | Var, full_scale: float | Var | None = None, loading: float | Var | None = None, bandwidth_hz: float | Var | None = None)#
Digital-to-analogue converter: uniform quantisation with clipping and output bandwidth.
Needs: samples. Gives: nothing.
- Parameters:
bits (int) – resolution N (1 to 24) [bits]; required
full_scale (float) – full scale A of each dimension; default loading × RMS
loading (float) – full scale in RMS values of one dimension of the samples; default optimal for a Gaussian input
bandwidth_hz (float) – 3 dB bandwidth of the output (Gaussian) [Hz]; default unlimited
- gives = ()#
- needs = ('samples',)#
- param_names = ('bits', 'full_scale', 'loading', 'bandwidth_hz')#
- class comnum.blocks.Dbp(*, fiber: dict | Var | None = None, steps_per_span: int | Var = 1, step_distribution: str | Var = 'uniform', step_factor: float | Var = 0.4, nonlinear_length: str | Var = 'effective', amplification: str | Var = 'edfa', nonlinear: bool | Var = True, nonlinear_scale: float | Var = 1.0)#
Digital back-propagation by the split-step method.
Needs: samples. Gives: nothing.
- Parameters:
fiber (dict) – fibre parameters, merged over the
fiberof the specification (see FiberParams); itsramanmapping adds Raman pumps and ISRS; keys alpha_db_km, d_ps_nm_km, gamma_w_km, span_km, n_spans, fc_hz, nf_db, slope_ps_nm2_km, raman; default spec fibersteps_per_span (int) – symmetric steps per span; default 1
step_distribution (str) – the steps of a span: equal, logarithmic (Bosco et al. 2000: every step carries the same integrated power of the forward span; better with 2 to 8 steps per span, worse with many), or modified logarithmic (Zhang et al. 2013: the attenuation times step_factor); one of uniform, logarithmic, modified_logarithmic; default uniform
step_factor (float) – the adjusting factor of the modified logarithmic steps (0.4 recommended by Zhang et al. 2013); default 0.4
nonlinear_length (str) – the nonlinear length of a coarse step: its effective length (the power integrated over the step) or the step itself (the midpoint rule of Häger & Pfister 2021); one of effective, step; default effective
amplification (str) – the amplification of the forward link; one of edfa, ideal, none; default edfa
nonlinear (bool) – false: linear back-propagation (dispersion compensation and loss); default true
nonlinear_scale (float) – ξ: multiplies the nonlinear phase (optimised DBP with few steps, Ip & Kahn 2008); default 1.0
- gives = ()#
- needs = ('samples',)#
- param_names = ('fiber', 'steps_per_span', 'step_distribution', 'step_factor', 'nonlinear_length', 'amplification', 'nonlinear', 'nonlinear_scale')#
- class comnum.blocks.Ddpll(*, kv: float | Var = 0.1, tau1_s: float | Var | None = None, tau2_s: float | Var | None = None)#
Decision-directed phase-locked loop.
Needs: samples, constellation. Gives: nothing.
- Parameters:
- gives = ()#
- needs = ('samples', 'constellation')#
- param_names = ('kv', 'tau1_s', 'tau2_s')#
- class comnum.blocks.Decimate(*, sps_out: int | Var = 1, method: str | Var = 'max_variance', offset: int | Var = 0)#
Reduce the samples per symbol.
Needs: samples. Gives: nothing.
- Parameters:
- gives = ()#
- needs = ('samples',)#
- param_names = ('sps_out', 'method', 'offset')#
- class comnum.blocks.Demap(*, max_log: bool | Var = False)#
Bit LLRs of the received symbols, with the noise variance of every symbol (from the receiver, or the noise block).
Needs: samples, symbols, constellation, noise. Gives: llr.
- Parameters:
max_log (bool) – max-log approximation instead of the exact LLRs; default false
- gives = ('llr',)#
- needs = ('samples', 'symbols', 'constellation', 'noise')#
- param_names = ('max_log',)#
- class comnum.blocks.Dump(*, dir: str | Var = 'results/signals', trials: int | Var = 1, datatype: str | Var = 'cf64')#
Save the samples at this point of the link for the first trials (by index) of every condition, as SigMF recordings <dir>/<campaign>/<condition>/<label>_<trial>.sigmf-meta and -data (one per stream, suffixed _s<stream> after the first).
Needs: samples. Gives: nothing.
- Parameters:
dir (str) – directory of the recordings (relative to the working directory); default results/signals
trials (int) – trials saved per condition: those of index 0 to trials - 1, whatever the order the threads run them in; default 1
datatype (str) – sample format of the SigMF data file; one of cf32, cf64, ci16; default cf64
- gives = ()#
- needs = ('samples',)#
- param_names = ('dir', 'trials', 'datatype')#
- class comnum.blocks.Dvbs2Rx(*, modulation: str | Var = 'QPSK', rate: str | Var = '1/2', frame: str | Var = 'normal', pilots: bool | Var = True, scrambling_code: int | Var = 0, frames: int | Var = 1, symbol_rate: float | Var = 1.0, iterations: int | Var = 50, max_log: bool | Var = False)#
DVB-S2 receiver of frame-aligned PLFRAMEs: descrambling, demapping, decoding.
Needs: samples, noise. Gives: decoded.
- Parameters:
modulation (str) – modulation; one of QPSK, 8PSK, 16APSK, 32APSK; default QPSK
rate (str) – code rate (Table 12); one of 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4, 4/5, 5/6, 8/9, 9/10; default 1/2
frame (str) – FECFRAME of 64 800 bits (normal) or 16 200 bits (short); one of normal, short, 64800, 16200; default normal
pilots (bool) – pilot blocks of 36 symbols every 16 slots; default true
scrambling_code (int) – number n of the Gold scrambling sequence; default 0
frames (int) – PLFRAMEs per trial (dvbs2_tx; the receiver reads it from the frame); default 1
symbol_rate (float) – symbol rate [Bd]; default 1.0
iterations (int) – LDPC iterations (sum-product, layered); default 50
max_log (bool) – max-log demapping instead of the exact LLRs; default false
- gives = ('decoded',)#
- needs = ('samples', 'noise')#
- param_names = ('modulation', 'rate', 'frame', 'pilots', 'scrambling_code', 'frames', 'symbol_rate', 'iterations', 'max_log')#
- class comnum.blocks.Dvbs2Tx(*, modulation: str | Var = 'QPSK', rate: str | Var = '1/2', frame: str | Var = 'normal', pilots: bool | Var = True, scrambling_code: int | Var = 0, frames: int | Var = 1, symbol_rate: float | Var = 1.0, iterations: int | Var = 50, max_log: bool | Var = False)#
DVB-S2 transmitter: BBFRAME, BCH and LDPC, bit interleaving, mapping, PL framing.
Needs: nothing. Gives: samples, payload.
- Parameters:
modulation (str) – modulation; one of QPSK, 8PSK, 16APSK, 32APSK; default QPSK
rate (str) – code rate (Table 12); one of 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4, 4/5, 5/6, 8/9, 9/10; default 1/2
frame (str) – FECFRAME of 64 800 bits (normal) or 16 200 bits (short); one of normal, short, 64800, 16200; default normal
pilots (bool) – pilot blocks of 36 symbols every 16 slots; default true
scrambling_code (int) – number n of the Gold scrambling sequence; default 0
frames (int) – PLFRAMEs per trial (dvbs2_tx; the receiver reads it from the frame); default 1
symbol_rate (float) – symbol rate [Bd]; default 1.0
iterations (int) – LDPC iterations (sum-product, layered); default 50
max_log (bool) – max-log demapping instead of the exact LLRs; default false
- gives = ('samples', 'payload')#
- needs = ()#
- param_names = ('modulation', 'rate', 'frame', 'pilots', 'scrambling_code', 'frames', 'symbol_rate', 'iterations', 'max_log')#
- class comnum.blocks.Edfa(*, gain_db: float | Var, nf_db: float | Var = 4.5, fc_hz: float | Var = 193100000000000.0)#
Erbium-doped fibre amplifier with ASE.
Needs: samples. Gives: nothing.
- Parameters:
- gives = ()#
- needs = ('samples',)#
- param_names = ('gain_db', 'nf_db', 'fc_hz')#
- class comnum.blocks.FecDecode(*, code: dict | Var, interleave: bool | Var = False, seed: int | Var = 0)#
Deinterleave and decode the LLRs into the information bits.
Needs: llr. Gives: decoded.
- Parameters:
- gives = ('decoded',)#
- needs = ('llr',)#
- param_names = ('code', 'interleave', 'seed')#
- class comnum.blocks.FecEncode(*, code: dict | Var, blocks: int | Var = 1, interleave: bool | Var = False, seed: int | Var = 0)#
Draw the information bits of the coded blocks and encode them (the first block of a coded link).
Needs: nothing. Gives: bits, payload.
- Parameters:
code (dict) – the code: {type: conv|rs|turbo|ldpc|polar, …} and its parameters; required
blocks (int) – codewords per trial; default 1
interleave (bool) – random bit interleaver over the coded bits of the trial (BICM), the same in fec_encode and fec_decode; default false
seed (int) – seed of the interleaver; default 0
- gives = ('bits', 'payload')#
- needs = ()#
- param_names = ('code', 'blocks', 'interleave', 'seed')#
- class comnum.blocks.Fiber(*, fiber: dict | Var | None = None, length_km: float | Var | None = None, compensate_loss: bool | Var = True)#
Linear fibre (loss and dispersion, OptiCommPy linearFiberChannel).
Needs: samples. Gives: nothing.
- Parameters:
fiber (dict) – fibre parameters, merged over the
fiberof the specification (see FiberParams); itsramanmapping adds Raman pumps and ISRS; keys alpha_db_km, d_ps_nm_km, gamma_w_km, span_km, n_spans, fc_hz, nf_db, slope_ps_nm2_km, raman; default spec fiberlength_km (float) – length; the whole link by default [km]; default total
compensate_loss (bool) – restore the power with an ideal gain e^(αL/2); default true
- gives = ()#
- needs = ('samples',)#
- param_names = ('fiber', 'length_km', 'compensate_loss')#
- class comnum.blocks.Fir(*, h: list | Var, alignment: str | Var = 'causal')#
Linear channel with complex taps.
Needs: samples. Gives: nothing.
- Parameters:
- gives = ()#
- needs = ('samples',)#
- param_names = ('h', 'alignment')#
- class comnum.blocks.Foe(*, m: int | Var = 4, refined: bool | Var = True)#
Frequency-offset estimation by the M-th power and correction; records foe_hz.
Needs: samples. Gives: nothing.
- Parameters:
- gives = ()#
- needs = ('samples',)#
- param_names = ('m', 'refined')#
- class comnum.blocks.FrameSync(*, start: int | Var = 0, length: int | Var = 512, max_delay: int | Var = 64, symmetry: int | Var = 4, exclude: bool | Var = True)#
Delay and rotation on known symbols, output aligned on the transmitted symbols; records delay and quality.
Needs: samples, symbols. Gives: nothing.
- Parameters:
start (int) – first known symbol; default 0
length (int) – number of known symbols; default 512
max_delay (int) – largest delay searched [symbols]; default 64
symmetry (int) – rotational symmetry of the constellation; 0 removes the exact phase; default 4
exclude (bool) – exclude the known symbols from the metrics; default true
- gives = ()#
- needs = ('samples', 'symbols')#
- param_names = ('start', 'length', 'max_delay', 'symmetry', 'exclude')#
- class comnum.blocks.Gardner(*, kp: float | Var = 0.001, ki: float | Var = 1e-06, nyquist: bool | Var = True)#
Gardner clock recovery at 2 samples per symbol.
Needs: samples. Gives: nothing.
- Parameters:
- gives = ()#
- needs = ('samples',)#
- param_names = ('kp', 'ki', 'nyquist')#
- class comnum.blocks.Manakov(*, fiber: dict | Var | None = None, step_rule: str | Var = 'fwm', steps_per_span: int | Var = 100, fwm_phase_rad: float | Var = 20.0, bandwidth_hz: float | Var | None = None, max_nl_phase_rad: float | Var = 0.02, step_km: float | Var | None = None, nonlinear_step: str | Var = 'midpoint', check_sampling: bool | Var = True, max_iterations: int | Var = 10, tolerance: float | Var = 1e-05, amplification: str | Var = 'edfa', noise: bool | Var = True)#
Dual-polarisation nonlinear propagation over the link (Manakov equation, split step with the phase at the middle of the step or OptiCommPy’s trapezoidal one), EDFAs with ASE.
Needs: samples. Gives: nothing.
- Parameters:
fiber (dict) – fibre parameters, merged over the
fiberof the specification (see FiberParams); itsramanmapping adds Raman pumps and ISRS; keys alpha_db_km, d_ps_nm_km, gamma_w_km, span_km, n_spans, fc_hz, nf_db, slope_ps_nm2_km, raman; default spec fiberstep_rule (str) – the steps: the four-wave-mixing phase of Musetti et al. 2018 (power independent), OptiCommPy’s nonlinear phase per step, or steps_per_span logarithmic steps (Bosco et al. 2000); one of fwm, nonlinear_phase, logarithmic; default fwm
steps_per_span (int) – logarithmic steps per span (step_rule logarithmic); default 100
fwm_phase_rad (float) – four-wave-mixing phase across the bandwidth in the first step of a span (step_rule fwm) [rad]; default 20.0
bandwidth_hz (float) – signal bandwidth of the rule fwm (measured on the launched field if absent) [Hz]; default none
max_nl_phase_rad (float) – largest nonlinear phase rotation per step (step_rule nonlinear_phase) [rad]; default 2e-2
step_km (float) – a fixed step instead of the adaptive one [km]; default none
nonlinear_step (str) – the nonlinear phase of a step: the power at its middle (the scalar solver) or the trapezoidal mean of the power at its ends (OptiCommPy, iterated; less accurate in WDM); one of midpoint, trapezoidal; default midpoint
check_sampling (bool) – refuse a signal whose sampling rate or block cannot hold the four-wave mixing and the walk-off of the link (Musetti et al. 2018, Appendix B); default true
max_iterations (int) – trapezoidal iterations per step at most; default 10
tolerance (float) – convergence tolerance of the iterations; default 1e-5
amplification (str) – edfa (gain αL, ASE), ideal (noiseless gain) or none; with fiber.raman, the amplifier restores every frequency; one of edfa, ideal, none; default edfa
noise (bool) – draw the ASE of the EDFAs and the spontaneous Raman noise; default true
- gives = ()#
- needs = ('samples',)#
- param_names = ('fiber', 'step_rule', 'steps_per_span', 'fwm_phase_rad', 'bandwidth_hz', 'max_nl_phase_rad', 'step_km', 'nonlinear_step', 'check_sampling', 'max_iterations', 'tolerance', 'amplification', 'noise')#
- class comnum.blocks.ManakovDbp(*, fiber: dict | Var | None = None, steps_per_span: int | Var = 1, nonlinear_scale: float | Var = 1.0, amplification: str | Var = 'edfa')#
Dual-polarisation digital back-propagation of the link (Manakov equation, coefficients negated).
Needs: samples. Gives: nothing.
- Parameters:
fiber (dict) – fibre parameters, merged over the
fiberof the specification (see FiberParams); itsramanmapping adds Raman pumps and ISRS; keys alpha_db_km, d_ps_nm_km, gamma_w_km, span_km, n_spans, fc_hz, nf_db, slope_ps_nm2_km, raman; default spec fibersteps_per_span (int) – symmetric steps per span; default 1
nonlinear_scale (float) – ξ: multiplies the nonlinear phase (0: dispersion compensation only); default 1.0
amplification (str) – the amplification of the forward link; one of edfa, ideal, none; default edfa
- gives = ()#
- needs = ('samples',)#
- param_names = ('fiber', 'steps_per_span', 'nonlinear_scale', 'amplification')#
- class comnum.blocks.Map(*, constellation: str | dict | Var = 'QPSK', symbol_rate: float | Var = 1.0)#
Map the coded bits on a constellation (Gray labels, the last symbol padded with random bits).
Needs: bits. Gives: symbols, constellation, samples.
- Parameters:
- gives = ('symbols', 'constellation', 'samples')#
- needs = ('bits',)#
- param_names = ('constellation', 'symbol_rate')#
- class comnum.blocks.MatchedFilter(*, kind: str | Var = 'rrc', rolloff: float | Var = 0.1, n_taps: int | Var = 1025)#
Filter with a receive pulse at the current samples per symbol.
Needs: samples. Gives: nothing.
- Parameters:
- gives = ()#
- needs = ('samples',)#
- param_names = ('kind', 'rolloff', 'n_taps')#
- class comnum.blocks.MimoRx(*, detector: str | Var = 'mmse', k: int | Var = 8, iterations: int | Var = 10, llr: bool | Var = False)#
Detect a single-carrier link over flat fading with the known channel; output the symbols and their noise variances.
Needs: samples, constellation, csi. Gives: noise, llr.
- Parameters:
detector (str) – mr (matched filter), zf, mmse, sic (MMSE-SIC), zf_sic (ZF-SIC), ml, sphere, kbest, amp (LAMA) or oamp (OAMP-LMMSE); one of mr, zf, mmse, sic, zf_sic, ml, sphere, kbest, amp, oamp; default mmse
k (int) – paths of kbest; default 8
iterations (int) – iterations of amp and oamp; default 10
llr (bool) – also compute the bit LLRs with the detector (mr, zf, mmse, ml, kbest, amp, oamp); default false
- gives = ('noise', 'llr')#
- needs = ('samples', 'constellation', 'csi')#
- param_names = ('detector', 'k', 'iterations', 'llr')#
- class comnum.blocks.MimoTx(*, n_tx: int | Var = 2, scheme: str | Var = 'spatial')#
Spread the symbols over n_tx antennas: spatial multiplexing (power 1/n_tx per antenna) or Alamouti’s code.
Needs: samples. Gives: nothing.
- Parameters:
- gives = ()#
- needs = ('samples',)#
- param_names = ('n_tx', 'scheme')#
- class comnum.blocks.NoiseEstimate(*, mode: str | Var = 'decisions')#
Declare the receiver’s posterior: the noise variance of the aligned samples; records sigma2.
Needs: samples, symbols, constellation. Gives: noise.
- Parameters:
mode (str) – decisions (blind, around the nearest points) or known (around the transmitted symbols); one of decisions, known; default decisions
- gives = ('noise',)#
- needs = ('samples', 'symbols', 'constellation')#
- param_names = ('mode',)#
- class comnum.blocks.Normalize(*, power_dbm: float | Var | None = None)#
Scale the samples to a mean power.
Needs: samples. Gives: nothing.
- Parameters:
power_dbm (float) – mean power [dBm]; default unit power
- gives = ()#
- needs = ('samples',)#
- param_names = ('power_dbm',)#
- class comnum.blocks.OfdmRx(*, estimation: str | Var = 'perfect', detector: str | Var = 'mmse', k: int | Var = 8, iterations: int | Var = 10, llr: bool | Var = False)#
Demodulate the OFDM grids, estimate the channel and detect every data resource element; output the symbols and their noise variances.
Needs: samples, constellation, ofdm. Gives: noise, llr.
- Parameters:
estimation (str) – perfect (the channel of the channel block), ls (linear interpolation) or lmmse (uniform delay profile over the prefix); one of perfect, ls, lmmse; default perfect
detector (str) – mr (matched filter), zf, mmse, sic (MMSE-SIC), zf_sic (ZF-SIC), ml, sphere, kbest, amp (LAMA) or oamp (OAMP-LMMSE); one of mr, zf, mmse, sic, zf_sic, ml, sphere, kbest, amp, oamp; default mmse
k (int) – paths of kbest; default 8
iterations (int) – iterations of amp and oamp; default 10
llr (bool) – also compute the bit LLRs with the detector (mr, zf, mmse, ml, kbest, amp, oamp); default false
- gives = ('noise', 'llr')#
- needs = ('samples', 'constellation', 'ofdm')#
- param_names = ('estimation', 'detector', 'k', 'iterations', 'llr')#
- class comnum.blocks.OfdmTx(*, n_fft: int | Var = 256, n_subcarriers: int | Var = 200, n_cp: int | Var = 16, oversampling: int | Var = 1, dc_null: bool | Var = False, n_symbols: int | Var = 14, pilots: str | dict | Var | None = None, subcarrier_spacing_hz: float | Var = 15000.0, seed: int | Var = 0)#
Map every antenna’s symbols on resource grids with pilots and OFDM-modulate them (power K/(LN) per sample).
Needs: samples. Gives: ofdm.
- Parameters:
n_fft (int) – subcarrier grid N; default 256
n_subcarriers (int) – active subcarriers K; default 200
n_cp (int) – cyclic prefix (Nyquist-rate samples) [samples]; default 16
oversampling (int) – oversampling L; default 1
dc_null (bool) – leave the DC subcarrier empty; default false
n_symbols (int) – OFDM symbols per grid; default 14
pilots (str | dict) – pattern block {period}, comb {spacing}, lattice {freq, time} or none; with several antennas the pilots of a symbol are dealt to the antennas in turn; keys pattern, period, spacing, freq, time; default {pattern: lattice, freq: 3, time: 4}
subcarrier_spacing_hz (float) – subcarrier spacing Δf [Hz]; default 15e3
seed (int) – seed of the pilot symbols; default 0
- gives = ('ofdm',)#
- needs = ('samples',)#
- param_names = ('n_fft', 'n_subcarriers', 'n_cp', 'oversampling', 'dc_null', 'n_symbols', 'pilots', 'subcarrier_spacing_hz', 'seed')#
- class comnum.blocks.PasDecode(*, constellation: str | dict | Var = '64-QAM', mb_lambda: float | Var = 1.0, n: int | Var = 1536, k: int | Var | None = None, var_degree: int | Var = 3, seed: int | Var = 1, rule: str | Var = 'sum_product', alpha: float | Var = 0.8, layered: bool | Var = True, iterations: int | Var = 50, blocks: int | Var = 1, symbol_rate: float | Var = 1.0)#
PAS receiver: bit LLRs with the amplitude priors, LDPC decoding, dematching (the parameters of pas_encode).
Needs: samples, symbols, noise. Gives: decoded.
- Parameters:
constellation (str | dict) – a square QAM: 2^m-PAM per dimension; keys kind, m; default 64-QAM
mb_lambda (float) – Maxwell-Boltzmann amplitudes p(a) ∝ exp(-λ x²) on the unit-energy uniform QAM (0: uniform); default 1.0
n (int) – length of the LDPC codeword, a multiple of 2m [bits]; default 1536
k (int) – information bits of the code; above n(m-1)/m the signs also carry data (γ > 0) [bits]; default n(m-1)/m
var_degree (int) – variable-node degree of the PEG code; default 3
seed (int) – seed of the PEG construction; default 1
rule (str) – check-node rule; one of sum_product, min_sum, normalized_min_sum, offset_min_sum; default sum_product
alpha (float) – scale or offset of min-sum; default 0.8
layered (bool) – layered schedule; default true
iterations (int) – decoding iterations at most; default 50
blocks (int) – codewords per trial (pas_encode); default 1
symbol_rate (float) – symbol rate (pas_encode) [Bd]; default 1.0
- gives = ('decoded',)#
- needs = ('samples', 'symbols', 'noise')#
- param_names = ('constellation', 'mb_lambda', 'n', 'k', 'var_degree', 'seed', 'rule', 'alpha', 'layered', 'iterations', 'blocks', 'symbol_rate')#
- class comnum.blocks.PasEncode(*, constellation: str | dict | Var = '64-QAM', mb_lambda: float | Var = 1.0, n: int | Var = 1536, k: int | Var | None = None, var_degree: int | Var = 3, seed: int | Var = 1, rule: str | Var = 'sum_product', alpha: float | Var = 0.8, layered: bool | Var = True, iterations: int | Var = 50, blocks: int | Var = 1, symbol_rate: float | Var = 1.0)#
Probabilistic amplitude shaping: CCDM-shaped amplitudes, an LDPC code whose parity bits are the signs, square QAM (the first block of a link).
Needs: nothing. Gives: bits, symbols, constellation, samples, payload.
- Parameters:
constellation (str | dict) – a square QAM: 2^m-PAM per dimension; keys kind, m; default 64-QAM
mb_lambda (float) – Maxwell-Boltzmann amplitudes p(a) ∝ exp(-λ x²) on the unit-energy uniform QAM (0: uniform); default 1.0
n (int) – length of the LDPC codeword, a multiple of 2m [bits]; default 1536
k (int) – information bits of the code; above n(m-1)/m the signs also carry data (γ > 0) [bits]; default n(m-1)/m
var_degree (int) – variable-node degree of the PEG code; default 3
seed (int) – seed of the PEG construction; default 1
rule (str) – check-node rule; one of sum_product, min_sum, normalized_min_sum, offset_min_sum; default sum_product
alpha (float) – scale or offset of min-sum; default 0.8
layered (bool) – layered schedule; default true
iterations (int) – decoding iterations at most; default 50
blocks (int) – codewords per trial (pas_encode); default 1
symbol_rate (float) – symbol rate (pas_encode) [Bd]; default 1.0
- gives = ('bits', 'symbols', 'constellation', 'samples', 'payload')#
- needs = ()#
- param_names = ('constellation', 'mb_lambda', 'n', 'k', 'var_degree', 'seed', 'rule', 'alpha', 'layered', 'iterations', 'blocks', 'symbol_rate')#
- class comnum.blocks.PhaseNoise(*, linewidth_hz: float | Var | None = None, sigma_rad: float | Var | None = None, origin: str | Var = 'zero')#
Wiener phase noise.
Needs: samples. Gives: nothing.
- Parameters:
linewidth_hz (float) – laser linewidth, increments of variance 2πΔν/f_s [Hz]; default none
sigma_rad (float) – increment standard deviation per sample, instead of the linewidth [rad]; default none
origin (str) – zero: φ[0] = 0, the first sample is not rotated (OptiCommPy); step: φ[0] = Δ[0], the first sample is rotated too; one of zero, step; default zero
- gives = ()#
- needs = ('samples',)#
- param_names = ('linewidth_hz', 'sigma_rad', 'origin')#
- class comnum.blocks.Pmd(*, mean_dgd_ps: float | Var = 0.0, sections: int | Var = 20, theta_deg: float | Var | None = None)#
Random rotation of the polarisations and polarisation-mode dispersion of a dual-polarisation signal, a new realisation every trial.
Needs: samples. Gives: nothing.
- Parameters:
- gives = ()#
- needs = ('samples',)#
- param_names = ('mean_dgd_ps', 'sections', 'theta_deg')#
- class comnum.blocks.Probe(*, metrics: list | Var | None = None, skip_start: int | Var = 0, skip_end: int | Var = 0, scale: str | Var = 'power')#
Measure metrics at this point of the link; reported as <label>.<metric> (label: probe by default).
Needs: samples. Gives: nothing.
- Parameters:
metrics (list) – the metrics of the specifications (on symbols aligned at 1 sample per symbol), and power_dbm and papr_db anywhere; default [snr_db]
skip_start (int) – symbols left out at the start of every polarisation (the edges of the filters) [symbols]; default 0
skip_end (int) – symbols left out at the end of every polarisation [symbols]; default 0
scale (str) – scaling before the decisions: power (blind), ls (least-squares complex gain, genie-aided) or none; one of power, ls, none; default power
- gives = ()#
- needs = ('samples',)#
- param_names = ('metrics', 'skip_start', 'skip_end', 'scale')#
- class comnum.blocks.PulseShape(*, kind: str | Var = 'rrc', rolloff: float | Var = 0.1, n_taps: int | Var = 1025, sps: int | Var = 2)#
Upsample and filter with a transmit pulse, then normalise to unit power.
Needs: samples. Gives: nothing.
- Parameters:
- gives = ()#
- needs = ('samples',)#
- param_names = ('kind', 'rolloff', 'n_taps', 'sps')#
- class comnum.blocks.Rayleigh(*, n_rx: int | Var = 1, coherence_samples: int | Var = 0, k_factor: float | Var = 0.0, rx_correlation: float | Var = 0.0, tx_correlation: float | Var = 0.0)#
Flat fading y = H x on every antenna; records the channel for a genie-aided receiver.
Needs: samples. Gives: csi.
- Parameters:
n_rx (int) – receive antennas; default 1
coherence_samples (int) – samples per channel matrix (0: one matrix per trial, 1: fast fading) [samples]; default 0
k_factor (float) – Rician factor K (linear), 0 for Rayleigh fading; default 0.0
rx_correlation (float) – exponential correlation ρ of the receive antennas; default 0.0
tx_correlation (float) – exponential correlation ρ of the transmit antennas; default 0.0
- gives = ('csi',)#
- needs = ('samples',)#
- param_names = ('n_rx', 'coherence_samples', 'k_factor', 'rx_correlation', 'tx_correlation')#
- class comnum.blocks.ReferenceSync(*, window: int | Var = 4096, start: int | Var | None = None, symmetry: int | Var = 4)#
Align the periodic reference of a capture on the received symbols (circular correlation); records offset and quality.
Needs: samples, constellation, capture. Gives: bits, symbols.
- Parameters:
- gives = ('bits', 'symbols')#
- needs = ('samples', 'constellation', 'capture')#
- param_names = ('window', 'start', 'symmetry')#
- class comnum.blocks.Resample(*, sps: float | Var = 2.0)#
Band-limited resampling of the block (FFT) to a number of samples per symbol.
Needs: samples. Gives: nothing.
- Parameters:
sps (float) – output samples per symbol; default 2.0
- gives = ()#
- needs = ('samples',)#
- param_names = ('sps',)#
- class comnum.blocks.RxIq(*, t: list | Var)#
Receiver IQ imbalance [Re y; Im y] = T [Re x; Im x].
Needs: samples. Gives: nothing.
- Parameters:
t (list) – row-major real 2×2 matrix [t00, t01, t10, t11]; required
- gives = ()#
- needs = ('samples',)#
- param_names = ('t',)#
- class comnum.blocks.Source(*, constellation: str | dict | Var = '16-QAM', n_symbols: int | Var = 4096, symbol_rate: float | Var = 1.0, mb_lambda: float | Var | None = None, pols: int | Var = 1)#
Draw the bits and symbols of a block (Gray labels of OptiCommPy).
Needs: nothing. Gives: bits, symbols, constellation, samples.
- Parameters:
constellation (str | dict) –
16-QAM,QPSK,8-PSK,4-PAM,OOK, {kind, m}, orgaussian(circular Gaussian symbols, no decisions); unit energy; keys kind, m; default 16-QAMn_symbols (int) – symbols per trial; default 4096
symbol_rate (float) – symbol rate; 1 keeps a normalised time axis [Bd]; default 1.0
mb_lambda (float) – Maxwell-Boltzmann shaping p(x) ∝ exp(-λ|x|²); default none
pols (int) – polarisations: 2 draws independent symbols for x and y (dual-polarisation optics); default 1
- gives = ('bits', 'symbols', 'constellation', 'samples')#
- needs = ()#
- param_names = ('constellation', 'n_symbols', 'symbol_rate', 'mb_lambda', 'pols')#
- class comnum.blocks.Ssfm(*, fiber: dict | Var | None = None, step_km: float | Var = 1.0, steps_per_span: int | Var | None = None, amplification: str | Var = 'edfa', noise: bool | Var = True, precision: str | Var = 'f64', check_sampling: bool | Var = True)#
Split-step Fourier propagation over the link, one polarisation.
Needs: samples. Gives: nothing.
- Parameters:
fiber (dict) – fibre parameters, merged over the
fiberof the specification (see FiberParams); itsramanmapping adds Raman pumps and ISRS; keys alpha_db_km, d_ps_nm_km, gamma_w_km, span_km, n_spans, fc_hz, nf_db, slope_ps_nm2_km, raman; default spec fiberstep_km (float) – step [km]; default 1.0
steps_per_span (int) – this number of logarithmic steps per span instead of step_km (Bosco et al. 2000, eq. (6): every step carries the same integrated power, short at the start of the span; double precision); default none
amplification (str) – edfa (gain αL, ASE), ideal (noiseless gain) or none; with fiber.raman, the amplifier restores every frequency; one of edfa, ideal, none; default edfa
noise (bool) – draw the ASE of the EDFAs and the spontaneous Raman noise; default true
precision (str) – f64, or f32 (about twice as fast, relative error about 1e-6 √steps; not with Raman); one of f64, f32; default f64
check_sampling (bool) – refuse a signal whose sampling rate or block cannot hold the four-wave mixing and the walk-off of the link (Musetti et al. 2018, Appendix B); default true
- gives = ()#
- needs = ('samples',)#
- param_names = ('fiber', 'step_km', 'steps_per_span', 'amplification', 'noise', 'precision', 'check_sampling')#
- class comnum.blocks.Tdl(*, profile: str | dict | Var = 'EPA', delay_spread_s: float | Var = 1e-07, doppler_hz: float | Var = 0.0, n_rx: int | Var = 1)#
Tapped-delay-line multipath fading with Clarke/Jakes Doppler; records the taps for a genie-aided receiver.
Needs: samples. Gives: csi.
- Parameters:
profile (str | dict) – EPA, EVA, ETU (3GPP TS 36.101), pedestrian_a, pedestrian_b, vehicular_a, vehicular_b (ITU-R M.1225, Tables 4 and 5), TDLA30, TDLB100, TDLC300, TDLD30 (3GPP TS 38.101-4, Annex B.2.1), TDL-A to TDL-E (3GPP TR 38.901, Tables 7.7.2-1 to 7.7.2-5, scaled to delay_spread_s), or {rms_delay_s, resolution_s} (exponential); keys rms_delay_s, resolution_s; default EPA
delay_spread_s (float) – RMS delay spread of TDL-A to TDL-E (TR 38.901 §7.7.3); the other profiles ignore it [s]; default 100e-9
doppler_hz (float) – maximum Doppler shift; 0 for a channel constant over the trial [Hz]; default 0.0
n_rx (int) – receive antennas; default 1
- gives = ('csi',)#
- needs = ('samples',)#
- param_names = ('profile', 'delay_spread_s', 'doppler_hz', 'n_rx')#
- class comnum.blocks.TxIq(*, beta: list | Var)#
Transmitter IQ imbalance y = x + β x*.
Needs: samples. Gives: nothing.
- Parameters:
beta (list) – [re, im] of β; required
- gives = ()#
- needs = ('samples',)#
- param_names = ('beta',)#
- class comnum.blocks.Viterbi(*, n: int | Var = 35, m: int | Var = 4)#
Viterbi–Viterbi phase estimation and correction.
Needs: samples. Gives: nothing.
- gives = ()#
- needs = ('samples',)#
- param_names = ('n', 'm')#
- class comnum.blocks.WdmRx(*, sps: int | Var = 2)#
Bring the channel under test to baseband and keep its band (ideal low-pass by resampling).
Needs: samples, wdm. Gives: nothing.
- Parameters:
sps (int) – output samples per symbol; default 2
- gives = ()#
- needs = ('samples', 'wdm')#
- param_names = ('sps',)#
- class comnum.blocks.WdmTx(*, n_channels: int | Var = 5, spacing_hz: float | Var = 50000000000.0, sps: int | Var = 8, power_dbm: float | list | Var = 0.0, kind: str | Var = 'rrc', rolloff: float | Var = 0.1, n_taps: int | Var = 1025, linewidth_hz: float | Var = 0.0, channel: int | Var | None = None, mzm_scale: float | Var | None = None)#
WDM transmitter: the channel under test and independently modulated neighbours on the grid of OptiCommPy’s simpleWDMTx.
Needs: samples. Gives: wdm.
- Parameters:
n_channels (int) – channels N; the grid is (k - ⌊N/2⌋) Δf, shifted by Δf/2 when N is even; default 5
spacing_hz (float) – grid spacing Δf [Hz]; default 50e9
sps (int) – samples per symbol of the multiplex (the sampling rate must cover the band); default 8
power_dbm (float | list) – launch power per channel, both polarisations; a list gives one per channel [dBm]; default 0.0
kind (str) – the pulse; one of rect, nrz, rc, rrc, rz; default rrc
rolloff (float) – roll-off of rc and rrc; default 0.1
n_taps (int) – taps of rc and rrc (odd: on the sampling instants); default 1025
linewidth_hz (float) – linewidth of the transmit lasers [Hz]; default 0.0
channel (int) – index of the channel under test (⌊N/2⌋ by default); default centre
mzm_scale (float) – drive the IQ modulator of OptiCommPy at this peak amplitude V/V_π (none: a linear modulator); default none
- gives = ('wdm',)#
- needs = ('samples',)#
- param_names = ('n_channels', 'spacing_hz', 'sps', 'power_dbm', 'kind', 'rolloff', 'n_taps', 'linewidth_hz', 'channel', 'mzm_scale')#