mokka.channels
Module with channel model implementations.
Channels sub-module implemented within the PyTorch framework.
- class mokka.channels.torch.ComplexAWGN(N_0=None)
Bases:
Module
Complex AWGN channel defined with zero mean and variance N_0.
This converts to a setting of stddev sqrt(N_0/2) for real and imaginary parts of the distribution.
- __init__(N_0=None)
Construct ComplexAWGN.
- forward(x, N_0=None)
Apply Gaussian noise to a signal.
- Parameters:
x – input signal to apply noise to.
N_0 – noise variance
- Returns:
input signal distorted with AWGN
- class mokka.channels.torch.DPImpairments(samp_rate, tau_cd, tau_pmd, phi_IQ, theta, rho=0)
Bases:
Module
Apply a list of impairments experienced for dual pol. transmission.
This includes residual chromatic dispersion, polarization mode dispersion, polarization rotation and IQ shift
- __init__(samp_rate, tau_cd, tau_pmd, phi_IQ, theta, rho=0)
Initialize internal Module state, shared by both nn.Module and ScriptModule.
- forward(signal)
Apply DPImpairment to a dual polarization signal
- Parameters:
signal – Must be a 2xN complex-valued PyTorch tensor
- class mokka.channels.torch.EDFAAmpDualPol(span_length: int, amp_gain: str, alphaa_db: Float[Tensor, '1'], alphab_db: Float[Tensor, '1'], amp_noise: bool, noise_figure: Float[Tensor, '1'], optical_carrier_frequency: float, bw: float, P_input_lin: float, padding: int)
Bases:
Module
Implement Gaussian noise EDFA model for dual polarization fiberoptical simulation.
- Parameters:
span_length – span_length
amp_gain – Which amplification gain model to use either ‘alpha_equalization’, ‘equal_power’
alphaa_db – power loss coeficient [dB/km] for eigenstate a
alphab_db – power loss coeficient [dB/km] for eigenstate b
amp_noise – Consider amplification noise
noise_figure – Amplifier noise figure in dB
optical_carrier_frequency – Optical carrier frequency (for PSD) [GHz]
bw – Bandwidth of baseband signal (for PSD)
P_input_lin – Input power
padding – Number of samples to ignore in the beginning and end
- P_input_lin: float
- __init__(span_length: int, amp_gain: str, alphaa_db: Float[Tensor, '1'], alphab_db: Float[Tensor, '1'], amp_noise: bool, noise_figure: Float[Tensor, '1'], optical_carrier_frequency: float, bw: float, P_input_lin: float, padding: int) None
Method generated by attrs for class EDFAAmpDualPol.
- alphaa_db: Float[Tensor, '1']
- alphaa_lin: Float[Tensor, '1']
- alphab_db: Float[Tensor, '1']
- alphab_lin: Float[Tensor, '1']
- amp_gain: str
- amp_noise: bool
- bw: float
- forward(u1, u2, segment)
Amplify the signal according to the selected method after each span.
attention: the noise depends on the amplification. if \(\alpha = 0\), no noise is added.
Parameters
- u1array_like
co-polarized signal before the amplifier
- u2array_like
cross-polarized signal before the amplifier
- segment: array_like
segment number
Returns
signal : signal after the amplifier
- noise_figure: Float[Tensor, '1']
- optical_carrier_frequency: float
- padding: int
- span_length: int
- class mokka.channels.torch.EDFAAmpSinglePol(span_length: int, amp_gain: str, alpha_db: Float[Tensor, '1'], amp_noise: bool, noise_figure: Float[Tensor, '1'], optical_carrier_frequency: float, bw: float, P_input_lin: float, padding: int)
Bases:
Module
Gaussian noise model of an EDFA for single polarization fiberoptics.
- Parameters:
span_length – span_length [km]
amp_gain – Either ‘alpha_equalization’ or ‘equal_power’
alpha_db – Attenuation of the fiber [dB/km]
amp_noise – Consider amplification noise [bool]
amp_gain – Which amplification gain model to use either ‘alpha_equalization’, ‘equal_power’
optical_carrier_frequency – Optical carrier frequency (for PSD) [GHz]
bw – Occupied bandwidth (for PSD) [Hz]
P_input_lin – Input power [W]
padding – Number of samples to ignore in the beginning and end
- P_input_lin: float
- __init__(span_length: int, amp_gain: str, alpha_db: Float[Tensor, '1'], amp_noise: bool, noise_figure: Float[Tensor, '1'], optical_carrier_frequency: float, bw: float, P_input_lin: float, padding: int) None
Method generated by attrs for class EDFAAmpSinglePol.
- alpha_db: Float[Tensor, '1']
- alpha_lin: Float[Tensor, '1']
- amp_gain: str
- amp_noise: bool
- bw: float
- forward(signal, segment)
Amplify the signal according to the selected method after each span.
Attention: the noise depends on the amplification. if \(\alpha = 0\), no noise is added.
Parameters
- signalarray_like
signal before the amplifier
- segment: array_like
segment number
Returns
signal : signal after the amplifier
- noise_figure: Float[Tensor, '1']
- optical_carrier_frequency: float
- padding: int
- span_length: int
- class mokka.channels.torch.FixedArbitraryChannelDP(impulse_response)
Bases:
Module
Apply a fixed channel impulse response on both polarization separately
- __init__(impulse_response)
Initialize internal Module state, shared by both nn.Module and ScriptModule.
- forward(tx_signal)
Define the computation performed at every call.
Should be overridden by all subclasses.
Note
Although the recipe for forward pass needs to be defined within this function, one should call the
Module
instance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.
- class mokka.channels.torch.FixedChannelDP(impulse_response)
Bases:
Module
Apply a fixed channel impulse response on both polarization separately
- __init__(impulse_response)
Initialize internal Module state, shared by both nn.Module and ScriptModule.
- forward(tx_signal)
Define the computation performed at every call.
Should be overridden by all subclasses.
Note
Although the recipe for forward pass needs to be defined within this function, one should call the
Module
instance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.
- class mokka.channels.torch.FixedChannelSP(impulse_response)
Bases:
Module
Apply a fixed channel impulse response for a single polarization
- __init__(impulse_response)
Initialize internal Module state, shared by both nn.Module and ScriptModule.
- forward(tx_signal)
Define the computation performed at every call.
Should be overridden by all subclasses.
Note
Although the recipe for forward pass needs to be defined within this function, one should call the
Module
instance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.
- class mokka.channels.torch.OpticalNoise(dt: float, optical_carrier_wavelength: float, wavelength_bandwidth: float, OSNR: float)
Bases:
Module
Zero mean additive Gaussian noise based on given OSNR defined over certain wavelength.
- Parameters:
dt – Time step
optical_carrier_wavelength – Wavelength of optical carrier in nm
wavelength_bandwidth – Bandwidth in nm for which OSNR is given
OSNR – Optical SNR in dB
- OSNR: float
- __init__(dt: float, optical_carrier_wavelength: float, wavelength_bandwidth: float, OSNR: float) None
Method generated by attrs for class OpticalNoise.
- dt: float
- forward(signal)
Apply optical noise realization on signal.
- Parameters:
signal – input signal
- Returns:
noise impaired signal
- optical_carrier_wavelength: float
- wavelength_bandwidth: float
- class mokka.channels.torch.PDLElement(rho)
Bases:
Module
Simulate PDL in optical channels
- __init__(rho)
Construct a PDL element which exhibits a differential linear attenuation of rho. To get the attenuation matrix Gamma we first set attenuation of one polarization to sqrt(1+rho) and the other to sqrt(1-rho) and then rotate the matrix with a random rotation matrix uniform in Stokes space.
- Parameters:
rho – PDL in linear units
- forward(signal)
Define the computation performed at every call.
Should be overridden by all subclasses.
Note
Although the recipe for forward pass needs to be defined within this function, one should call the
Module
instance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.
- class mokka.channels.torch.PMDElement(sigma_p, pmd_parameter, span_length, steps_per_span, method='static')
Bases:
Module
Static and dynamic PMD Element according to Czegledi (2016)
Note: for SSFM only static PMD is correct
- property J
- __init__(sigma_p, pmd_parameter, span_length, steps_per_span, method='static')
Initialize internal Module state, shared by both nn.Module and ScriptModule.
- property a
- forward(signal: Tensor)
Process a dual polarization signal and apply PMD with a random walk to it.
- Parameters:
signal
- forward_dynamic(signal: Tensor)
- forward_static(signal: Tensor)
- step()
- steps(k=1)
- property theta
- class mokka.channels.torch.PMDPDLChannel(L, num_steps, pmd_parameter, pmd_correlation_length, f_samp, pmd_sigma=0.0, num_pdl_elements=0, pdl_max=0.8, pdl_min=0.1, method='freq')
Bases:
Module
Optical channel with only PMD and PDL impairments.
- __init__(L, num_steps, pmd_parameter, pmd_correlation_length, f_samp, pmd_sigma=0.0, num_pdl_elements=0, pdl_max=0.8, pdl_min=0.1, method='freq')
Initialize internal Module state, shared by both nn.Module and ScriptModule.
- channel_transfer(length, pulse_shape=None)
- forward(u)
Define the computation performed at every call.
Should be overridden by all subclasses.
Note
Although the recipe for forward pass needs to be defined within this function, one should call the
Module
instance afterwards instead of this since the former takes care of running the registered hooks while the latter silently ignores them.
- forward_freq(u)
- forward_time(u)
- step()
- class mokka.channels.torch.PhasenoiseWiener(start_phase_width=6.283185307179586, start_phase_init=0)
Bases:
Module
Wiener phase noise channel.
Forward call takes N0 for AWGN and sigma_phi for Wiener phase noise.
- Parameters:
start_phase_width – upper bound for initialization with a uniform distribution.
start_phase_init – initial phase value at the start of the generation for each noise sequence.
- __init__(start_phase_width=6.283185307179586, start_phase_init=0)
Construct PhasenoiseWiener.
- apply(x, sigma_phi=None)
Apply only Wiener phase noise.
Parameters
- x: array_like
Input data
- sigma_phi: float
phase noise variance
- forward(x, N0=None, sigma_phi=None)
Apply Wiener phase noise to a complex signal.
- Parameters:
x – ipnut signal to apply noise to
N0 – noise variance for Gaussian noise
sigma_phi – standard deviation of Wiener phase noise process
- Returns:
noise impaired signal
- class mokka.channels.torch.PolyPhaseChannelizer(coeff, n_down)
Bases:
Module
Perform poly-phase channelization with variable filter coefficients.
- __init__(coeff, n_down)
Init PolyPhaseChannelizer.
- forward(signal)
Apply poly-phase channelization on a wideband signal.
- mokka.channels.torch.ProakisChannel(variant, sps=1)
- class mokka.channels.torch.RamanAmpDualPol(amp_gain: str, alphaa_db: Float[Tensor, '1'], alphab_db: Float[Tensor, '1'], amp_noise: bool, noise_figure: Float[Tensor, '1'], optical_carrier_frequency: float, bw: float, P_input_lin: float, padding: int)
Bases:
Module
Implement a Gaussian model of the Raman dual polarization amp.
- Parameters:
amp_gain – Which amplification gain model to use either ‘alpha_equalization’, ‘equal_power’
alphaa_db – power loss coeficient [dB/km] for eigenstate a
alphab_db – power loss coeficient [dB/km] for eigenstate b
noise_figure – Amplifier noise figure in dB
optical_carrier_frequency – Optical carrier frequency (for PSD) [GHz]
bw – Bandwidth of baseband signal (for PSD)
P_input_lin – Input power
padding – Number of samples to ignore in the beginning and end
- P_input_lin: float
- __init__(amp_gain: str, alphaa_db: Float[Tensor, '1'], alphab_db: Float[Tensor, '1'], amp_noise: bool, noise_figure: Float[Tensor, '1'], optical_carrier_frequency: float, bw: float, P_input_lin: float, padding: int) None
Method generated by attrs for class RamanAmpDualPol.
- alphaa_db: Float[Tensor, '1']
- alphaa_lin: Float[Tensor, '1']
- alphab_db: Float[Tensor, '1']
- alphab_lin: Float[Tensor, '1']
- amp_gain: str
- amp_noise: bool
- bw: float
- forward(u1, u2, dz)
Amplify the signal according to the selected method after each span.
Attention: the noise depends on the amplification. if \(\alpha = 0\), no noise is added Parameters ———- signal : signal before the amplifier dz : step-size Returns ——- signal : signal after the amplifier
- noise_figure: Float[Tensor, '1']
- optical_carrier_frequency: float
- padding: int
- class mokka.channels.torch.ResidualPhaseNoise
Bases:
Module
Residual phase noise implementation.
This implements residual phase noise modeled with a zero mean phase noise process.
- __init__()
Construct ResidualPhaseNoise.
- forward(x, RPN)
Apply residual phase noise to signal.
- Parameters:
x – complex input signal
RPN – phase noise variance per input symbol
- Returns:
x with phase noise
- class mokka.channels.torch.SSFMPropagationDualPol(dt: Float[Tensor, '1'], dz: Float[Tensor, '1'], alphaa_db: Float[Tensor, '1'], alphab_db: Float[Tensor, '1'], betapa: Float[Tensor, '...'], betapb: Float[Tensor, '...'], gamma: Float[Tensor, '1'], length_span: Float[Tensor, '1'], num_span: Integer, delta_G: Float = 0.001, maxiter: Integer = 4, alphaa_pdl_lin: Float[Tensor, '1'] = tensor(0.), alphab_pdl_lin: Float[Tensor, '1'] = tensor(0.), psp: Float[Tensor, '2'] = tensor([0, 0]), amp: RamanAmpDualPol | EDFAAmpDualPol | None = None, solver_method: str = 'localerror', pmd_simulation: Bool = False, pmd_sigma: Float[Tensor, '1'] = tensor(0.), pmd_correlation_length: Float[Tensor, '1'] = tensor(0.1000), pmd_parameter: Float[Tensor, '1'] = tensor(0.), pdl_simulation: Bool = False, pdl_min: float = 0.07, pdl_max: float = 0.17)
Bases:
Module
Coupled NLS fibre propagation (with SSFM).
This class is adapted from Code written by Dominik Rimpf published under the MIT license [https://gitlab.com/domrim/bachelorarbeit-code]
This class solves the coupled nonlinear Schrodinger equation for pulse propagation in an optical fiber using the split-step Fourier method. The implementation and name are based on https://photonics.umd.edu/software/ssprop/vector-version/
- Parameters:
dt – time step between samples (sample time)
dz – propagation stepsize (delta z) of SSFM (segment length)
alphaa_db – power loss coeficient [dB/km] for eigenstate a
alphab_db – power loss coeficient [dB/km] for eigenstate b
betapa – dispersion polynomial coefficient vector for eigenstate a
betapb – dispersion polynomial coefficient vector for eigenstate b
gamma – nonlinearity coefficient
length_span – Length of span between amplifiers
num_span – Number of spans where num_span * length_span is full fiber channel length
delta_G – Goal local error (optional) (default 1e-3)
maxiter – Number of step-size iterations (optional) (default 4)
psp – Principal eigenstate of the fiber specified as a 2-vector containing the angles Psi and Chi (optional) (default [0,0])
solution_method – String that specifies which method to use when performing the split-step calculations. Supported methods elliptical and circular (optional) (default elliptical)
- __init__(dt: Float[Tensor, '1'], dz: Float[Tensor, '1'], alphaa_db: Float[Tensor, '1'], alphab_db: Float[Tensor, '1'], betapa: Float[Tensor, '...'], betapb: Float[Tensor, '...'], gamma: Float[Tensor, '1'], length_span: Float[Tensor, '1'], num_span: Integer, delta_G: Float = 0.001, maxiter: Integer = 4, alphaa_pdl_lin: Float[Tensor, '1'] = tensor(0.), alphab_pdl_lin: Float[Tensor, '1'] = tensor(0.), psp: Float[Tensor, '2'] = tensor([0, 0]), amp: RamanAmpDualPol | EDFAAmpDualPol | None = None, solver_method: str = 'localerror', pmd_simulation: Bool = False, pmd_sigma: Float[Tensor, '1'] = tensor(0.), pmd_correlation_length: Float[Tensor, '1'] = tensor(0.1000), pmd_parameter: Float[Tensor, '1'] = tensor(0.), pdl_simulation: Bool = False, pdl_min: float = 0.07, pdl_max: float = 0.17) None
Method generated by attrs for class SSFMPropagationDualPol.
- alphaa_db: Float[Tensor, '1']
- alphaa_lin: Float[Tensor, '1']
- alphaa_pdl_lin: Float[Tensor, '1']
- alphab_db: Float[Tensor, '1']
- alphab_lin: Float[Tensor, '1']
- alphab_pdl_lin: Float[Tensor, '1']
- amp: RamanAmpDualPol | EDFAAmpDualPol | None
- betapa: Float[Tensor, '...']
- betapb: Float[Tensor, '...']
- calculate_basis(w)
Calculate basis functions for linear step.
If any of the parameters alpha or beta change, this function needs to be executed again to recalculate parameters
- delta_G: Float
- dt: Float[Tensor, '1']
- dz: Float[Tensor, '1']
- forward(ux, uy)
Compute the progpagation for the dual polarization signal through the fiber optical channel.
- Parameters:
ux – input signal in x-polarization.
uy – input signal in y-polarization.
- Returns:
signal at the end of the fiber
- gamma: Float[Tensor, '1']
- get_operators(dz)
Obtain linear operators for given step length.
- length_span: Float[Tensor, '1']
- maxiter: Integer
- num_span: Integer
- pdl_max: float
- pdl_min: float
- pdl_simulation: Bool
- pmd_correlation_length: Float[Tensor, '1']
- pmd_parameter: Float[Tensor, '1']
- pmd_sigma: Float[Tensor, '1']
- pmd_simulation: Bool
- psp: Float[Tensor, '2']
- solution_method = 'elliptical'
- solver_method: str
- class mokka.channels.torch.SSFMPropagationSinglePol(dt: tensor, dz: tensor, alphadb: tensor, betap: tensor, gamma: tensor, length_span: tensor, num_span: tensor, delta_G: tensor = 0.001, maxiter: tensor = 4, amp: object | None = None, solver_method: str = 'localerror')
Bases:
Module
Non-linear fibre propagation (with SSFM).
This class is adapted from Code written by Dominik Rimpf published under the MIT license [https://gitlab.com/domrim/bachelorarbeit-code]
This class solves the nonlinear Schrodinger equation for pulse propagation in an optical fiber using the split-step Fourier method. The actual implementation is the local error method Sec II.E of Optimization of the Split-Step Fourier Method in Modeling Optical-Fiber Communications Systems https://doi.org/10.1109/JLT.2003.808628
- Parameters:
dt – time step between samples (sample time)
dz – propagation stepsize (delta z) of SSFM (segment length)
alphadb – power loss coeficient [dB/km]
beta2 – dispersion polynomial coefficient
gamma – nonlinearity coefficient
length_span – Length of span between amplifiers
num_span – Number of spans where num_span * length_span is full fiber channel length
delta_G – Goal local error
maxiter – Number of step-size iterations
- __init__(dt: tensor, dz: tensor, alphadb: tensor, betap: tensor, gamma: tensor, length_span: tensor, num_span: tensor, delta_G: tensor = 0.001, maxiter: tensor = 4, amp: object | None = None, solver_method: str = 'localerror') None
Method generated by attrs for class SSFMPropagationSinglePol.
- alphadb: tensor
- alphalin: tensor
- amp: object
- betap: tensor
- delta_G: tensor
- dt: tensor
- dz: tensor
- forward(u)
Compute the propagation through the configured fiber-optical channel.
- Parameters:
u0 – input signal (array)
- Returns:
array signal at the end of the fiber
- gamma: tensor
- get_operators(dz)
Calculate linear operators for given step length.
- length_span: tensor
- maxiter: tensor
- num_span: tensor
- solver_method: str
- mokka.channels.torch.SSFM_halfstep_end(signal, linear_op)
Calculate the final halfstep of the single polarization SSFM.
- mokka.channels.torch.SSFM_step(signal, linear_op, nonlinear_op)
Calculate single polarization SSFM step.
- class mokka.channels.torch.WDMDemux(n_channels, spacing, sym_rate, sim_rate, used_channels, method='classical')
Bases:
Module
WDM Demuxing for a configurable number of channels and system parameters.
- __init__(n_channels, spacing, sym_rate, sim_rate, used_channels, method='classical')
Initialize WDMDemux.
- classical_demux(signal)
Perform WDM Demuxing for each channel individually.
- forward(signal)
WDM Demux the wide-band signal.
- polyphase_demux(signal)
Peform WDM Demuxing with the Polyphase Channelizer method.
- class mokka.channels.torch.WDMMux(n_channels, spacing, samp_rate, sim_rate)
Bases:
Module
Perform configurable muxing of baseband channels to simulate WDM.
- __init__(n_channels, spacing, samp_rate, sim_rate)
Initialize WDMMux.
- forward(signals)
Modulate the signals on WDM channels in the digital baseband.
- mokka.channels.torch.symmetrical_SSFM_step(signal, half_linear_op, nonlinear_op)
Calculate symmetrical single polarization SSFM step.
- mokka.channels.torch.symmetrical_SSPROPV_step(u1, u2, h11, h12, h21, h22, NOP)
Calculate symmetrical dual polarization SSFM step.