WDM code added (Pol Cont., Opt MUX/DEMUX, Opt Atten, DP_Fiber) -> the codebase is not optimized to always work with dp signals!
164 lines
4.9 KiB
Matlab
164 lines
4.9 KiB
Matlab
classdef Amplifier
|
|
%UNTITLED Summary of this class goes here
|
|
% Detailed explanation goes here
|
|
|
|
properties
|
|
amp_mode
|
|
gain_mode
|
|
nase_mode
|
|
|
|
amplification_db
|
|
noifig
|
|
|
|
fsimu
|
|
end
|
|
|
|
methods
|
|
function obj = Amplifier(options)
|
|
%UNTITLED Construct an instance of this class
|
|
% Detailed explanation goes here
|
|
arguments
|
|
options.amp_mode amp_mode = amp_mode.ideal_no_noise
|
|
options.gain_mode gain_mode = gain_mode.output_power
|
|
options.nase_mode nase_mode = nase_mode.pass_ase
|
|
|
|
options.amplification_db double = 0
|
|
|
|
options.noifig double = 0;
|
|
end
|
|
|
|
fn = fieldnames(options);
|
|
for n = 1:numel(fn)
|
|
obj.(fn{n}) = options.(fn{n});
|
|
end
|
|
|
|
end
|
|
|
|
function signalclass_out = process(obj,signalclass_in)
|
|
|
|
% actual processing of the signal
|
|
signalclass_in = obj.process_(signalclass_in);
|
|
|
|
% append to logbook
|
|
lbdesc = ['Optical Amplifier '];
|
|
signalclass_in = signalclass_in.logbookentry(lbdesc,obj);
|
|
|
|
% write to output
|
|
signalclass_out = signalclass_in;
|
|
|
|
end
|
|
|
|
function [X_out] = process_(obj,X_in)
|
|
|
|
|
|
%calc gain for output power mode, amp mode and saturated mode
|
|
a_lin = obj.calculateGain(X_in.signal);
|
|
|
|
%apply amplification
|
|
X_in.signal = a_lin * X_in.signal;
|
|
|
|
% now, optical ase noise:
|
|
if class(X_in) == "Opticalsignal"
|
|
|
|
if obj.amp_mode == amp_mode.ideal_no_noise
|
|
|
|
%don't add/ remove noise, but scale it accordingly
|
|
X_in.nase = obj.onlyAmplifyAse(X_in.nase, a_lin);
|
|
|
|
elseif obj.amp_mode == amp_mode.edfa_increase_nase
|
|
|
|
%calculate ASE-noise
|
|
X_in.nase = obj.increaseAse(X_in.nase, a_lin, obj.noifig , X_in.lambda );
|
|
|
|
elseif obj.amp_mode == amp_mode.edfa_replace_nase
|
|
|
|
%calculate ASE-noise
|
|
X_in.nase = obj.replaceAse(X_in.nase, a_lin, obj.noifig , X_in.lambda );
|
|
|
|
end
|
|
|
|
if obj.nase_mode == nase_mode.generate_ase
|
|
|
|
nase = X_in.nase;
|
|
fs = X_in.fs;
|
|
dimension = size(X_in.signal);
|
|
|
|
nase_numeric = obj.generateAseNoise(nase, fs, dimension);
|
|
|
|
[X_in.signal, osnr] = obj.applyAseToSignal(X_in.signal, nase_numeric);
|
|
|
|
X_in.nase = 0;
|
|
|
|
elseif obj.nase_mode == nase_mode.pass_ase
|
|
|
|
X_in.nase = X_in.nase;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
X_out = X_in;
|
|
|
|
|
|
|
|
end
|
|
|
|
function a_lin = calculateGain(obj,xin)
|
|
|
|
if obj.gain_mode == gain_mode.output_power
|
|
|
|
%get linear gain for output power mode
|
|
pow_in = sum(mean(abs(xin.^2)),2) ; % lin input power
|
|
pow_out = 10^(obj.amplification_db/10 - 3) ; % dBm to lin
|
|
a_lin = sqrt(pow_out/pow_in) ;
|
|
|
|
elseif obj.gain_mode == gain_mode.gain
|
|
|
|
%get linear gain for classic gain mode
|
|
a_lin=10^(obj.amplification_db/20);
|
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
function nase_amped = onlyAmplifyAse(~,nase_old, a_lin)
|
|
nase_amped = a_lin^2 * nase_old;
|
|
end
|
|
|
|
function nase_new = calculateAseFromThisAmp(~, a_lin, noisefig, lambda)
|
|
h = Constant.Planck;
|
|
c = Constant.LightSpeed;
|
|
nase_new = 0.5* 10^(noisefig/10) * h*c/lambda * (a_lin^2-1) ;
|
|
end
|
|
|
|
function ase_increased = increaseAse(obj,nase_old, a_lin, noisefig, lambda)
|
|
|
|
nase_fromThisAmp = obj.calculateAseFromThisAmp(a_lin, noisefig, lambda);
|
|
|
|
nase_old = a_lin^2 * nase_old;
|
|
|
|
ase_increased = nase_old + nase_fromThisAmp;
|
|
end
|
|
|
|
function nase_new = replaceAse(~,a_lin, noisefig, lambda_nm)
|
|
|
|
nase_fromThisAmp = obj.calculateAseFromThisAmp(a_lin, noisefig, lambda_nm);
|
|
|
|
nase_new = nase_fromThisAmp;
|
|
end
|
|
|
|
function nase_numeric = generateAseNoise(~, nase, fs, dimension)
|
|
rng(2023);
|
|
nase_numeric = (randn(dimension) + 1i*randn(dimension))*sqrt(nase/2*fs) ;
|
|
end
|
|
|
|
function [noisy_sig, osnr] = applyAseToSignal(~, opticalsignal, nase_numeric)
|
|
noisy_sig = opticalsignal + nase_numeric ;
|
|
osnr = pow2db(mean(abs(opticalsignal.^2))/mean(abs(nase_numeric.^2)));
|
|
% disp(osnr);
|
|
end
|
|
end
|
|
end
|
|
|