impairments#

Functions for the simulation of transmission and transceiver impairments.

qampy.core.impairments.H_PMD(theta, t_dgd, omega)#

Calculate the response for PMD applied to the signal (see e.g. _[1])

Parameters:
  • theta (float) – angle of the principle axis to the observed axis

  • t_dgd (float) – differential group delay between the polarisation axes

  • omega (array_like) – angular frequency of the light field

Returns:

H – response matrix for applying dgd

Return type:

matrix

References

qampy.core.impairments.add_awgn(sig, strgth)#

Add additive white Gaussian noise to a signal.

Parameters:
  • sig (array_like) – signal input array can be 1d or 2d, if 2d noise will be added to every dimension

  • strgth (float) – the strength of the noise to be added to each dimension

Returns:

sigout – output signal with added noise

Return type:

array_like

qampy.core.impairments.add_carrier_offset(sig, fo, fs)#

Add frequency offset to signal

Parameters:
  • sig (array_like) – signal input array

  • df (float) – frequency offset

  • fs (float) – sampling rate

Returns:

signal – signal with added offset

Return type:

array_like

qampy.core.impairments.add_dispersion(sig, fs, D, L, wl0=1.55e-06)#

Add dispersion to signal.

Parameters:
  • sig (array_like) – input signal

  • fs (flaot) – sampling frequency of the signal (in SI units)

  • D (float) – Dispersion factor in s/m/m

  • L (float) – Length of the dispersion in m

  • wl0 (float,optional) – center wavelength of the signal

Returns:

sig_out – dispersed signal

Return type:

array_like

qampy.core.impairments.add_modal_delay(sig, delay)#

Add a modal delay of n-symbols to modes of signal, e.g. to simulate a fake-pol mux system.

Parameters:
  • sig (array_like) – input signal

  • delay (array_like) – array of delays given in number of samples

Returns:

sig_out – output signal where each mode has been shifted by the appropriate delay

Return type:

array_like

qampy.core.impairments.apply_DAC_filter(sig, fs, cutoff=18000000000.0, fn=None, ch=1)#

Apply the frequency response filter of the DAC. This function uses either a 2nd order Bessel filter or a measured frequency response loaded from a file.

Parameters:
  • sig (array_like) – signal to be filtered. Can be real or complex

  • fs (float) – sampling rate of the signal

  • cutoff (float, optional) – Cutoff frequency used by only by Bessel filter

  • fn (string, optional) – filename of a experimentally measured response, if None use a Bessel filter approximation

  • ch (int, optional) – channel number of the measured response to use

Returns:

filter_sig – filtered signal

Return type:

array_like

qampy.core.impairments.apply_PMD_to_field(field, theta, t_dgd, fs)#

Apply PMD to a given input field

Parameters:
  • field (array_like) – input dual polarisation optical field (first axis is polarisation)

  • theta (float) – angle of the principle axis to the observed axis

  • t_dgd (float) – differential group delay between the polarisation axes

  • fs (float) – sampling rate of the field

Returns:

out – new dual polarisation field with PMD

Return type:

array_like

qampy.core.impairments.apply_enob_as_awgn(sig, enob, verbose=False)#

Add noise from limited ENOB as modelled as AWGN to signal.

Parameters:
  • sig (array_like) – input signal

  • enob (float) – Effective Number of Bits of the ADC or DAC

  • verbose (bool, optional) – Wether to return additional information

Returns:

  • if verbose is True – sig_enob_noise, snr_enob

  • else – sig_enob_noise

  • sig_enob_noise (array_like) – signal with added noise

  • snr_enob (float) – SNR corresponding to the ENOB in dB

qampy.core.impairments.apply_phase_noise(signal, df, fs)#

Add phase noise from local oscillators, based on a Wiener noise process.

Parameters:
  • signal (array_like) – single polarisation signal

  • df (float) – combined linewidth of local oscillators in the system

  • fs (float) – sampling frequency of the signal

Returns:

out – output signal with phase noise

Return type:

array_like

qampy.core.impairments.change_snr(sig, snr, fb, fs)#

Change the SNR of a signal assuming that the input signal is noiseless

Parameters:
  • sig (array_like) – the signal to change

  • snr (float) – the desired signal to noise ratio in dB

  • fb (float) – the symbol rate

  • fs (float) – the sampling rate

Returns:

sig – output signal with given SNR

Return type:

array_like

qampy.core.impairments.er_to_g(ext_rat)#
Parameters:

ext_rat

qampy.core.impairments.ideal_amplifier_response(sig, out_volt)#

Simulate a ideal amplifier, which just scale RF signal to out_volt. :param sig: :param out_volt:

qampy.core.impairments.load_dac_response(fn, fs, N, ch=1)#

Load the measured dac response and adjust it to target sampling frequency.

Parameters:
  • fn (string) – filename of the resposne to be loaded

  • fs (float) – sampling rate

  • N (int) – length of the output vector

  • ch (int, optional) – Which of the DAC channels to load the response for

Returns:

dacf_interp – frequency response of the DAC for channel ch with vector length N

Return type:

array_like

qampy.core.impairments.modulator_response(rfsig, dcbias=1, gfactr=1, cfactr=0, dcbias_out=0.5, gfactr_out=1)#

Function so simulate IQ modulator response.

Parameters:
  • rfsig (array_like) – complex version of the I (real part) and Q (imaginary part) of the signal

  • dcsig (complex or float, optional) – DC bias for I (real) and Q (imaginary) channel. If dcsig is real use the same DC bias for I and Q

  • vpi (complex or float, optional) – Vpi of the MZM (zero-power point) in I (real) and Q (imaginary) channel. If vpi is real use the same Vpi for both.

  • gfactr (complex or float, optional) – Split imbalance and path dependent loss of I (real) and Q (imaginary) MZM. An ideal MZM with infinite extinction ratio has gfactor=1. If gfactr is real use the same value for both I and Q.

  • cfactr (complex or float, optional) – Chirp factors of I (real) and (Q) channel MZMs, caused by the asymmetry in the electrode design of the MZM. cfactr = 0 for ideal MZM.

  • dcbias_out (float, optional) – DCBias of the outer MZM

  • gfactr_out (float, optional) – gain factor of the outer MZM

Returns:

e_out – Output signal of IQ modulator. (i.e. Here assume that input laser power is 0 dBm)

Return type:

array_like

qampy.core.impairments.phase_noise(sz, df, fs)#

Calculate phase noise from local oscillators, based on a Wiener noise process with a variance given by \(\sigma^2=2\pi df/fs\)

Parameters:
  • sz (tuple) – size of the phase noise array

  • df (float) – combined linewidth of local oscillators in the system

  • fs (float) – sampling frequency of the signal

Returns:

phase – randomly varying phase term

Return type:

array_like

qampy.core.impairments.quantize_signal(sig, nbits=6, rescale=True, re_normalize=True)#

Function so simulate limited resultion using DACs and ADCs

Parameters:
  • sig – Input signal, numpy array

  • nbits – Quantization resultion

  • rescale – Rescale to range p/m 1, default True

  • re_normalize – Renormalize signal after quantization

Returns:

Output quantized waveform

Return type:

sig_out

qampy.core.impairments.quantize_signal_New(sig_in, nbits=6, rescale_in=True, rescale_out=True)#
Function so simulate limited resultion using DACs and ADCs, limit quantization error to (-delta/2,delta/2) and set

decision threshold at mid-point between two quantization levels.

Parameters:
  • sig_in – Input signal, numpy array, notice: input signal should be rescale to (-1,1)

  • nbits – Quantization resolution

  • rescale_in – Rescale input signal to (-1,1)

  • rescale_out – Rescale output signal to (-input_max_swing,input_max_swing)

Returns:

Output quantized waveform

Return type:

sig_out

qampy.core.impairments.rotate_field(field, theta)#

Rotate a dual polarisation field by the given angle

Parameters:
  • field (array_like) – input dual polarisation optical field (first axis is polarisation)

  • theta (float) – angle to rotate by

Returns:

rotated_field – new rotated field

Return type:

array_like

qampy.core.impairments.sim_DAC_response(sig, fs, enob=5, clip_rat=1, quant_bits=0, **dac_params)#

Function to simulate DAC response, including quantization noise (ENOB) and frequency response.

Parameters:
  • sig (array_like) – Input signal

  • fs (float) – Sampling frequency of the signal

  • enob (float, optional) – Effective number of bits of the DAC (i.e. 6 bits.) modelled as AWGN. If enob=0 only quantize. If both enob and quant_bits are given, quantize first and then add enob noise.

  • clip_rat (float, optional) – Ratio of signal left after clipping. (i.e. clip_rat=0.8 means 20% of the signal is clipped) (default 1: no clipping)

  • quant_bits (float, optional) – Number of bits in the quantizer, only applied if not =0. (Default: don’t qpply quantization)

  • dac_params (dict, optional) – Parameters for the DAC response check apply_DAC_filter for the keyword parameters. If this is empty than do not apply the DAC response

Returns:

filter_sig – Quantized, clipped and filtered output signal

Return type:

array_like

qampy.core.impairments.sim_tx_response(sig, fs, enob=6, tgt_v=1, clip_rat=1, quant_bits=0, dac_params={'ch': None, 'cutoff': 18000000000.0, 'fn': None}, **mod_prms)#

Simulate a realistic transmitter possibly including quantization, noise due to limited ENOB, and DAC frequency response

Parameters:
  • sig (array_like) – Input signal used for transmission

  • fs (float) – Sampling frequency of signal

  • enob (float, optional) – efficient number of bits for DAC. If enob=0 only use quantizer. Unit: bits

  • tgt_v (float, optional) – target Voltage in fraction of Vpi

  • clip_rat (float, optional) – Ratio of signal left after clipping. (i.e. clip_rat=0.8 means 20% of the signal is clipped) (default 1: no clipping)

  • quant_bits (float, optional) – Number of bits in the quantizer, only applied if not =0. (Default: don’t qpply quantization)

  • dac_params (dict, optional) – parameters to pass to the DAC filter

  • mod_prms (dict, optional) – parameters to pass to the modulator (see modulator response for details)

Returns:

e_out – Signal with TX impairments

Return type:

array_like

qampy.core.impairments.simulate_transmission(sig, fb, fs, snr=None, freq_off=None, lwdth=None, dgd=None, theta=0.8420242973974251, modal_delay=None, roll_frame_sync=False)#

Convenience function to simulate impairments on signal at once

Parameters:
  • sig (array_like) – input signal

  • fb (flaot) – symbol rate of the signal

  • fs (float) – sampling rate of the signal

  • snr (flaat, optional) – desired signal-to-noise ratio of the signal. (default: None, don’t change SNR)

  • freq_off (float, optional) – apply a carrier offset to signal (default: None, don’t apply offset)

  • lwdth (float, optional) – linewidth of the transmitter and LO lasers (default: None, infinite linewidth)

  • dgd (float, optional) – first-order PMD (differential group delay) (default: None, do not apply PMD)

  • theta (float, optional) – rotation angle to principle states of polarization

  • modal_delay (array_like, optional) – add a delay given in N samples to the signal (default: None, do not add delay)

Returns:

signal – signal with transmission impairments applied

Return type:

array_like