Files
imdd_silas/Classes/Amplifier.m
2023-05-17 14:47:56 +02:00

163 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 = ['Amp '];
signalclass_in = signalclass_in.logbookentry(lbdesc);
% 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 = mean(abs(xin.^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)
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