auswertungsfiles und algos for ECOC 2025 rush...
This commit is contained in:
@@ -141,7 +141,7 @@ classdef Signal
|
|||||||
|
|
||||||
arguments
|
arguments
|
||||||
obj
|
obj
|
||||||
options.fignum
|
options.fignum = []
|
||||||
options.displayname = [];
|
options.displayname = [];
|
||||||
options.timeframe = 0;
|
options.timeframe = 0;
|
||||||
options.clear = 0;
|
options.clear = 0;
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ classdef FFE_DCremoval < handle
|
|||||||
obj.e = zeros(obj.order,1);
|
obj.e = zeros(obj.order,1);
|
||||||
obj.error = 0;
|
obj.error = 0;
|
||||||
|
|
||||||
|
obj.dc_buffer_len = floor(obj.dc_buffer_len);
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function [X,Noi] = process(obj, X, D)
|
function [X,Noi] = process(obj, X, D)
|
||||||
@@ -155,16 +157,15 @@ classdef FFE_DCremoval < handle
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if ~training
|
% if ~training
|
||||||
figure(1122)
|
% figure(1122)
|
||||||
hold on
|
% hold on
|
||||||
scatter(1:numel(e_dc_save),e_dc_save,1,'.');
|
% scatter(1:numel(e_dc_save),e_dc_save,1,'.');
|
||||||
scatter(1:numel(y),y,1,'.');
|
% % scatter(1:numel(y),y,1,'.');
|
||||||
|
%
|
||||||
end
|
% end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
272
Classes/04_DSP/Equalizer/FFE_DCremoval_adaptive_mu.m
Normal file
272
Classes/04_DSP/Equalizer/FFE_DCremoval_adaptive_mu.m
Normal file
@@ -0,0 +1,272 @@
|
|||||||
|
classdef FFE_DCremoval_adaptive_mu < handle
|
||||||
|
% Implementation of plain and simple FFE.
|
||||||
|
% 1) Training mode (stable performance when you use NLMS)
|
||||||
|
% 2) Decision directed mode
|
||||||
|
|
||||||
|
% Eq = FFE("epochs_tr",5,"epochs_dd",5,"len_tr",4096*2,"mu_dd",1e-4,"mu_tr",0,"order",25,"sps",2,"decide",0);
|
||||||
|
|
||||||
|
properties
|
||||||
|
sps % usually 2
|
||||||
|
order
|
||||||
|
e
|
||||||
|
error
|
||||||
|
|
||||||
|
len_tr
|
||||||
|
mu_tr
|
||||||
|
epochs_tr
|
||||||
|
|
||||||
|
mu_dd
|
||||||
|
epochs_dd
|
||||||
|
|
||||||
|
mu_dc
|
||||||
|
dc_buffer_len
|
||||||
|
|
||||||
|
ffe_buffer_len
|
||||||
|
|
||||||
|
smoothing_buffer_length
|
||||||
|
smoothing_buffer_update
|
||||||
|
|
||||||
|
constellation
|
||||||
|
|
||||||
|
decide
|
||||||
|
end
|
||||||
|
|
||||||
|
methods
|
||||||
|
function obj = FFE_DCremoval_adaptive_mu(options)
|
||||||
|
arguments(Input)
|
||||||
|
|
||||||
|
options.sps = 2;
|
||||||
|
options.order = 15;
|
||||||
|
|
||||||
|
options.len_tr = 4096;
|
||||||
|
options.mu_tr = 0;
|
||||||
|
options.epochs_tr = 5;
|
||||||
|
|
||||||
|
options.mu_dd = 1e-5;
|
||||||
|
options.epochs_dd = 5;
|
||||||
|
|
||||||
|
options.mu_dc = 0.05;
|
||||||
|
options.dc_buffer_len = 1;
|
||||||
|
|
||||||
|
options.ffe_buffer_len = 1;
|
||||||
|
|
||||||
|
options.smoothing_buffer_length = 0;
|
||||||
|
options.smoothing_buffer_update = 0;
|
||||||
|
options.decide = false;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(options.dc_buffer_len>0);
|
||||||
|
|
||||||
|
fn = fieldnames(options);
|
||||||
|
for n = 1:numel(fn)
|
||||||
|
obj.(fn{n}) = options.(fn{n});
|
||||||
|
end
|
||||||
|
|
||||||
|
obj.e = zeros(obj.order,1);
|
||||||
|
obj.error = 0;
|
||||||
|
|
||||||
|
obj.dc_buffer_len = floor(obj.dc_buffer_len);
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function [X,Noi] = process(obj, X, D)
|
||||||
|
|
||||||
|
% actual processing of the signal (steps 1. - 3.)
|
||||||
|
% 1 normalize RMS
|
||||||
|
X = X.normalize("mode","rms");
|
||||||
|
|
||||||
|
obj.constellation = unique(D.signal);
|
||||||
|
|
||||||
|
% if obj.smoothing_buffer_length > 0
|
||||||
|
% % Apply A1 filter smoothing
|
||||||
|
% % Calculate the moving sum with the window size N1
|
||||||
|
% moving_sum = movsum(X.signal, [obj.smoothing_buffer_length,0]);
|
||||||
|
%
|
||||||
|
% % Initialize the output smoothed signal
|
||||||
|
% X.signal = X.signal - (1 / obj.smoothing_buffer_length) * moving_sum;
|
||||||
|
% end
|
||||||
|
|
||||||
|
% Training Mode
|
||||||
|
training = 1;
|
||||||
|
obj.equalize(X.signal, D.signal,obj.mu_tr,obj.epochs_tr,obj.len_tr,training);
|
||||||
|
|
||||||
|
% Decision Directed Mode
|
||||||
|
N = X.length;
|
||||||
|
training = 0;
|
||||||
|
[signal,decision]=obj.equalize(X.signal, D.signal,obj.mu_dd,obj.epochs_dd,N,training);
|
||||||
|
|
||||||
|
% Output Signal
|
||||||
|
if obj.decide
|
||||||
|
X.signal = decision;
|
||||||
|
else
|
||||||
|
X.signal = signal;
|
||||||
|
end
|
||||||
|
X.fs = D.fs; %change sampling frequency of outgoing signal from fdac e.g. 2 sps to symbol spaced = fsym
|
||||||
|
lbdesc = [num2str(obj.order),' tap FFE'];
|
||||||
|
X = X.logbookentry(lbdesc); % append to logbook
|
||||||
|
|
||||||
|
Noi = X - D;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function [y,d_hat] = equalize(obj, x, d, mu_lms, epochs, N, training)
|
||||||
|
% Equalize with adaptive DC-removal, VSS, and parallel-buffered DC updates
|
||||||
|
% Added: FFE gradient buffering in DD mode (error buffer) with update every obj.dc_buffer_len symbols
|
||||||
|
|
||||||
|
arguments
|
||||||
|
obj
|
||||||
|
x
|
||||||
|
d
|
||||||
|
mu_lms % LMS step-size (or 0 for NLMS)
|
||||||
|
epochs % number of training/DD epochs
|
||||||
|
N % number of samples to process
|
||||||
|
training % boolean flag: true->training mode, false->DD mode
|
||||||
|
end
|
||||||
|
|
||||||
|
% Zero-padding for filter memory
|
||||||
|
x = [zeros(floor(obj.order/2),1); x; zeros(obj.order,1)];
|
||||||
|
|
||||||
|
% Initialize storage
|
||||||
|
numSymbols = ceil(N/obj.sps);
|
||||||
|
y = zeros(numSymbols,1);
|
||||||
|
d_hat = zeros(numSymbols,1);
|
||||||
|
err = NaN(numSymbols,numel(obj.constellation));
|
||||||
|
e_dc_save= zeros(numSymbols,1);
|
||||||
|
|
||||||
|
% DC-adaptation parameters
|
||||||
|
P_err = 0; % running error power
|
||||||
|
alpha = 0.98; % forgetting factor for error power
|
||||||
|
err_prev = 0; % previous error sample for VSS correlation
|
||||||
|
gamma_dc = 1e-6; % meta step-size for DC VSS
|
||||||
|
mu_min = 1e-6; % lower bound for mu_dc
|
||||||
|
mu_max = 1e-1; % upper bound for mu_dc
|
||||||
|
|
||||||
|
% DC removal buffer
|
||||||
|
L = obj.dc_buffer_len; % buffer length
|
||||||
|
e_dc_buf = NaN(L,1);
|
||||||
|
e_dc_est = 0;
|
||||||
|
|
||||||
|
% FFE gradient buffer (DD mode only)
|
||||||
|
L_grad = obj.ffe_buffer_len; % buffer length
|
||||||
|
if ~training
|
||||||
|
% each column holds one past gradient of length obj.order
|
||||||
|
grad_buf = NaN(obj.order, L_grad);
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
smth_buffer = zeros(1, obj.smoothing_buffer_length);
|
||||||
|
smth_mean = 0;
|
||||||
|
% Main loop
|
||||||
|
for epoch = 1:epochs
|
||||||
|
s = 0;
|
||||||
|
for sample = 1:obj.sps:N
|
||||||
|
s = s + 1;
|
||||||
|
|
||||||
|
if obj.smoothing_buffer_length > 0
|
||||||
|
smth_buffer = circshift(smth_buffer,1,2);
|
||||||
|
smth_buffer(1) = x(sample);
|
||||||
|
if mod(s, obj.smoothing_buffer_update) == 0
|
||||||
|
smth_mean = mean(smth_buffer);
|
||||||
|
end
|
||||||
|
x(sample:sample+obj.sps-1) = x(sample:sample+obj.sps-1)-smth_mean;
|
||||||
|
end
|
||||||
|
|
||||||
|
U = x(obj.order+sample-1:-1:sample);
|
||||||
|
|
||||||
|
%-- 1) filter output with DC correction
|
||||||
|
y(s) = e_dc_est + obj.e.'*U;
|
||||||
|
|
||||||
|
%-- 2) decision
|
||||||
|
if training
|
||||||
|
[~, idx] = min(abs(d(s) - obj.constellation));
|
||||||
|
else
|
||||||
|
[~, idx] = min(abs(y(s) - obj.constellation));
|
||||||
|
end
|
||||||
|
d_hat(s) = obj.constellation(idx);
|
||||||
|
|
||||||
|
%-- 3) error
|
||||||
|
e_val = y(s) - d_hat(s);
|
||||||
|
err(s,idx) = e_val;
|
||||||
|
|
||||||
|
%-- 4) tap-weight update: training immediate, DD buffered
|
||||||
|
if training
|
||||||
|
% immediate update (LMS or NLMS)
|
||||||
|
if mu_lms ~= 0
|
||||||
|
obj.e = obj.e - mu_lms * e_val * U;
|
||||||
|
else
|
||||||
|
normU = (U.'*U) + eps;
|
||||||
|
obj.e = obj.e - e_val * U / normU;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if 1
|
||||||
|
% buffer gradient
|
||||||
|
if mu_lms ~= 0
|
||||||
|
grad = e_val * U;
|
||||||
|
else
|
||||||
|
normU = (U.'*U) + eps;
|
||||||
|
grad = e_val * U / normU;
|
||||||
|
end
|
||||||
|
% shift and insert
|
||||||
|
grad_buf = circshift(grad_buf, 1, 2);
|
||||||
|
grad_buf(:,1) = grad;
|
||||||
|
% update once every L symbols
|
||||||
|
if mod(s, L_grad) == 0
|
||||||
|
avg_grad = mean(grad_buf, 2, 'omitnan');
|
||||||
|
if mu_lms ~= 0
|
||||||
|
obj.e = obj.e - mu_lms * avg_grad;
|
||||||
|
else
|
||||||
|
obj.e = obj.e - avg_grad;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
%-- 5) DC adaptation
|
||||||
|
if obj.mu_dc ~= 0
|
||||||
|
|
||||||
|
% VSS for mu_dc
|
||||||
|
delta_mu = gamma_dc * e_val * err_prev * (U.'*U);
|
||||||
|
obj.mu_dc = min(max(obj.mu_dc + delta_mu, mu_min), mu_max);
|
||||||
|
err_prev = e_val;
|
||||||
|
|
||||||
|
% DC buffer update & periodic estimate
|
||||||
|
P_err = alpha*P_err + (1-alpha)*e_val^2;
|
||||||
|
mu_dc_norm = obj.mu_dc / (P_err + eps);
|
||||||
|
e_dc_buf = circshift(e_dc_buf, 1);
|
||||||
|
e_dc_buf(1) = e_dc_est - mu_dc_norm * e_val;
|
||||||
|
|
||||||
|
if mod(s, L) == 0
|
||||||
|
e_dc_est = median(e_dc_buf, 'omitnan');
|
||||||
|
end
|
||||||
|
|
||||||
|
e_dc_save(s) = e_dc_est;
|
||||||
|
end
|
||||||
|
|
||||||
|
% store instantaneous squared error
|
||||||
|
obj.error(epoch, s) = e_val^2;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
% Optional plotting in DD mode (uncomment if needed)
|
||||||
|
if ~training
|
||||||
|
figure(342);clf
|
||||||
|
hold on
|
||||||
|
scatter(1:numSymbols, err + obj.constellation', '.', 'SizeData', 1);
|
||||||
|
|
||||||
|
yline(obj.constellation);
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function mu = update_mu()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
240
Classes/04_DSP/Equalizer/FFE_DCremoval_level.m
Normal file
240
Classes/04_DSP/Equalizer/FFE_DCremoval_level.m
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
classdef FFE_DCremoval_level < handle
|
||||||
|
% Implementation of plain and simple FFE.
|
||||||
|
% 1) Training mode (stable performance when you use NLMS)
|
||||||
|
% 2) Decision directed mode
|
||||||
|
|
||||||
|
% Eq = FFE("epochs_tr",5,"epochs_dd",5,"len_tr",4096*2,"mu_dd",1e-4,"mu_tr",0,"order",25,"sps",2,"decide",0);
|
||||||
|
|
||||||
|
properties
|
||||||
|
sps % usually 2
|
||||||
|
order
|
||||||
|
e
|
||||||
|
error
|
||||||
|
|
||||||
|
len_tr
|
||||||
|
mu_tr
|
||||||
|
epochs_tr
|
||||||
|
|
||||||
|
mu_dd
|
||||||
|
epochs_dd
|
||||||
|
|
||||||
|
mu_dc
|
||||||
|
dc_buffer_len
|
||||||
|
|
||||||
|
constellation
|
||||||
|
|
||||||
|
decide
|
||||||
|
|
||||||
|
KF_meas_noise = 0;
|
||||||
|
KF_process_noise = 0;
|
||||||
|
KF_state_cov = 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
methods
|
||||||
|
function obj = FFE_DCremoval_level(options)
|
||||||
|
arguments(Input)
|
||||||
|
|
||||||
|
options.sps = 2;
|
||||||
|
options.order = 15;
|
||||||
|
|
||||||
|
options.len_tr = 4096;
|
||||||
|
options.mu_tr = 0;
|
||||||
|
options.epochs_tr = 5;
|
||||||
|
|
||||||
|
options.mu_dd = 1e-5;
|
||||||
|
options.epochs_dd = 5;
|
||||||
|
|
||||||
|
options.mu_dc = 0.05;
|
||||||
|
options.dc_buffer_len = 1;
|
||||||
|
|
||||||
|
options.decide = false;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(options.dc_buffer_len>0);
|
||||||
|
|
||||||
|
fn = fieldnames(options);
|
||||||
|
for n = 1:numel(fn)
|
||||||
|
obj.(fn{n}) = options.(fn{n});
|
||||||
|
end
|
||||||
|
|
||||||
|
obj.e = zeros(obj.order,1);
|
||||||
|
obj.error = 0;
|
||||||
|
|
||||||
|
obj.dc_buffer_len = floor(obj.dc_buffer_len);
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function [X,Noi] = process(obj, X, D)
|
||||||
|
|
||||||
|
% actual processing of the signal (steps 1. - 3.)
|
||||||
|
% 1 normalize RMS
|
||||||
|
X = X.normalize("mode","rms");
|
||||||
|
|
||||||
|
obj.constellation = unique(D.signal);
|
||||||
|
|
||||||
|
% Training Mode
|
||||||
|
training = 1;
|
||||||
|
obj.equalize(X.signal, D.signal,obj.mu_tr,obj.epochs_tr,obj.len_tr,training);
|
||||||
|
|
||||||
|
% Decision Directed Mode
|
||||||
|
N = X.length;
|
||||||
|
training = 0;
|
||||||
|
[signal,decision]=obj.equalize(X.signal, D.signal,obj.mu_dd,obj.epochs_dd,N,training);
|
||||||
|
|
||||||
|
% Output Signal
|
||||||
|
if obj.decide
|
||||||
|
X.signal = decision;
|
||||||
|
else
|
||||||
|
X.signal = signal;
|
||||||
|
end
|
||||||
|
X.fs = D.fs; %change sampling frequency of outgoing signal from fdac e.g. 2 sps to symbol spaced = fsym
|
||||||
|
lbdesc = [num2str(obj.order),' tap FFE'];
|
||||||
|
X = X.logbookentry(lbdesc); % append to logbook
|
||||||
|
|
||||||
|
Noi = X - D;
|
||||||
|
|
||||||
|
end
|
||||||
|
function [y, d_hat, logs] = equalize(obj, x, d, mu_lms, epochs, N, training)
|
||||||
|
% Equalize with Kalman-based DC removal; training epochs estimate KF noise parameters
|
||||||
|
|
||||||
|
arguments
|
||||||
|
obj
|
||||||
|
x
|
||||||
|
d
|
||||||
|
mu_lms % LMS step-size (or 0 for NLMS)
|
||||||
|
epochs % number of training or DD epochs
|
||||||
|
N % number of samples to process
|
||||||
|
training % true => training mode (tap-training + noise estimation)
|
||||||
|
end
|
||||||
|
|
||||||
|
% Zero-pad for filter memory
|
||||||
|
x = [zeros(floor(obj.order/2),1); x; zeros(obj.order,1)];
|
||||||
|
numSym = ceil(N/obj.sps);
|
||||||
|
|
||||||
|
% Pre-allocate outputs
|
||||||
|
y = zeros(numSym,1);
|
||||||
|
d_hat = zeros(numSym,1);
|
||||||
|
|
||||||
|
% --- Training: estimate noise stats and train taps ---
|
||||||
|
if training
|
||||||
|
% Pre-allocate error accumulator
|
||||||
|
totalTrain = epochs * numSym;
|
||||||
|
trainErrs = zeros(totalTrain,1);
|
||||||
|
te_idx = 0;
|
||||||
|
|
||||||
|
for ep = 1:epochs
|
||||||
|
s = 0;
|
||||||
|
for n = 1:obj.sps:N
|
||||||
|
s = s + 1;
|
||||||
|
U = x(obj.order + n - 1 : -1 : n);
|
||||||
|
|
||||||
|
% Equalizer output (no DC correction yet)
|
||||||
|
y(s) = obj.e.' * U;
|
||||||
|
|
||||||
|
% Decision based on known symbol
|
||||||
|
[~, idx] = min(abs(d(s) - obj.constellation));
|
||||||
|
d_hat(s) = obj.constellation(idx);
|
||||||
|
|
||||||
|
% Instantaneous error
|
||||||
|
e_n = y(s) - d_hat(s);
|
||||||
|
|
||||||
|
% Collect error for noise estimation
|
||||||
|
te_idx = te_idx + 1;
|
||||||
|
trainErrs(te_idx) = e_n;
|
||||||
|
|
||||||
|
% Tap-weight update (LMS or NLMS)
|
||||||
|
if mu_lms ~= 0
|
||||||
|
obj.e = obj.e - mu_lms * e_n * U;
|
||||||
|
else
|
||||||
|
normU = (U.'*U) + eps;
|
||||||
|
obj.e = obj.e - e_n * U / normU;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
% Estimate measurement noise R and process noise Q
|
||||||
|
R_est = var(trainErrs(1:te_idx));
|
||||||
|
Q_est = 1e-3 * R_est; % Q/R ratio = 1e-3 (tune as needed)
|
||||||
|
|
||||||
|
% Store into object for DD pass
|
||||||
|
obj.KF_meas_noise = R_est;
|
||||||
|
obj.KF_process_noise = Q_est;
|
||||||
|
obj.KF_state_cov = 5*R_est; % or 5*R_est for a more “eager” start
|
||||||
|
|
||||||
|
% No Kalman in training; return
|
||||||
|
logs = struct();
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
% --- Decision-Directed with Kalman DC tracking ---
|
||||||
|
% Initialize Kalman state
|
||||||
|
x_est = 0;
|
||||||
|
P = obj.KF_state_cov; % initial P (tune in obj; e.g. 1)
|
||||||
|
|
||||||
|
% Logging containers
|
||||||
|
logs.y_raw = zeros(numSym,1);
|
||||||
|
logs.y_corr = zeros(numSym,1);
|
||||||
|
logs.err = zeros(numSym,1);
|
||||||
|
logs.K_gain = zeros(numSym,1);
|
||||||
|
logs.x_est = zeros(numSym,1);
|
||||||
|
logs.P = zeros(numSym,1);
|
||||||
|
logs.normU = zeros(numSym,1);
|
||||||
|
logs.tap_norm = zeros(numSym,1);
|
||||||
|
|
||||||
|
for ep = 1:epochs
|
||||||
|
s = 0;
|
||||||
|
for n = 1:obj.sps:N
|
||||||
|
s = s + 1;
|
||||||
|
U = x(obj.order + n - 1 : -1 : n);
|
||||||
|
|
||||||
|
% 1) Kalman prediction
|
||||||
|
P = P + obj.KF_process_noise;
|
||||||
|
x_prior = x_est;
|
||||||
|
|
||||||
|
% 2) raw equalizer output
|
||||||
|
y_raw = obj.e.' * U;
|
||||||
|
logs.y_raw(s) = y_raw;
|
||||||
|
|
||||||
|
% 3) DC-corrected output
|
||||||
|
y_corr = y_raw + x_prior;
|
||||||
|
y(s) = y_corr;
|
||||||
|
logs.y_corr(s) = y_corr;
|
||||||
|
|
||||||
|
% 4) decision-directed symbol
|
||||||
|
[~, idx] = min(abs(y_corr - obj.constellation));
|
||||||
|
d_hat(s) = obj.constellation(idx);
|
||||||
|
|
||||||
|
% 5) error
|
||||||
|
e_n = y_corr - d_hat(s);
|
||||||
|
logs.err(s) = e_n;
|
||||||
|
|
||||||
|
% 6) tap-weight update (LMS/NLMS)
|
||||||
|
if mu_lms ~= 0
|
||||||
|
obj.e = obj.e - mu_lms * e_n * U;
|
||||||
|
else
|
||||||
|
normU = U.' * U + eps;
|
||||||
|
logs.normU(s) = normU;
|
||||||
|
obj.e = obj.e - e_n * U / normU;
|
||||||
|
end
|
||||||
|
|
||||||
|
logs.tap_norm(s) = norm(obj.e);
|
||||||
|
|
||||||
|
% 7) Kalman update
|
||||||
|
K_gain = P / (P + obj.KF_meas_noise);
|
||||||
|
x_est = x_prior + K_gain * (e_n - x_prior);
|
||||||
|
P = (1 - K_gain) * P;
|
||||||
|
|
||||||
|
% 8) log Kalman state
|
||||||
|
logs.K_gain(s) = K_gain;
|
||||||
|
logs.x_est(s) = x_est;
|
||||||
|
logs.P(s) = P;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ classdef DBHandler < handle
|
|||||||
% Get table names and the first rows of each table to understand the structure
|
% Get table names and the first rows of each table to understand the structure
|
||||||
obj.getTableNames();
|
obj.getTableNames();
|
||||||
obj.getTables();
|
obj.getTables();
|
||||||
obj.getDistinctValues();
|
% obj.getDistinctValues();
|
||||||
end
|
end
|
||||||
|
|
||||||
function obj = getTableNames(obj)
|
function obj = getTableNames(obj)
|
||||||
|
|||||||
@@ -1,129 +1,192 @@
|
|||||||
function [eq_package] = vnle(eq_,M,rx_signal,tx_symbols,tx_bits,options)
|
function [eq_package] = vnle(eq_,M,rx_signal,tx_symbols,tx_bits,options)
|
||||||
%VNLE Apply an equalization algorithm to the received signal and calculate BER
|
|
||||||
% This function takes an equalizer object, a received signal, and the
|
|
||||||
% transmitted symbols to apply equalization, map the received signal back to bits,
|
|
||||||
% and compute the bit error rate (BER).
|
|
||||||
%
|
|
||||||
% Inputs:
|
|
||||||
% EQ - Equalizer object that provides the equalization method
|
|
||||||
% rx_signal - Received signal that needs to be equalized
|
|
||||||
% tx_symbols - Transmitted symbols used as a reference for BER calculation
|
|
||||||
%
|
|
||||||
% Outputs:
|
|
||||||
% eq_signal - Equalized version of the received signal
|
|
||||||
% ber - Bit error rate after equalization
|
|
||||||
% numErrors - Number of bit errors detected
|
|
||||||
|
|
||||||
arguments
|
arguments
|
||||||
eq_
|
eq_
|
||||||
M
|
M
|
||||||
rx_signal
|
rx_signal
|
||||||
tx_symbols
|
tx_symbols
|
||||||
tx_bits
|
tx_bits
|
||||||
options.precode_mode db_mode
|
options.precode_mode db_mode
|
||||||
options.showAnalysis = 0
|
options.showAnalysis = 0;
|
||||||
options.eth_style = 0;
|
options.eth_style_symbol_mapping = 0;
|
||||||
options.postFFE = [];
|
options.postFFE = [];
|
||||||
end
|
options.database = [];
|
||||||
|
end
|
||||||
|
|
||||||
%FFE or VNLE
|
mudc_given = eq_.mu_dc;
|
||||||
if length(rx_signal)/2 == length(tx_symbols)+0.5
|
|
||||||
rx_signal.signal = rx_signal.signal(1:end-1);
|
|
||||||
elseif length(rx_signal)/2 == length(tx_symbols)-1
|
|
||||||
end
|
|
||||||
[eq_signal_sd,eq_noise] = eq_.process(rx_signal,tx_symbols);
|
|
||||||
|
|
||||||
if ~isempty(options.postFFE)
|
%FFE or VNLE
|
||||||
[eq_signal_sd,eq_noise] = options.postFFE.process(eq_signal_sd,tx_symbols);
|
[eq_signal_sd,eq_noise] = eq_.process(rx_signal,tx_symbols);
|
||||||
end
|
|
||||||
|
|
||||||
eq_signal_hd = PAMmapper(M,0).quantize(eq_signal_sd);
|
if ~isempty(options.postFFE)
|
||||||
|
tic
|
||||||
|
[eq_signal_sd,eq_noise] = options.postFFE.process(eq_signal_sd,tx_symbols);
|
||||||
|
toc
|
||||||
|
end
|
||||||
|
|
||||||
% precoding to mitigate error propagation, most prominently used in
|
eq_signal_hd = PAMmapper(M,0).quantize(eq_signal_sd);
|
||||||
% combination with duobinary signaling to avoid catastrophic error
|
|
||||||
% behavior (see J.W.M. Bergmans, Digital Baseband Transmission and Recording -> partial response signaling)
|
|
||||||
|
|
||||||
% takes:
|
% precoding to mitigate error propagation, most prominently used in
|
||||||
% -> eq_signal_hd: hard decision signal after eq
|
% combination with duobinary signaling to avoid catastrophic error
|
||||||
% -> tx_symbols: that where used as reference for eq
|
% behavior (see J.W.M. Bergmans, Digital Baseband Transmission and Recording -> partial response signaling)
|
||||||
|
|
||||||
switch options.precode_mode
|
switch options.precode_mode
|
||||||
case db_mode.db_emulate
|
|
||||||
% re
|
case db_mode.no_db
|
||||||
eq_signal_hd = Duobinary().encode(eq_signal_hd,"M",M);
|
% TX Data is not precoded:
|
||||||
eq_signal_hd = Duobinary().decode(eq_signal_hd,"M",M);
|
|
||||||
|
% A) Emulate diff precoding
|
||||||
|
eq_signal_hd_precoded = Duobinary().encode(eq_signal_hd,"M",M);
|
||||||
|
eq_signal_hd_precoded = Duobinary().decode(eq_signal_hd_precoded,"M",M);
|
||||||
|
|
||||||
tx_symbols_precoded = Duobinary().encode(tx_symbols);
|
tx_symbols_precoded = Duobinary().encode(tx_symbols);
|
||||||
tx_symbols_precoded = Duobinary().decode(tx_symbols_precoded);
|
tx_symbols_precoded = Duobinary().decode(tx_symbols_precoded);
|
||||||
|
|
||||||
tx_bits = PAMmapper(M,0,"eth_style",options.eth_style).demap(tx_symbols_precoded);
|
tx_bits_precoded = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(tx_symbols_precoded);
|
||||||
|
|
||||||
case db_mode.db_discard
|
rx_bits_vnle = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(eq_signal_hd_precoded);
|
||||||
|
[~,errors_vnle_diff_precoded,ber_vnle_diff_precoded,~] = calc_ber(rx_bits_vnle.signal,tx_bits_precoded.signal,"skip_front",30000,"skip_end",150,"returnErrorLocation",1);
|
||||||
|
|
||||||
% normal dsp for precoded sequence == discard/omit/ignore precode
|
%B) Just determine BER
|
||||||
tx_bits = PAMmapper(M,0).demap(tx_symbols);
|
rx_bits_vnle = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(eq_signal_hd);
|
||||||
|
[bits_vnle,errors_vnle,ber_vnle,error_pos_vnle] = calc_ber(rx_bits_vnle.signal,tx_bits.signal,"skip_front",30000,"skip_end",150,"returnErrorLocation",1);
|
||||||
|
|
||||||
case db_mode.db_encoded
|
max_burst_length = 10;
|
||||||
|
burst_count = count_error_bursts(error_pos_vnle, max_burst_length);
|
||||||
|
|
||||||
% normal DB encoded data (only for 10KM)
|
case db_mode.db_precoded
|
||||||
|
|
||||||
case db_mode.db_precoded
|
% Daten SIND TATSÄCHLICH precoded auf TX Seite:
|
||||||
|
|
||||||
eq_signal_hd = Duobinary().encode(eq_signal_hd,"M",M);
|
% A) Decode at Rx if no DB targeting was applied (we are in VNLE or MLSE EQ structure here!
|
||||||
eq_signal_hd = Duobinary().decode(eq_signal_hd,"M",M);
|
eq_signal_hd_decoded = Duobinary().encode(eq_signal_hd,"M",M);
|
||||||
|
eq_signal_hd_decoded = Duobinary().decode(eq_signal_hd_decoded,"M",M);
|
||||||
|
rx_bits_vnle_decoded = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(eq_signal_hd_decoded);
|
||||||
|
[~,errors_vnle_diff_precoded,ber_vnle_diff_precoded,~] = calc_ber(rx_bits_vnle_decoded.signal,tx_bits.signal,"skip_front",30000,"skip_end",150,"returnErrorLocation",1);
|
||||||
|
|
||||||
end
|
% B) Omit the Coding by comparing with demapped TX symbol sequence
|
||||||
|
|
||||||
rx_bits = PAMmapper(M,0,"eth_style",options.eth_style).demap(eq_signal_hd);
|
tx_bits = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(tx_symbols);
|
||||||
|
rx_bits_vnle = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(eq_signal_hd);
|
||||||
|
[bits_vnle,errors_vnle,ber_vnle,~] = calc_ber(rx_bits_vnle.signal,tx_bits.signal,"skip_front",30000,"skip_end",150,"returnErrorLocation",1);
|
||||||
|
|
||||||
[~,numErrors,ber,~] = calc_ber(rx_bits.signal,tx_bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
|
||||||
[evm_total,evm_lvl] = calc_evm(eq_signal_sd,tx_symbols);
|
|
||||||
[inf_rate] = calc_air(eq_signal_sd,tx_symbols,"skip_front",10000,"skip_end",10000);
|
|
||||||
|
|
||||||
|
|
||||||
eq_package.ber_vnle = ber;
|
|
||||||
eq_package.evm_total = evm_total;
|
|
||||||
eq_package.evm_lvl = evm_lvl;
|
|
||||||
eq_package.inf_rate_vnle = inf_rate;
|
|
||||||
eq_package.snr = snr(eq_signal_sd.signal,eq_noise.signal);
|
|
||||||
|
|
||||||
eq_package.signal = eq_signal_sd;
|
|
||||||
|
|
||||||
|
|
||||||
if options.showAnalysis
|
|
||||||
|
|
||||||
fprintf('SNR: %d dB \n',snr(eq_signal_sd.signal,eq_noise.signal));
|
|
||||||
|
|
||||||
if M == 6
|
|
||||||
logm = 2.5;
|
|
||||||
else
|
|
||||||
logm = log2(M);
|
|
||||||
end
|
|
||||||
|
|
||||||
fprintf('NGMI: %.4f \n', inf_rate/logm);
|
|
||||||
|
|
||||||
fprintf(['VNLE EVM lvl: ',repmat('%.3f ',1,numel(evm_lvl)),' \n'],evm_lvl);
|
|
||||||
|
|
||||||
fprintf('VNLE BER: %.2e \n',ber);
|
|
||||||
|
|
||||||
disp("%%%%%%%%%%%%%%%%%%%%%")
|
|
||||||
|
|
||||||
% showEQcoefficients('n1',eq_.e,'n2',eq_.e2,'n3',eq_.e3,"displayname",'Coefficients');
|
|
||||||
%
|
|
||||||
% if ~isempty(options.postFFE)
|
|
||||||
% showEQcoefficients('n1',options.postFFE.e,"displayname",'Coefficients');
|
|
||||||
% end
|
|
||||||
%
|
|
||||||
% showEQNoisePSD(eq_noise);
|
|
||||||
%
|
|
||||||
% showEQfilter(eq_.e,eq_signal_sd.fs.*2)
|
|
||||||
|
|
||||||
% noiselessness(tx_symbols,eq_noise,"displayname",'SNR after VNLE','fignum',301);
|
|
||||||
|
|
||||||
% showLevelHistogram(eq_signal_sd,tx_symbols,"fignum",302);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
% METRICS OF VNLE SD Signal:
|
||||||
|
[snr_vnle,snr_vnle_lvl] = calc_snr(tx_symbols.signal,eq_noise.signal);
|
||||||
|
[gmi_vnle] = calc_air(eq_signal_sd,tx_symbols,"skip_front",10000,"skip_end",10000);
|
||||||
|
air_vnle = tx_symbols.fs .* floor(log2(double(M))*10)/10 .* gmi_vnle ./ log2(double(M));
|
||||||
|
[evm_vnle_total,evm_vnle_lvl] = calc_evm(eq_signal_sd,tx_symbols);
|
||||||
|
[std_vnle_total,std_vnle_lvl] = calc_std(eq_signal_sd,tx_symbols);
|
||||||
|
[std_rxraw_total,std_rxraw_lvl] = calc_std(rx_signal.resample("fs_out",tx_symbols.fs),tx_symbols);
|
||||||
|
|
||||||
|
eq_package.ber_vnle = ber_vnle;
|
||||||
|
eq_package.evm_vnle_total = evm_vnle_total;
|
||||||
|
eq_package.evm_vnle_lvl = evm_vnle_lvl;
|
||||||
|
eq_package.gmi = gmi_vnle;
|
||||||
|
|
||||||
|
eq_package.eq = eq_;
|
||||||
|
|
||||||
|
resultsVNLE = struct( ...
|
||||||
|
'result_id', NaN, ... %
|
||||||
|
'run_id', NaN, ... % Beispielhafte Run-ID
|
||||||
|
'eqParam_id', NaN, ... % Beispielhafter Fremdschlüssel zur EqualizerParameters-Tabelle
|
||||||
|
'date_of_processing', datetime('now'), ... % Aktuelles Datum und Uhrzeit
|
||||||
|
'BER', ber_vnle, ... % BER = 120 / 1.000.000
|
||||||
|
'numBits', bits_vnle, ... % Beispiel: 1.000.000 Bits
|
||||||
|
'numBitErr', errors_vnle, ... % Beispiel: 120 Bitfehler
|
||||||
|
'BER_precoded', ber_vnle_diff_precoded, ... % BER = 120 / 1.000.000
|
||||||
|
'numBitErr_precoded', errors_vnle_diff_precoded, ... % Beispiel: 120 Bitfehler
|
||||||
|
'SNR', snr_vnle, ... % Beispielhafte SNR
|
||||||
|
'SNR_level', jsonencode(snr_vnle_lvl), ... % SNR-Level als JSON-codiertes Array
|
||||||
|
'STD', std_vnle_total, ...
|
||||||
|
'STD_level', jsonencode(std_vnle_lvl),...
|
||||||
|
'STDrx' , std_rxraw_total, ...
|
||||||
|
'STDrx_level', jsonencode(std_rxraw_lvl),...
|
||||||
|
'GMI', gmi_vnle, ... % Beispielhafter GMI-Wert
|
||||||
|
'AIR', air_vnle, ... % Beispielhafter AIR-Wert
|
||||||
|
'EVM', evm_vnle_total, ... % Beispielhafte EVM
|
||||||
|
'EVM_level', jsonencode(evm_vnle_lvl), ... % EVM-Level als JSON-codiertes Array
|
||||||
|
'Alpha', [] ... % Beispielhafter Alpha-Wert
|
||||||
|
);
|
||||||
|
|
||||||
|
if ~isempty(options.postFFE)
|
||||||
|
npostFFE = options.postFFE.order;
|
||||||
|
else
|
||||||
|
npostFFE = 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
equalizerConfigVNLE = struct( ...
|
||||||
|
'eq_id', NaN, ... % Auto-Inkrement, wird in der DB gesetzt
|
||||||
|
'equalizer_structure', int32(equalizer_structure.vnle), ... % Beispiel: 1 (z.B. für vnle)
|
||||||
|
'M', M, ... % Ordnung der PAM-Konstellation
|
||||||
|
'target_constellation', jsonencode(round(unique(tx_symbols.signal),5)), ... % Beispielhafter Target-String
|
||||||
|
'db_target', 0, ... % 0 oder 1
|
||||||
|
'diff_precode', int32(options.precode_mode), ... % 0 oder 1
|
||||||
|
'postFFE', int32(~isempty(options.postFFE)), ... % Beispielwert
|
||||||
|
'NpostFFE', npostFFE, ... % Beispielwert
|
||||||
|
'Ne1', eq_.order, ... % Feedforward Koeffizienten 1. Ordnung
|
||||||
|
'K', eq_.sps, ... % Samples pro Symbol
|
||||||
|
'DCmu', mudc_given, ... % Anpassungsrate für DC-Tap
|
||||||
|
'training_length', eq_.len_tr, ... % Anzahl Trainingssymbole
|
||||||
|
'training_loops', eq_.epochs_tr, ... % Anzahl Trainingsdurchläufe
|
||||||
|
'TRmu1', eq_.mu_tr, ... % mu für DD-Modus (1. Ordnung)
|
||||||
|
'dd_loops', eq_.epochs_dd, ... % Anzahl Durchläufe im DD-Modus
|
||||||
|
'DDmu1', eq_.mu_dd, ... % mu für DD-Modus (1. Ordnung)
|
||||||
|
'comment', 'function: ffe dc removal', ... % Zusätzliche Kommentare
|
||||||
|
'ffe_buffer_len', eq_.ffe_buffer_len, ...
|
||||||
|
'smoothing_buffer_len', eq_.smoothing_buffer_length, ...
|
||||||
|
'smoothing_buffer_update', eq_.smoothing_buffer_update, ...
|
||||||
|
'dc_buffer_len', eq_.dc_buffer_len, ...
|
||||||
|
'config_hash', NaN ...
|
||||||
|
);
|
||||||
|
|
||||||
|
eq_package.resultsVNLE = resultsVNLE;
|
||||||
|
eq_package.equalizerConfigVNLE = equalizerConfigVNLE;
|
||||||
|
|
||||||
|
|
||||||
|
% eq_package.vnle_out = eq_signal_sd;
|
||||||
|
if options.showAnalysis
|
||||||
|
|
||||||
|
|
||||||
|
% fprintf(['VNLE EVM lvl: ',repmat('%.3f ',1,numel(evm_lvl)),' \n'],evm_lvl);
|
||||||
|
|
||||||
|
% fprintf('VNLE BER: %.2e \n',ber_vnle);
|
||||||
|
%
|
||||||
|
% fprintf('MLSE BER: %.2e \n',ber_mlse);
|
||||||
|
|
||||||
|
figure(336);
|
||||||
|
showEQNoisePSD(eq_noise,"fignum",336,"displayname",'Residual Noise after VNLE');
|
||||||
|
|
||||||
|
% figure(337);clf;
|
||||||
|
% rx_signal.spectrum("normalizeTo0dB",1,"fignum",337,"displayname",'Rx Signal');
|
||||||
|
|
||||||
|
% figure(338);clf;
|
||||||
|
% showEQcoefficients('n1',eq_.e,'n2',eq_.e2,'n3',eq_.e3,"displayname",'Coefficients','fignum',338);
|
||||||
|
|
||||||
|
if ~isempty(options.postFFE)
|
||||||
|
showEQcoefficients('n1',options.postFFE.e,"displayname",'Coefficients','fignum',338);
|
||||||
|
end
|
||||||
|
|
||||||
|
showEQfilter(eq_.e,eq_signal_sd.fs.*2);
|
||||||
|
|
||||||
|
% figure(340);clf;
|
||||||
|
% eq_signal_sd.eye(eq_signal_sd.fs,M,"fignum",340);
|
||||||
|
|
||||||
|
figure(341);clf;
|
||||||
|
showLevelHistogram(eq_signal_sd,tx_symbols,"fignum",341);
|
||||||
|
|
||||||
|
figure(400);clf;
|
||||||
|
warning off
|
||||||
|
showLevelScatter(eq_signal_sd,tx_symbols,"fignum",400);
|
||||||
|
|
||||||
|
showLevelScatter(rx_signal.resample("fs_out",tx_symbols.fs),tx_symbols,"fignum",400);
|
||||||
|
warning on
|
||||||
|
% autoArrangeFigures(3,3,2)
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ end
|
|||||||
air_vnle = tx_symbols.fs .* floor(log2(double(M))*10)/10 .* gmi_vnle ./ log2(double(M));
|
air_vnle = tx_symbols.fs .* floor(log2(double(M))*10)/10 .* gmi_vnle ./ log2(double(M));
|
||||||
[evm_vnle_total,evm_vnle_lvl] = calc_evm(eq_signal_sd,tx_symbols);
|
[evm_vnle_total,evm_vnle_lvl] = calc_evm(eq_signal_sd,tx_symbols);
|
||||||
[std_vnle_total,std_vnle_lvl] = calc_std(eq_signal_sd,tx_symbols);
|
[std_vnle_total,std_vnle_lvl] = calc_std(eq_signal_sd,tx_symbols);
|
||||||
[std_rxraw_total,std_rxraw_lvl] = calc_std(rx_signal.resample("fs_out",tx_symbols.fs),tx_symbols);
|
[std_rxraw_total,std_rxraw_lvl] = calc_std(rx_signal.resample("fs_out",tx_symbols.fs),tx_symbols);
|
||||||
|
|
||||||
% METRICS OF MLSE (HD-VITERBI)
|
% METRICS OF MLSE (HD-VITERBI)
|
||||||
pf_.ncoeff = 1;
|
pf_.ncoeff = 1;
|
||||||
@@ -252,7 +252,7 @@ if options.showAnalysis
|
|||||||
%
|
%
|
||||||
% fprintf('MLSE BER: %.2e \n',ber_mlse);
|
% fprintf('MLSE BER: %.2e \n',ber_mlse);
|
||||||
|
|
||||||
figure(336);clf;
|
figure(336);
|
||||||
showEQNoisePSD(eq_noise,"fignum",336,"displayname",'Residual Noise after VNLE','postfilter_taps',pf_.coefficients);
|
showEQNoisePSD(eq_noise,"fignum",336,"displayname",'Residual Noise after VNLE','postfilter_taps',pf_.coefficients);
|
||||||
|
|
||||||
% figure(337);clf;
|
% figure(337);clf;
|
||||||
@@ -273,9 +273,12 @@ if options.showAnalysis
|
|||||||
figure(341);clf;
|
figure(341);clf;
|
||||||
showLevelHistogram(eq_signal_sd,tx_symbols,"fignum",341);
|
showLevelHistogram(eq_signal_sd,tx_symbols,"fignum",341);
|
||||||
|
|
||||||
|
warning off
|
||||||
showLevelScatter(eq_signal_sd,tx_symbols,"fignum",400);
|
showLevelScatter(eq_signal_sd,tx_symbols,"fignum",400);
|
||||||
|
|
||||||
showLevelScatter(rx_signal.resample("fs_out",tx_symbols.fs),tx_symbols,"fignum",401);
|
showLevelScatter(rx_signal.resample("fs_out",tx_symbols.fs),tx_symbols,"fignum",401);
|
||||||
|
warning on
|
||||||
|
drawnow;
|
||||||
|
|
||||||
% autoArrangeFigures(3,3,2)
|
% autoArrangeFigures(3,3,2)
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ if isnan(options.fignum)
|
|||||||
fig = figure; % Create a new figure and get its handle
|
fig = figure; % Create a new figure and get its handle
|
||||||
else
|
else
|
||||||
fig = figure(options.fignum); % Use the specified figure number
|
fig = figure(options.fignum); % Use the specified figure number
|
||||||
clf;
|
|
||||||
end
|
end
|
||||||
|
|
||||||
assert(~isempty(options.f_sym),'No fsym given');
|
assert(~isempty(options.f_sym),'No fsym given');
|
||||||
@@ -40,7 +39,7 @@ ende = length(correct_symbols);
|
|||||||
% start = 30000;
|
% start = 30000;
|
||||||
% ende = 40000;
|
% ende = 40000;
|
||||||
|
|
||||||
for l = 1:4
|
for l = 1:numel(levels)
|
||||||
ccnt = ccnt+2;
|
ccnt = ccnt+2;
|
||||||
|
|
||||||
level_amplitude = levels(l);
|
level_amplitude = levels(l);
|
||||||
@@ -50,23 +49,24 @@ for l = 1:4
|
|||||||
std_lvl(l) = std(symbols_for_lvl,'omitnan');
|
std_lvl(l) = std(symbols_for_lvl,'omitnan');
|
||||||
xax_in_sec = ((1:length(correct_symbols)) / f_sym) * 1e6;
|
xax_in_sec = ((1:length(correct_symbols)) / f_sym) * 1e6;
|
||||||
% xax_in_sec = 1:length(correct_symbols);
|
% xax_in_sec = 1:length(correct_symbols);
|
||||||
|
if 0
|
||||||
scatter(xax_in_sec(start:ende),symbols_for_lvl(start:ende),10,'.','MarkerFaceAlpha',0.5,'MarkerEdgeAlpha',0.5,'MarkerEdgeColor',col(ccnt,:));
|
scatter(xax_in_sec(start:ende),symbols_for_lvl(start:ende),10,'.','MarkerFaceAlpha',0.5,'MarkerEdgeAlpha',0.5,'MarkerEdgeColor',col(ccnt,:));
|
||||||
hold on;
|
hold on;
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
std_lvl = round(std_lvl,2);
|
std_lvl = round(std_lvl,2);
|
||||||
|
|
||||||
ccnt = 0;
|
ccnt = 0;
|
||||||
|
|
||||||
% Add the windowed/ smoothed curves
|
% Add the windowed/ smoothed curves
|
||||||
for l = 1:4
|
for l = 1:numel(levels)
|
||||||
ccnt = ccnt+2;
|
ccnt = ccnt+2;
|
||||||
level_amplitude = levels(l);
|
level_amplitude = levels(l);
|
||||||
|
|
||||||
symbols_for_lvl = NaN(1,length(correct_symbols));
|
symbols_for_lvl = NaN(1,length(correct_symbols));
|
||||||
|
|
||||||
movmean = 1/250 .* movsum(rx_symbols(correct_symbols==level_amplitude),[250/2,250/2]);
|
movmean = 1/250 .* movsum(rx_symbols(correct_symbols==level_amplitude),[250/2,250/2], 'Endpoints', 'fill');
|
||||||
|
|
||||||
symbols_for_lvl(correct_symbols==level_amplitude) = movmean;
|
symbols_for_lvl(correct_symbols==level_amplitude) = movmean;
|
||||||
|
|
||||||
|
|||||||
29
Functions/Metrics/count_error_bursts.m
Normal file
29
Functions/Metrics/count_error_bursts.m
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
function burst_count = count_error_bursts(err_pos, max_burst_length)
|
||||||
|
% err_pos: Vector of error positions
|
||||||
|
% max_burst_length: Maximum length for which bursts are counted (e.g., 10)
|
||||||
|
|
||||||
|
% Sort the error positions to ensure they're in increasing order
|
||||||
|
err_pos = sort(err_pos);
|
||||||
|
|
||||||
|
% Initialize burst_count array to hold the counts for each burst length
|
||||||
|
burst_count = zeros(1, max_burst_length);
|
||||||
|
|
||||||
|
% Find the differences between consecutive error positions
|
||||||
|
diffs = diff(err_pos);
|
||||||
|
|
||||||
|
% Find the start of the bursts (where the difference is greater than 1)
|
||||||
|
burst_starts = [1, find(diffs > 1) + 1]; % Starts at index 1 and after gaps
|
||||||
|
burst_ends = [find(diffs > 1), length(err_pos)]; % Ends where gaps are
|
||||||
|
|
||||||
|
% Loop over the bursts
|
||||||
|
for b = 1:length(burst_starts)
|
||||||
|
burst_length = burst_ends(b) - burst_starts(b) + 1;
|
||||||
|
|
||||||
|
% Check if the burst length exceeds any of the thresholds
|
||||||
|
for i = 1:max_burst_length
|
||||||
|
if burst_length > i
|
||||||
|
burst_count(i) = burst_count(i) + 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
63
projects/ECOC_2025/dsp_loop_id.m
Normal file
63
projects/ECOC_2025/dsp_loop_id.m
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
savePath = 'Z:\2025\ECOC Silas\ecoc_2025\';
|
||||||
|
databasePath = 'C:\Users\Silas\Documents\MATLAB\imdd_simulation\projects\ECOC_2025\';
|
||||||
|
database_name = 'ecoc2025_loops.db';
|
||||||
|
db = DBHandler("type","mysql");
|
||||||
|
% db = DBHandler("pathToDB", [databasePath, database_name],"type","sqlite");
|
||||||
|
|
||||||
|
filterParams = db.tables;
|
||||||
|
% filterParams.Configurations = struct('run_id', run_id);
|
||||||
|
filterParams.Configurations = struct( ...
|
||||||
|
'symbolrate', 112e9, ... %[224,336,360,390,420,448]
|
||||||
|
'fiber_length', 0, ...
|
||||||
|
'db_mode', '"no_db"', ...
|
||||||
|
'interference_attenuation', [], ...
|
||||||
|
'interference_path_length', 10, ...
|
||||||
|
'is_mpi', 1, ...
|
||||||
|
'pam_level', 4, ...
|
||||||
|
'wavelength', 1310, ...
|
||||||
|
'precomp_amp', [], ...
|
||||||
|
'signal_attenuation', [], ...
|
||||||
|
'v_awg', [], ...
|
||||||
|
'v_bias', 2.65 ...
|
||||||
|
);
|
||||||
|
|
||||||
|
selectedFields = {'Runs.run_id','Runs.loop_id','Runs.tx_bits_path','Runs.tx_signal_path','Runs.tx_symbols_path','Runs.rx_sync_path','Runs.rx_raw_path',...
|
||||||
|
'Configurations.db_mode','Configurations.pam_level','Configurations.bitrate','Configurations.symbolrate','Configurations.fiber_length','Configurations.wavelength','Configurations.precomp_amp','Measurements.power_rop','Configurations.v_bias',...
|
||||||
|
'Configurations.interference_attenuation', 'Configurations.interference_path_length'};
|
||||||
|
|
||||||
|
[dataTable,sql_query] = db.queryDB(filterParams, selectedFields);
|
||||||
|
|
||||||
|
dataTable(dataTable.loop_id~=217,:) = [];
|
||||||
|
|
||||||
|
num_occ = 10;
|
||||||
|
run_par = true;
|
||||||
|
run_id = dataTable.run_id;
|
||||||
|
|
||||||
|
params.dc_buffer_len = 224;
|
||||||
|
params.ffe_buffer_len = 1;
|
||||||
|
params.smoothing_buffer_length = 0;
|
||||||
|
params.smoothing_buffer_update = 0;
|
||||||
|
params.mu_dc = 0.005;
|
||||||
|
|
||||||
|
futures_list = parallel.FevalFuture.empty();
|
||||||
|
for id = 1:length(dataTable.run_id)
|
||||||
|
run_id = dataTable.run_id(id);
|
||||||
|
[out, futures_list(id)] = submit_dsp(run_id, databasePath, database_name, savePath,"parallel",run_par,'max_occurences',num_occ,'paramstruct',params);
|
||||||
|
end
|
||||||
|
|
||||||
|
% Extract all ber_mlse values from the vnle_pf_package using cellfun
|
||||||
|
ber_mlse = cellfun(@(pkg) pkg.ber_mlse, future.OutputArguments{1,1}.vnle_pf_package);
|
||||||
|
ber_vnle = cellfun(@(pkg) pkg.ber_vnle, future.OutputArguments{1,1}.vnle_pf_package);
|
||||||
|
|
||||||
|
figure(101)
|
||||||
|
hold on;
|
||||||
|
scatter(1:num_occ,ber_mlse,15,'Marker','*');
|
||||||
|
scatter(1:num_occ,ber_vnle,15,'Marker','*');
|
||||||
|
legend('Interpreter', 'latex');
|
||||||
|
xlabel('Occurences');
|
||||||
|
ylabel('BER');
|
||||||
|
grid on;
|
||||||
|
beautifyBERplot;
|
||||||
@@ -48,15 +48,14 @@ mu_ffe3 = 0.001;
|
|||||||
mu_dfe = 0.0004;
|
mu_dfe = 0.0004;
|
||||||
mu_dc = 0.00;
|
mu_dc = 0.00;
|
||||||
|
|
||||||
% mu_ffe1 = 0;
|
|
||||||
% mu_ffe2 = 0;
|
|
||||||
% mu_ffe3 = 0;
|
|
||||||
% mu_dfe =0;
|
|
||||||
% mu_dc = 0.00;
|
|
||||||
|
|
||||||
mu_ffe = [mu_ffe1 mu_ffe2 mu_ffe3];
|
mu_ffe = [mu_ffe1 mu_ffe2 mu_ffe3];
|
||||||
vnle_order=[vnle_order1,vnle_order2,vnle_order3];
|
vnle_order=[vnle_order1,vnle_order2,vnle_order3];
|
||||||
|
|
||||||
|
dc_buffer_len = 224;
|
||||||
|
ffe_buffer_len = 1;
|
||||||
|
smoothing_buffer_length = 4096;
|
||||||
|
smoothing_buffer_update = 224;
|
||||||
|
|
||||||
% Overwrite default parameters if given in options.parameters
|
% Overwrite default parameters if given in options.parameters
|
||||||
paramStruct = options.parameters;
|
paramStruct = options.parameters;
|
||||||
if ~isempty(paramStruct)
|
if ~isempty(paramStruct)
|
||||||
@@ -78,7 +77,7 @@ eq_post = FFE("epochs_tr",5,"epochs_dd",5,"len_tr",4096*2,"mu_dd",1e-4,"mu_tr",0
|
|||||||
|
|
||||||
output = struct();
|
output = struct();
|
||||||
vnle_pf_package = {};
|
vnle_pf_package = {};
|
||||||
vnle_dfe_package = {};
|
vnle_package = {};
|
||||||
dbtgt_package = {};
|
dbtgt_package = {};
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
@@ -121,7 +120,7 @@ if ~found_sync
|
|||||||
end
|
end
|
||||||
|
|
||||||
record_realizations = min(options.max_occurences,length(Scpe_cell));
|
record_realizations = min(options.max_occurences,length(Scpe_cell));
|
||||||
for occ = 1:record_realizations
|
for occ = 4:record_realizations
|
||||||
|
|
||||||
Scpe_sig = Scpe_cell{occ};
|
Scpe_sig = Scpe_cell{occ};
|
||||||
|
|
||||||
@@ -137,16 +136,27 @@ for occ = 1:record_realizations
|
|||||||
|
|
||||||
if duob_mode ~= db_mode.db_encoded
|
if duob_mode ~= db_mode.db_encoded
|
||||||
|
|
||||||
vnle_pf = 1;
|
vnle_pf = 0;
|
||||||
dbtgt = 0;
|
dbtgt = 0;
|
||||||
% %%%%% VNLE + DFE %%%%
|
% %%%%% VNLE + DFE %%%%
|
||||||
if 0
|
if 1
|
||||||
|
|
||||||
eq_vnle_dfe = EQ("Ne",vnle_order,"Nb",[0,0,0],"training_length",len_tr,"training_loops",5,"dd_loops",5,"K",2,"DCmu",mu_dc,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",0);
|
eq_ = FFE_DCremoval_adaptive_mu("epochs_tr",5,"epochs_dd",3,"len_tr",4096*2,"mu_dd",...
|
||||||
eq_post = FFE("epochs_tr",5,"epochs_dd",5,"len_tr",4096*2,"mu_dd",1e-4,"mu_tr",0,"order",2001,"sps",1,"decide",0);
|
0.0002,"mu_tr",0,"order",25,"sps",2,"decide",0,...
|
||||||
|
"mu_dc",mu_dc,...
|
||||||
|
"dc_buffer_len",dc_buffer_len, ...
|
||||||
|
"ffe_buffer_len",ffe_buffer_len,...
|
||||||
|
"smoothing_buffer_length",smoothing_buffer_length,...
|
||||||
|
"smoothing_buffer_update",smoothing_buffer_update);
|
||||||
|
|
||||||
[result] = vnle(eq_vnle_dfe,M,Scpe_sig,Symbols,Tx_bits,"precode_mode",duob_mode,"showAnalysis",1,"postFFE",[]);
|
result = vnle(eq_,M,Scpe_sig,Symbols,Tx_bits,"precode_mode",duob_mode,'showAnalysis',1,"postFFE",[],"eth_style_symbol_mapping",0);
|
||||||
vnle_dfe_package{occ} = result;
|
vnle_package{occ} = result;
|
||||||
|
fprintf("FFE Results: %.2e\n", result.ber_vnle);
|
||||||
|
|
||||||
|
|
||||||
|
if options.append_to_db
|
||||||
|
database.addProcessingResult(run_id, result.resultsVNLE, result.equalizerConfigVNLE);
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -176,32 +186,32 @@ for occ = 1:record_realizations
|
|||||||
% % fprintf("BER VNLE: %.2e | %.2e; BER MLSE: %.2e | %.2e \n",vnle_pf_package{occ}.resultsVNLE.BER,vnle_pf_package{occ}.resultsVNLE.BER_precoded ,vnle_pf_package{occ}.resultsMLSE.BER,vnle_pf_package{occ}.resultsMLSE.BER_precoded);
|
% % fprintf("BER VNLE: %.2e | %.2e; BER MLSE: %.2e | %.2e \n",vnle_pf_package{occ}.resultsVNLE.BER,vnle_pf_package{occ}.resultsVNLE.BER_precoded ,vnle_pf_package{occ}.resultsMLSE.BER,vnle_pf_package{occ}.resultsMLSE.BER_precoded);
|
||||||
|
|
||||||
if vnle_pf
|
if vnle_pf
|
||||||
occ = 1; % or whatever your loop index is
|
% occ = 1; % or whatever your loop index is
|
||||||
|
|
||||||
|
|
||||||
% Extract VNLE results for readability
|
% Extract VNLE results for readability
|
||||||
vnle = vnle_pf_package{occ}.resultsVNLE;
|
vnle_result = vnle_pf_package{occ}.resultsVNLE;
|
||||||
mlse = vnle_pf_package{occ}.resultsMLSE;
|
mlse_result = vnle_pf_package{occ}.resultsMLSE;
|
||||||
|
|
||||||
|
|
||||||
% Print header
|
% Print header
|
||||||
fprintf("==== EQUALIZATION RUN-ID %d | PAM-%d | %.2f GBd ====\n\n", run_id, M, Symbols.fs.*1e-9);
|
fprintf("==== EQUALIZATION RUN-ID %d | PAM-%d | %.2f GBd ====\n\n", run_id, M, Symbols.fs.*1e-9);
|
||||||
|
s
|
||||||
% VNLE Results
|
% VNLE Results
|
||||||
fprintf(">> VNLE Results:\n");
|
fprintf(">> VNLE Results:\n");
|
||||||
fprintf(" BER %.2e\n", vnle.BER);
|
fprintf(" BER %.2e\n", vnle_result.BER);
|
||||||
fprintf(" BER (pre-code) %.2e\n", vnle.BER_precoded);
|
fprintf(" BER (pre-code) %.2e\n", vnle_result.BER_precoded);
|
||||||
fprintf(" SNR: %.2f dB\n", vnle.SNR);
|
fprintf(" SNR: %.2f dB\n", vnle_result.SNR);
|
||||||
fprintf(" GMI: %.4f\n", vnle.GMI);
|
fprintf(" GMI: %.4f\n", vnle_result.GMI);
|
||||||
fprintf(" Linerate: %.2f Gbps\n", Symbols.fs .* floor(log2(M)*10)/10 .*1e-9);
|
fprintf(" Linerate: %.2f Gbps\n", Symbols.fs .* floor(log2(M)*10)/10 .*1e-9);
|
||||||
fprintf(" AIR: %.2f Gbps\n", vnle.AIR.*1e-9);
|
fprintf(" AIR: %.2f Gbps\n", vnle_result.AIR.*1e-9);
|
||||||
fprintf("\n");
|
fprintf("\n");
|
||||||
|
|
||||||
% MLSE Results
|
% MLSE Results
|
||||||
fprintf(">> MLSE Results:\n");
|
fprintf(">> MLSE Results:\n");
|
||||||
fprintf(" BER : %.2e\n", mlse.BER);
|
fprintf(" BER : %.2e\n", mlse_result.BER);
|
||||||
fprintf(" BER (pre-code): %.2e\n", mlse.BER_precoded);
|
fprintf(" BER (pre-code): %.2e\n", mlse_result.BER_precoded);
|
||||||
fprintf(" Channel Alpha : %.2f\n", mlse.Alpha);
|
fprintf(" Channel Alpha : %.2f\n", mlse_result.Alpha);
|
||||||
fprintf("\n");
|
fprintf("\n");
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -244,6 +254,7 @@ end
|
|||||||
|
|
||||||
output.dataTable = dataTable;
|
output.dataTable = dataTable;
|
||||||
output.vnle_pf_package = vnle_pf_package;
|
output.vnle_pf_package = vnle_pf_package;
|
||||||
|
output.vnle_package = vnle_package;
|
||||||
output.dbtgt_package = dbtgt_package;
|
output.dbtgt_package = dbtgt_package;
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -4,9 +4,89 @@
|
|||||||
savePath = 'Z:\2025\ECOC Silas\ecoc_2025\';
|
savePath = 'Z:\2025\ECOC Silas\ecoc_2025\';
|
||||||
databasePath = 'C:\Users\Silas\Documents\MATLAB\imdd_simulation\projects\ECOC_2025\';
|
databasePath = 'C:\Users\Silas\Documents\MATLAB\imdd_simulation\projects\ECOC_2025\';
|
||||||
database_name = 'ecoc2025_loops.db';
|
database_name = 'ecoc2025_loops.db';
|
||||||
db = DBHandler("pathToDB", [databasePath, database_name],"type","mysql");
|
db = DBHandler("type","mysql");
|
||||||
% db = DBHandler("type","mysql");
|
% db = DBHandler("pathToDB", [databasePath, database_name],"type","sqlite");
|
||||||
num_occ = 5;
|
|
||||||
run_par = false;
|
filterParams = db.tables;
|
||||||
run_id = 1958;
|
% filterParams.Configurations = struct('run_id', 4001);
|
||||||
[out, future] = submit_dsp(run_id, databasePath, database_name, savePath,"parallel",run_par,'max_occurences',num_occ);
|
filterParams.Configurations = struct( ...
|
||||||
|
'symbolrate', 112e9, ... %[224,336,360,390,420,448]
|
||||||
|
'fiber_length', 0, ...
|
||||||
|
'db_mode', '"no_db"', ...
|
||||||
|
'interference_attenuation', [], ...
|
||||||
|
'interference_path_length', [], ...
|
||||||
|
'is_mpi', 1, ...
|
||||||
|
'pam_level', 4, ...
|
||||||
|
'wavelength', 1310, ...
|
||||||
|
'precomp_amp', [], ...
|
||||||
|
'signal_attenuation', [], ...
|
||||||
|
'v_awg', [], ...
|
||||||
|
'v_bias', 2.65 ...
|
||||||
|
);
|
||||||
|
|
||||||
|
selectedFields = {'Runs.run_id','Runs.loop_id','Runs.tx_bits_path','Runs.tx_signal_path','Runs.tx_symbols_path','Runs.rx_sync_path','Runs.rx_raw_path',...
|
||||||
|
'Configurations.db_mode','Configurations.pam_level','Configurations.bitrate','Configurations.symbolrate','Configurations.fiber_length','Configurations.wavelength','Configurations.precomp_amp','Measurements.power_rop','Configurations.v_bias',...
|
||||||
|
'Configurations.interference_attenuation', 'Configurations.interference_path_length'};
|
||||||
|
|
||||||
|
[dataTable,sql_query] = db.queryDB(filterParams, selectedFields);
|
||||||
|
|
||||||
|
% dataTable(dataTable.loop_id<200,:) = [];
|
||||||
|
|
||||||
|
num_occ = 15;
|
||||||
|
run_par = true;
|
||||||
|
run_id = dataTable.run_id;
|
||||||
|
params = struct();
|
||||||
|
|
||||||
|
% slow DC tracking
|
||||||
|
params.dc_buffer_len = 224;
|
||||||
|
params.ffe_buffer_len = 1;
|
||||||
|
params.smoothing_buffer_length = 0;
|
||||||
|
params.smoothing_buffer_update = 0;
|
||||||
|
params.mu_dc = 0.005;
|
||||||
|
|
||||||
|
futures_list = parallel.FevalFuture.empty();
|
||||||
|
for id = 1:length(dataTable.run_id)
|
||||||
|
run_id = dataTable.run_id(id);
|
||||||
|
[out, futures_list(id)] = submit_dsp(run_id, databasePath, database_name, savePath,"parallel",run_par,'max_occurences',num_occ,'paramstruct',params);
|
||||||
|
end
|
||||||
|
|
||||||
|
% ideal DC tracking
|
||||||
|
params.dc_buffer_len = 1;
|
||||||
|
params.ffe_buffer_len = 1;
|
||||||
|
params.smoothing_buffer_length = 0;
|
||||||
|
params.smoothing_buffer_update = 0;
|
||||||
|
params.mu_dc = 0.005;
|
||||||
|
|
||||||
|
futures_list = parallel.FevalFuture.empty();
|
||||||
|
for id = 1:length(dataTable.run_id)
|
||||||
|
run_id = dataTable.run_id(id);
|
||||||
|
[out, futures_list(id)] = submit_dsp(run_id, databasePath, database_name, savePath,"parallel",run_par,'max_occurences',num_occ,'paramstruct',params);
|
||||||
|
end
|
||||||
|
|
||||||
|
% DC smoothing
|
||||||
|
params.dc_buffer_len = 1;
|
||||||
|
params.ffe_buffer_len = 1;
|
||||||
|
params.smoothing_buffer_length = 4096;
|
||||||
|
params.smoothing_buffer_update = 224;
|
||||||
|
params.mu_dc = 0.00;
|
||||||
|
|
||||||
|
futures_list = parallel.FevalFuture.empty();
|
||||||
|
for id = 1:length(dataTable.run_id)
|
||||||
|
run_id = dataTable.run_id(id);
|
||||||
|
[out, futures_list(id)] = submit_dsp(run_id, databasePath, database_name, savePath,"parallel",run_par,'max_occurences',num_occ,'paramstruct',params);
|
||||||
|
end
|
||||||
|
|
||||||
|
% only FFE
|
||||||
|
params.dc_buffer_len = 1;
|
||||||
|
params.ffe_buffer_len = 1;
|
||||||
|
params.smoothing_buffer_length = 0;
|
||||||
|
params.smoothing_buffer_update = 0;
|
||||||
|
params.mu_dc = 0.00;
|
||||||
|
|
||||||
|
futures_list = parallel.FevalFuture.empty();
|
||||||
|
for id = 1:length(dataTable.run_id)
|
||||||
|
run_id = dataTable.run_id(id);
|
||||||
|
[out, futures_list(id)] = submit_dsp(run_id, databasePath, database_name, savePath,"parallel",run_par,'max_occurences',num_occ,'paramstruct',params);
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
58
projects/ECOC_2025/dsp_test/hyperparam_tuning.m
Normal file
58
projects/ECOC_2025/dsp_test/hyperparam_tuning.m
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
|
||||||
|
|
||||||
|
Scpe_sig = load("imdd_simulation\projects\ECOC_2025\dsp_test\pam4_scopesignal.mat");Scpe_sig = Scpe_sig.Scpe_sig;
|
||||||
|
Tx_bits = load("imdd_simulation\projects\ECOC_2025\dsp_test\pam4_bits.mat");Tx_bits = Tx_bits.Tx_bits;
|
||||||
|
Symbols = load("imdd_simulation\projects\ECOC_2025\dsp_test\pam4_symbols.mat");Symbols = Symbols.Symbols;
|
||||||
|
|
||||||
|
eq_ = FFE_DCremoval("epochs_tr",5,"epochs_dd",3,"len_tr",4096*2,"mu_dd",1e-5,"mu_tr",0,"order",50,"sps",2,"decide",0,"mu_dc",0.005,"dc_buffer_len",1);
|
||||||
|
|
||||||
|
savePath = 'Z:\2025\ECOC Silas\ecoc_2025\';
|
||||||
|
databasePath = 'C:\Users\Silas\Documents\MATLAB\imdd_simulation\projects\ECOC_2025\';
|
||||||
|
database_name = 'ecoc2025_loops.db';
|
||||||
|
db = DBHandler("type","mysql");
|
||||||
|
|
||||||
|
params = (logspace(-6,-2,20));
|
||||||
|
params = floor((logspace(2,3,20)));
|
||||||
|
params = 224;
|
||||||
|
|
||||||
|
for i = 1:length(params)
|
||||||
|
|
||||||
|
eq_ = FFE_DCremoval_adaptive_mu("epochs_tr",5,"epochs_dd",3,"len_tr",4096*2,"mu_dd",...
|
||||||
|
0.0002,"mu_tr",0,"order",25,"sps",2,"decide",0,...
|
||||||
|
"mu_dc",0.005,"dc_buffer_len",224, ...
|
||||||
|
"ffe_buffer_len",1,...
|
||||||
|
"smoothing_buffer_length",0,...
|
||||||
|
"smoothing_buffer_update",224);
|
||||||
|
|
||||||
|
result = vnle(eq_,4,Scpe_sig,Symbols,Tx_bits,"precode_mode",db_mode.no_db,'showAnalysis',1,"postFFE",[],"eth_style_symbol_mapping",0);
|
||||||
|
ber_ffe(i) = result.ber_vnle;
|
||||||
|
fprintf(" FFE Results: %.2e\n", ber_ffe(i));
|
||||||
|
|
||||||
|
db.addProcessingResult(run_id, result.resultsVNLE, result.equalizerConfigVNLE);
|
||||||
|
|
||||||
|
% eq_ = FFE_adaptive_decision("epochs_tr",5,"epochs_dd",3,"len_tr",4096*2,"mu_dd",...
|
||||||
|
% 0.0003,"mu_tr",0,"order",50,"sps",2,"decide",1,"buffer_length",params(i));
|
||||||
|
%
|
||||||
|
% result = vnle(eq_,4,Scpe_sig,Symbols,Tx_bits,"precode_mode",db_mode.no_db,'showAnalysis',1,"postFFE",[],"eth_style_symbol_mapping",0);
|
||||||
|
% ber_dc(i) = result.ber_vnle;
|
||||||
|
%
|
||||||
|
% fprintf(" FFE+dc tr. Results: %.2e\n", ber_dc(i));
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
figure(103435)
|
||||||
|
hold on;
|
||||||
|
% scatter(params,ber_dc,15,'Marker','o','LineWidth',1,'DisplayName','DC tracking');
|
||||||
|
% [a,b]=min(ber_dc);
|
||||||
|
% scatter(params(b),a,45,'Marker','x','MarkerEdgeColor','r','LineWidth',1);
|
||||||
|
|
||||||
|
scatter(params,ber_ffe,15,'Marker','square','LineWidth',1);
|
||||||
|
[a,b]=min(ber_ffe);
|
||||||
|
scatter(params(b),a,45,'Marker','x','MarkerEdgeColor','r','LineWidth',1,'DisplayName','FFE');
|
||||||
|
|
||||||
|
legend('Interpreter', 'latex');
|
||||||
|
xlabel('Occurences');
|
||||||
|
ylabel('BER');
|
||||||
|
grid on;
|
||||||
|
beautifyBERplot;
|
||||||
|
ylim([1e-4,0.1 ])
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
|
|
||||||
run_id = 231;
|
run_id = 3966;
|
||||||
|
|
||||||
savePath = 'Z:\2025\ECOC Silas\ecoc_2025\';
|
savePath = 'Z:\2025\ECOC Silas\ecoc_2025\';
|
||||||
databasePath = 'C:\Users\Silas\Documents\MATLAB\imdd_simulation\projects\ECOC_2025\';
|
databasePath = 'C:\Users\Silas\Documents\MATLAB\imdd_simulation\projects\ECOC_2025\';
|
||||||
@@ -9,7 +9,22 @@ db = DBHandler("type","mysql");
|
|||||||
% db = DBHandler("pathToDB", [databasePath, database_name],"type","sqlite");
|
% db = DBHandler("pathToDB", [databasePath, database_name],"type","sqlite");
|
||||||
|
|
||||||
filterParams = db.tables;
|
filterParams = db.tables;
|
||||||
filterParams.Configurations = struct('run_id', run_id);
|
% filterParams.Configurations = struct('run_id', run_id);
|
||||||
|
filterParams.Configurations = struct( ...
|
||||||
|
'symbolrate', [], ... %[224,336,360,390,420,448]
|
||||||
|
'fiber_length', 0, ...
|
||||||
|
'db_mode', '"no_db"', ...
|
||||||
|
'interference_attenuation', 4, ...
|
||||||
|
'interference_path_length', 10, ...
|
||||||
|
'is_mpi', 1, ...
|
||||||
|
'pam_level', [], ...
|
||||||
|
'wavelength', 1310, ...
|
||||||
|
'precomp_amp', [], ...
|
||||||
|
'signal_attenuation', [], ...
|
||||||
|
'v_awg', [], ...
|
||||||
|
'v_bias', 2.65 ...
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
selectedFields = {'Runs.run_id','Runs.tx_bits_path','Runs.tx_signal_path','Runs.tx_symbols_path','Runs.rx_sync_path','Runs.rx_raw_path',...
|
selectedFields = {'Runs.run_id','Runs.tx_bits_path','Runs.tx_signal_path','Runs.tx_symbols_path','Runs.rx_sync_path','Runs.rx_raw_path',...
|
||||||
'Configurations.db_mode','Configurations.pam_level','Configurations.bitrate','Configurations.symbolrate','Configurations.fiber_length','Configurations.wavelength','Configurations.precomp_amp','Measurements.power_rop','Configurations.v_bias',...
|
'Configurations.db_mode','Configurations.pam_level','Configurations.bitrate','Configurations.symbolrate','Configurations.fiber_length','Configurations.wavelength','Configurations.precomp_amp','Measurements.power_rop','Configurations.v_bias',...
|
||||||
@@ -18,29 +33,36 @@ selectedFields = {'Runs.run_id','Runs.tx_bits_path','Runs.tx_signal_path','Runs.
|
|||||||
[dataTable,sql_query] = db.queryDB(filterParams, selectedFields);
|
[dataTable,sql_query] = db.queryDB(filterParams, selectedFields);
|
||||||
|
|
||||||
[~, uniqueIdx] = unique(dataTable.run_id); % Get unique run_id indices
|
[~, uniqueIdx] = unique(dataTable.run_id); % Get unique run_id indices
|
||||||
dataTable = dataTable(uniqueIdx,:); % Extract unique configurations for each run_id
|
|
||||||
|
|
||||||
fsym = dataTable.symbolrate;
|
|
||||||
M = double(dataTable.pam_level);
|
|
||||||
duob_mode = db_mode.(strrep(char(dataTable.db_mode),'"',''));
|
|
||||||
|
|
||||||
Tx_signal = load([savePath, char(dataTable.tx_signal_path)]);
|
for i = 1:4%size(dataTable,1)
|
||||||
Tx_signal = Tx_signal.Digi_sig;
|
dataTable_ = dataTable(i,:); % Extract unique configurations for each run_id
|
||||||
|
|
||||||
Tx_bits = load([savePath, char(dataTable.tx_bits_path)]);
|
fsym = dataTable_.symbolrate;
|
||||||
Tx_bits = Tx_bits.Bits;
|
M = double(dataTable_.pam_level);
|
||||||
Symbols_mapped = PAMmapper(M,0).map(Tx_bits);
|
duob_mode = db_mode.(strrep(char(dataTable_.db_mode),'"',''));
|
||||||
Symbols_mapped.fs = dataTable.symbolrate;
|
|
||||||
|
|
||||||
Symbols = load([savePath, char(dataTable.tx_symbols_path)]);
|
Tx_signal = load([savePath, char(dataTable_.tx_signal_path)]);
|
||||||
Symbols = Symbols.Symbols;
|
Tx_signal = Tx_signal.Digi_sig;
|
||||||
|
|
||||||
Scpe_sig_raw = load([savePath, char(dataTable.rx_raw_path(1))]);
|
Tx_bits = load([savePath, char(dataTable_.tx_bits_path)]);
|
||||||
Scpe_sig_raw = Scpe_sig_raw.Scpe_sig_raw;
|
Tx_bits = Tx_bits.Bits;
|
||||||
Scpe_sig_resampled = Scpe_sig_raw.resample("fs_in",Scpe_sig_raw.fs,"fs_out",2*fsym);
|
Symbols_mapped = PAMmapper(M,0).map(Tx_bits);
|
||||||
[~,Scpe_cell,found_sync,~,shifts] = Scpe_sig_resampled.tsynch("reference",Symbols,"fs_ref",dataTable.symbolrate,"debug_plots",1);
|
Symbols_mapped.fs = dataTable_.symbolrate;
|
||||||
|
|
||||||
shifts_mus = shifts./Scpe_sig_resampled.fs .*1e6;
|
Symbols = load([savePath, char(dataTable_.tx_symbols_path)]);
|
||||||
Scpe_sig_raw.plot("displayname",['Scope Signal (Run ID: ',num2str(run_id)],"fignum",2024,"clear",1);
|
Symbols = Symbols.Symbols;
|
||||||
hold on;
|
|
||||||
xline(shifts_mus,'HandleVisibility','off');
|
Scpe_sig_raw = load([savePath, char(dataTable_.rx_raw_path(1))]);
|
||||||
|
Scpe_sig_raw = Scpe_sig_raw.Scpe_sig_raw;
|
||||||
|
Scpe_sig_raw.plot("displayname",['Scope Signal (Run ID: ',num2str(dataTable_.run_id)],"fignum",dataTable_.run_id,"clear",0);
|
||||||
|
|
||||||
|
|
||||||
|
Scpe_sig_resampled = Scpe_sig_raw.resample("fs_in",Scpe_sig_raw.fs,"fs_out",2*fsym);
|
||||||
|
[~,Scpe_cell,found_sync,~,shifts] = Scpe_sig_resampled.tsynch("reference",Symbols,"fs_ref",dataTable_.symbolrate,"debug_plots",1);
|
||||||
|
|
||||||
|
shifts_mus = shifts./Scpe_sig_resampled.fs .*1e6;
|
||||||
|
Scpe_sig_raw.plot("displayname",['Scope Signal (Run ID: ',num2str(dataTable_.run_id)],"fignum",dataTable_.run_id,"clear",0);
|
||||||
|
hold on;
|
||||||
|
xline(shifts_mus,'HandleVisibility','off');
|
||||||
|
end
|
||||||
@@ -1,67 +1,129 @@
|
|||||||
|
|
||||||
local = 1;
|
basePath = 'C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor\';
|
||||||
|
% database = DBHandler("pathToDB",[basePath,'silas_labor.db']);
|
||||||
if local
|
database = DBHandler("type",'mysql');
|
||||||
databasePath = 'C:\Users\sioe\Documents\MATLAB\imdd_simulation\projects\ECOC_2025\';
|
|
||||||
else
|
|
||||||
databasePath = '\\ntserver.tf.uni-kiel.de\scratch\sioe\ECOC_2025\';
|
|
||||||
end
|
|
||||||
|
|
||||||
database_name = 'ecoc2025_loops.db';
|
|
||||||
database = DBHandler("pathToDB", [databasePath, database_name]);
|
|
||||||
|
|
||||||
figure();
|
|
||||||
plotBoundaries = 1;
|
|
||||||
plotRealizations = 1;
|
|
||||||
cols = linspecer(3); % Ensure color count matches
|
|
||||||
% cols = cols(8,:);
|
|
||||||
|
|
||||||
filterParams = database.tables;
|
filterParams = database.tables;
|
||||||
|
%filterParams.Runs.loop_id = 209;
|
||||||
filterParams.Configurations = struct( ...
|
filterParams.Configurations = struct( ...
|
||||||
'symbolrate', 112e9, ... %[224,336,360,390,420,448]
|
'symbolrate', 112e9, ... %[224,336,360,390,420,448]
|
||||||
'fiber_length', 0, ...
|
'fiber_length', 0, ...
|
||||||
'db_mode', '"no_db"', ...
|
'db_mode', '"no_db"', ...
|
||||||
'interference_attenuation', [], ...
|
'interference_attenuation', [], ...
|
||||||
'interference_path_length', 10, ...
|
'interference_path_length', [], ...
|
||||||
'is_mpi', 1, ...
|
'is_mpi', 1, ...
|
||||||
'pam_level', 4, ...
|
'pam_level', 4, ...
|
||||||
'wavelength', 1310, ...
|
'wavelength', 1310, ...
|
||||||
'precomp_amp', [], ...
|
'precomp_amp', [], ...
|
||||||
'signal_attenuation', [], ...
|
'signal_attenuation', [], ...
|
||||||
'v_awg', 0.95, ...
|
'v_awg', [], ...
|
||||||
'v_bias', 2.5 ...
|
'v_bias', [] ...
|
||||||
);
|
);
|
||||||
|
|
||||||
% filterParams.EqualizerParameters.diff_precode = int32(db_mode.db_encoded);
|
|
||||||
% filterParams.EqualizerParameters.equalizer_structure = int32(equalizer_structure.vnle);
|
% if 1
|
||||||
|
% % filterParams.EqualizerParameters.dc_buffer_len = 1;
|
||||||
|
% filterParams.EqualizerParameters.ffe_buffer_len = 1;
|
||||||
|
% filterParams.EqualizerParameters.smoothing_buffer_len = 4096;
|
||||||
|
% filterParams.EqualizerParameters.smoothing_buffer_update = 224;
|
||||||
|
% filterParams.EqualizerParameters.DCmu = 0;
|
||||||
|
% end
|
||||||
|
|
||||||
selectedFields = {'Configurations.run_id' 'Runs.loop_id' 'Runs.date_of_run' 'Runs.rx_raw_path' 'Configurations.bitrate' 'Configurations.v_bias' 'Configurations.v_awg' 'Configurations.precomp_amp' 'Configurations.symbolrate' 'Configurations.pam_level'...
|
selectedFields = {'Configurations.run_id' 'Runs.loop_id' 'Runs.date_of_run' 'Runs.rx_raw_path' 'Configurations.bitrate' 'Configurations.v_bias' 'Configurations.v_awg' 'Configurations.precomp_amp' 'Configurations.symbolrate' 'Configurations.pam_level'...
|
||||||
'Configurations.db_mode' 'Configurations.rop_attenuation' 'Configurations.is_mpi' 'Configurations.interference_attenuation' 'Configurations.interference_path_length' 'Configurations.signal_attenuation' ...
|
'Configurations.db_mode' 'Configurations.rop_attenuation' 'Configurations.is_mpi' 'Configurations.interference_attenuation' 'Configurations.interference_path_length' 'Configurations.signal_attenuation' ...
|
||||||
'EqualizerParameters.equalizer_structure' 'EqualizerParameters.diff_precode' 'EqualizerParameters.eq_id' 'Measurements.power_pd_in' ...
|
'EqualizerParameters.equalizer_structure' 'EqualizerParameters.diff_precode' 'EqualizerParameters.eq_id' 'EqualizerParameters.dc_buffer_len' 'EqualizerParameters.ffe_buffer_len' 'EqualizerParameters.smoothing_buffer_len' 'EqualizerParameters.smoothing_buffer_update' 'EqualizerParameters.DCmu' 'Measurements.power_pd_in' ...
|
||||||
'Measurements.power_mpi_interference' 'Measurements.power_mpi_signal' 'Results.BER' 'Results.BER_precoded' 'Results.SNR' 'Results.GMI' 'Results.Alpha' 'Results.date_of_processing'};
|
'Measurements.power_mpi_interference' 'Measurements.power_mpi_signal' 'Results.BER' 'Results.BER_precoded' 'Results.EVM' 'Results.SNR' 'Results.GMI' 'Results.Alpha' 'Results.date_of_processing'};
|
||||||
|
|
||||||
[dataTable,sql_query] = database.queryDB(filterParams, selectedFields);
|
% [dataTable_raw,sql_query] = database.queryDB(filterParams, selectedFields);
|
||||||
dataTable.SIR = round(-6 - dataTable.power_mpi_interference);
|
|
||||||
dataTable = cleanUpTable(dataTable);
|
%%
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
dataTable_clean = dataTable_raw;
|
||||||
|
dataTable_clean.SIR = round(-7.5 - dataTable_clean.power_mpi_interference);
|
||||||
|
dataTable_clean.NGMI = dataTable_clean.GMI ./ log2(dataTable_clean.pam_level);
|
||||||
|
dataTable_clean = cleanUpTable(dataTable_clean);
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
dataTable = dataTable_clean;
|
||||||
|
|
||||||
|
figure(26);
|
||||||
|
plotBoundaries = 1;
|
||||||
|
plotRealizations = 0;
|
||||||
|
cols = linspecer(8); % Ensure color count matches
|
||||||
|
|
||||||
|
% ideal DC tracking
|
||||||
|
if 0
|
||||||
|
dataTable = dataTable(dataTable.dc_buffer_len == 1, :);
|
||||||
|
dataTable = dataTable(dataTable.ffe_buffer_len == 1, :);
|
||||||
|
dataTable = dataTable(dataTable.smoothing_buffer_len == 0, :);
|
||||||
|
dataTable = dataTable(dataTable.smoothing_buffer_update == 0, :);
|
||||||
|
dataTable = dataTable(dataTable.DCmu == 0.005, :);
|
||||||
|
cols = cols(1:1+1,:);
|
||||||
|
method = 'ideal dc tracking';
|
||||||
|
% slow DC tracking
|
||||||
|
elseif 1
|
||||||
|
|
||||||
|
dataTable = dataTable(dataTable.dc_buffer_len == 224, :);
|
||||||
|
dataTable = dataTable(dataTable.ffe_buffer_len == 1, :);
|
||||||
|
dataTable = dataTable(dataTable.smoothing_buffer_len == 0, :);
|
||||||
|
dataTable = dataTable(dataTable.smoothing_buffer_update == 0, :);
|
||||||
|
dataTable = dataTable(dataTable.DCmu == 0.005, :);
|
||||||
|
cols = cols(2:2+1,:);
|
||||||
|
method = 'parallelized dc tracking';
|
||||||
|
% slow DC smoothing
|
||||||
|
elseif 0
|
||||||
|
|
||||||
|
dataTable = dataTable(dataTable.dc_buffer_len == 1, :);
|
||||||
|
dataTable = dataTable(dataTable.ffe_buffer_len == 1, :);
|
||||||
|
dataTable = dataTable(dataTable.smoothing_buffer_len == 4096, :);
|
||||||
|
dataTable = dataTable(dataTable.smoothing_buffer_update == 224, :);
|
||||||
|
dataTable = dataTable(dataTable.DCmu == 0, :);
|
||||||
|
cols = cols(3:3+1,:);
|
||||||
|
method = 'dc smoothing';
|
||||||
|
elseif 0
|
||||||
|
% No compensation method
|
||||||
|
dataTable = dataTable(dataTable.dc_buffer_len == 1, :);
|
||||||
|
dataTable = dataTable(dataTable.ffe_buffer_len == 1, :);
|
||||||
|
dataTable = dataTable(dataTable.smoothing_buffer_len == 0, :);
|
||||||
|
dataTable = dataTable(dataTable.smoothing_buffer_update == 0, :);
|
||||||
|
dataTable = dataTable(dataTable.DCmu == 0, :);
|
||||||
|
cols = cols(4:4+1,:);
|
||||||
|
method = 'ffe only';
|
||||||
|
end
|
||||||
|
|
||||||
dataTable(dataTable.eq_id==0,:) = [];
|
dataTable(dataTable.eq_id==0,:) = [];
|
||||||
|
dataTable(dataTable.equalizer_structure~=1,:) = [];
|
||||||
|
|
||||||
|
% dataTable.interference_path_length(dataTable.interference_path_length < 20, :) = 20;
|
||||||
|
|
||||||
|
dataTable = dataTable(dataTable.interference_path_length == 1000, :);
|
||||||
|
|
||||||
|
% dataTable(dataTable.interference_path_length ~= 50, :) = [];
|
||||||
|
% dataTable = dataTable(dataTable.interference_path_length < 51, :);
|
||||||
|
|
||||||
|
% dataTable(dataTable.loop_id<200,:) = [];
|
||||||
|
|
||||||
% Filter by time
|
% Filter by time
|
||||||
filter_by_time = 0;
|
filter_by_time = 0;
|
||||||
if filter_by_time
|
if filter_by_time
|
||||||
startTime = datetime('2025-04-14 13:00:00', 'InputFormat', 'yyyy-MM-dd HH:mm:ss');
|
startTime = datetime('2025-04-20 18:00:00', 'InputFormat', 'yyyy-MM-dd HH:mm:ss');
|
||||||
stopTime = datetime('2025-04-14 19:30:00', 'InputFormat', 'yyyy-MM-dd HH:mm:ss');
|
stopTime = datetime('2025-04-30 19:30:00', 'InputFormat', 'yyyy-MM-dd HH:mm:ss');
|
||||||
dataTable.date_of_run = datetime(dataTable.date_of_run, 'InputFormat', 'yyyy-MM-dd HH:mm:ss.SSSSSS');
|
dataTable.date_of_run = datetime(dataTable.date_of_run, 'InputFormat', 'yyyy-MM-dd HH:mm:ss.SSSSSS');
|
||||||
dataTable.date_of_processing = datetime(dataTable.date_of_processing, 'InputFormat', 'yyyy-MM-dd HH:mm:ss.SSSSSS');
|
dataTable.date_of_processing = datetime(dataTable.date_of_processing, 'InputFormat', 'yyyy-MM-dd HH:mm:ss.SSSSSS');
|
||||||
dataTable = dataTable(dataTable.date_of_processing > startTime, :);
|
dataTable = dataTable(dataTable.date_of_processing > startTime, :);
|
||||||
dataTable = dataTable(dataTable.date_of_processing < stopTime, :);
|
dataTable = dataTable(dataTable.date_of_processing < stopTime, :);
|
||||||
end
|
end
|
||||||
|
|
||||||
% Group by smth
|
% Group by smth
|
||||||
y_var = 'BER';
|
y_var = 'BER';
|
||||||
x_var = 'SIR';
|
x_var = 'SIR';
|
||||||
|
|
||||||
loop_var = 'eq_id';
|
loop_var = 'interference_path_length';
|
||||||
fixedVars = {'eq_id',x_var};
|
fixedVars = {'equalizer_structure','interference_path_length',x_var};
|
||||||
|
|
||||||
[dataTable, outliersTable] = removeGroupOutliers(dataTable, fixedVars, y_var);
|
[dataTable, outliersTable] = removeGroupOutliers(dataTable, fixedVars, y_var);
|
||||||
|
|
||||||
@@ -69,14 +131,13 @@ dataTableGrpd_mean = groupIt(fixedVars, dataTable, @mean);
|
|||||||
dataTableGrpd_min = groupIt(fixedVars, dataTable, @min);
|
dataTableGrpd_min = groupIt(fixedVars, dataTable, @min);
|
||||||
dataTableGrpd_max = groupIt(fixedVars, dataTable, @max);
|
dataTableGrpd_max = groupIt(fixedVars, dataTable, @max);
|
||||||
|
|
||||||
|
|
||||||
% Create a new figure
|
% Create a new figure
|
||||||
mkr = '.';
|
mkr = '.';
|
||||||
hold on
|
hold on
|
||||||
|
|
||||||
unique_loop_var = unique(dataTable.(loop_var));
|
unique_loop_var = unique(dataTable.(loop_var));
|
||||||
|
|
||||||
for i = 1%:numel(unique_loop_var)
|
for i = 1:numel(unique_loop_var)
|
||||||
|
|
||||||
% Prepare filtered data for this loop variable
|
% Prepare filtered data for this loop variable
|
||||||
loopValue = unique_loop_var(i);
|
loopValue = unique_loop_var(i);
|
||||||
@@ -98,32 +159,43 @@ for i = 1%:numel(unique_loop_var)
|
|||||||
y_bounds = [y_lower, y_upper];
|
y_bounds = [y_lower, y_upper];
|
||||||
|
|
||||||
% Display name (optional)
|
% Display name (optional)
|
||||||
idx = find(dataTable.(loop_var) == loopValue, 1, 'first');
|
try
|
||||||
dispname = equalizer_structure(dataTable.equalizer_structure(idx));
|
idx = find(dataTable.(loop_var) == loopValue, 1, 'first');
|
||||||
dispname = [char(dispname),'; ',num2str(unique(dataTable.interference_path_length)),' m'];
|
% dispname = char(equalizer_structure(dataTable.equalizer_structure(idx)));
|
||||||
|
dispname = [method];
|
||||||
|
dispname = [dispname, '/ ',num2str(unique_loop_var(i)) ,' m'];
|
||||||
|
% dispname = [dispname,'; ',num2str(unique(dataTable.interference_path_length)),' m'];
|
||||||
|
dispname = [dispname, '/ PAM ', num2str(filterParams.Configurations.pam_level)];
|
||||||
|
dispname = [dispname, '/ ', num2str(filterParams.Configurations.symbolrate.*1e-9),' GBd'];
|
||||||
|
end
|
||||||
|
|
||||||
if plotBoundaries
|
if plotBoundaries
|
||||||
% Plot bounded line
|
% Plot bounded line
|
||||||
[hl, hp] = boundedline(x_values, y_mean, y_bounds, ...
|
[hl, hp] = boundedline(x_values, y_mean, y_bounds, ...
|
||||||
'alpha', 'transparency', 0.2, ...
|
'alpha', 'transparency', 0.1, ...
|
||||||
'cmap', cols(i,:), ...
|
'cmap', cols(i,:), ...
|
||||||
'nan', 'fill', ...
|
'nan', 'fill', ...
|
||||||
'orientation', 'vert');
|
'orientation', 'vert');
|
||||||
|
|
||||||
% Style the main line: thinnest, dotted, no marker
|
% % Style the main line: thinnest, dotted, no marker
|
||||||
set(hl, 'LineWidth', 1, 'LineStyle', '-', 'Marker', 'none', ...
|
set(hl, 'LineWidth', 1, 'LineStyle', '-', 'Marker', 'none', ...
|
||||||
'Color', cols(i,:), 'DisplayName', string(dispname));
|
'Color', cols(i,:), 'DisplayName', string(dispname));
|
||||||
|
|
||||||
|
plt = errorbar(x_values,y_mean,y_lower,y_upper,'LineWidth', 0.1, 'LineStyle', 'none', 'Marker', 'none','Color', cols(i,:), 'DisplayName', string(dispname),'HandleVisibility','off');
|
||||||
|
|
||||||
% Hide patch (shaded area) from legend
|
% Hide patch (shaded area) from legend
|
||||||
set(hp, 'HandleVisibility', 'off','LineStyle',':','LineWidth',0.5,'Marker','none');
|
set(hp, 'HandleVisibility', 'off','LineStyle',':','LineWidth',0.5,'Marker','none');
|
||||||
|
|
||||||
% Add invisible scatter for DataTips
|
% % Add invisible scatter for DataTips
|
||||||
plt = scatter(x_values, y_mean, ...
|
% plt = scatter(x_values, y_mean, ...
|
||||||
'Marker', 'o', 'MarkerEdgeColor', 'none', 'MarkerFaceColor', 'none', ...
|
% 'Marker', 'o', 'MarkerEdgeColor', 'none', 'MarkerFaceColor', 'none', ...
|
||||||
'HandleVisibility', 'off', 'PickableParts', 'all');
|
% 'HandleVisibility', 'off', 'PickableParts', 'all');
|
||||||
else
|
else
|
||||||
|
|
||||||
plt= plot(x_values,y_mean,'LineWidth', 1, 'LineStyle', '-', 'Marker', 'none', ...
|
plt= plot(x_values,y_mean,'LineWidth', 1, 'LineStyle', '-', 'Marker', 'none', ...
|
||||||
'Color', cols(i,:), 'DisplayName', string(dispname));
|
'Color', cols(i,:), 'DisplayName', string(dispname));
|
||||||
|
% plt= errorbar(x_values,y_mean,y_lower,y_upper,'LineWidth', 1, 'LineStyle', '-', 'Marker', 'none','Color', cols(i,:), 'DisplayName', string(dispname));
|
||||||
|
|
||||||
end
|
end
|
||||||
% Add data tips to the invisible scatter
|
% Add data tips to the invisible scatter
|
||||||
pair_one = {'Run ID', dataTableGrpd_mean.run_id(loopFiltGrpd, :)};
|
pair_one = {'Run ID', dataTableGrpd_mean.run_id(loopFiltGrpd, :)};
|
||||||
@@ -146,7 +218,7 @@ for i = 1%:numel(unique_loop_var)
|
|||||||
y_single = double(dataTable.(y_var)(loopFiltSingle, :));
|
y_single = double(dataTable.(y_var)(loopFiltSingle, :));
|
||||||
|
|
||||||
sc = scatter(x_single, y_single, 'Marker', mkr, 'MarkerEdgeColor', cols(i, :), ...
|
sc = scatter(x_single, y_single, 'Marker', mkr, 'MarkerEdgeColor', cols(i, :), ...
|
||||||
'LineWidth', 0.5, 'HandleVisibility', 'on', 'DisplayName', string(dispname));
|
'LineWidth', 0.5, 'HandleVisibility', 'off', 'DisplayName', string(dispname));
|
||||||
|
|
||||||
pair_one = {'Run ID', dataTable.run_id(loopFiltSingle, :)};
|
pair_one = {'Run ID', dataTable.run_id(loopFiltSingle, :)};
|
||||||
pair_two = {'Rate', dataTable.bitrate(loopFiltSingle, :) * 1e-9};
|
pair_two = {'Rate', dataTable.bitrate(loopFiltSingle, :) * 1e-9};
|
||||||
@@ -161,12 +233,14 @@ xlabel(x_var);
|
|||||||
ylabel(y_var);
|
ylabel(y_var);
|
||||||
title([x_var, ' vs. ', y_var]);
|
title([x_var, ' vs. ', y_var]);
|
||||||
|
|
||||||
if y_var == 'BER'
|
if string(y_var) == "BER"
|
||||||
yline(4e-4, 'LineWidth', 1, 'LineStyle', '--', 'HandleVisibility', 'off');
|
yline(4e-4, 'LineWidth', 1, 'LineStyle', '--', 'HandleVisibility', 'off');
|
||||||
|
yline(3.8e-3, 'LineWidth', 1, 'LineStyle', '--', 'HandleVisibility', 'off');
|
||||||
|
yline(2e-2, 'LineWidth', 1, 'LineStyle', '--', 'HandleVisibility', 'off');
|
||||||
ylim([1e-5, 0.1]);
|
ylim([1e-5, 0.1]);
|
||||||
end
|
end
|
||||||
|
|
||||||
xlim([15,50]);
|
xlim([13,35]);
|
||||||
|
|
||||||
% Enable grid and beautify
|
% Enable grid and beautify
|
||||||
grid on;
|
grid on;
|
||||||
@@ -243,7 +317,6 @@ resultTable.nRows = groupCount;
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function addDatatips(sc, varargin)
|
function addDatatips(sc, varargin)
|
||||||
% addDatatips Adds custom data tip rows to a scatter plot.
|
% addDatatips Adds custom data tip rows to a scatter plot.
|
||||||
%
|
%
|
||||||
@@ -283,7 +356,6 @@ end
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function cleanedTable = cleanUpTable(inputTable)
|
function cleanedTable = cleanUpTable(inputTable)
|
||||||
% cleanUpTable Cleans a MATLAB table where numbers and NaNs are stored as strings or structs.
|
% cleanUpTable Cleans a MATLAB table where numbers and NaNs are stored as strings or structs.
|
||||||
%
|
%
|
||||||
@@ -335,7 +407,7 @@ for i = 1:numel(varNames)
|
|||||||
else
|
else
|
||||||
% Try convert to datetime
|
% Try convert to datetime
|
||||||
try
|
try
|
||||||
cleanedTable.(varNames{i}) = datetime(col, 'InputFormat', 'yyyy-MM-dd HH:mm:ss.SSSSSS');
|
cleanedTable.(varNames{i}) = datetime(col, 'InputFormat', 'yyyy-MM-dd HH:mm:ss');
|
||||||
catch
|
catch
|
||||||
% Leave as string
|
% Leave as string
|
||||||
end
|
end
|
||||||
@@ -391,8 +463,9 @@ for groupIdx = 1:height(groupKeys)
|
|||||||
continue;
|
continue;
|
||||||
end
|
end
|
||||||
|
|
||||||
% Detect outliers
|
% Detect outliers in log space
|
||||||
outlierMask = isoutlier(y_values, 'quartiles');
|
y_log = log10(y_values);
|
||||||
|
outlierMask = isoutlier(y_log, 'quartiles'); % or 'median', 'grubbs', etc.
|
||||||
|
|
||||||
% If any outliers found, collect their data
|
% If any outliers found, collect their data
|
||||||
if any(outlierMask)
|
if any(outlierMask)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ arguments
|
|||||||
savePath
|
savePath
|
||||||
options.parallel (1,1) logical = true
|
options.parallel (1,1) logical = true
|
||||||
options.max_occurences = 1;
|
options.max_occurences = 1;
|
||||||
|
options.paramstruct = struct();
|
||||||
end
|
end
|
||||||
|
|
||||||
if options.parallel
|
if options.parallel
|
||||||
@@ -29,7 +30,8 @@ if options.parallel
|
|||||||
"database_name", database_name, ...
|
"database_name", database_name, ...
|
||||||
'storage_path', savePath, ...
|
'storage_path', savePath, ...
|
||||||
'append_to_db', 1, ...
|
'append_to_db', 1, ...
|
||||||
'max_occurences', options.max_occurences ...
|
'max_occurences', options.max_occurences, ...
|
||||||
|
'parameters', options.paramstruct ...
|
||||||
);
|
);
|
||||||
|
|
||||||
output = [];
|
output = [];
|
||||||
@@ -46,7 +48,8 @@ else
|
|||||||
"database_name", database_name, ...
|
"database_name", database_name, ...
|
||||||
'storage_path', savePath, ...
|
'storage_path', savePath, ...
|
||||||
'append_to_db', 1, ...
|
'append_to_db', 1, ...
|
||||||
'max_occurences', options.max_occurences ...
|
'max_occurences', options.max_occurences,...
|
||||||
|
'parameters', options.paramstruct ...
|
||||||
);
|
);
|
||||||
|
|
||||||
future = []; % No future since it's synchronous
|
future = []; % No future since it's synchronous
|
||||||
|
|||||||
@@ -2,17 +2,18 @@
|
|||||||
% 1) Find RUN ID's
|
% 1) Find RUN ID's
|
||||||
|
|
||||||
basePath = 'C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor\';
|
basePath = 'C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor\';
|
||||||
database = DBHandler("pathToDB",[basePath,'silas_labor.db']);
|
% database = DBHandler("pathToDB",[basePath,'silas_labor.db']);
|
||||||
|
database = DBHandler("type",'mysql');
|
||||||
|
|
||||||
filterParams = database.tables;
|
filterParams = database.tables;
|
||||||
filterParams.Configurations = struct( ...
|
filterParams.Configurations = struct( ...
|
||||||
'bitrate', [], ... %[224,336,360,390,420,448]
|
'bitrate', 112e9, ... %[224,336,360,390,420,448]
|
||||||
'db_mode', [], ...
|
'db_mode', [], ...
|
||||||
'fiber_length', [], ...
|
'fiber_length', [], ...
|
||||||
'interference_attenuation',[], ...
|
'interference_attenuation',[], ...
|
||||||
'is_mpi', 0, ...
|
'interference_path_length',300, ...
|
||||||
'pam_level', [], ...
|
'is_mpi', 1, ...
|
||||||
'rop_attenuation', 0 ...
|
'pam_level', 4 ...
|
||||||
);
|
);
|
||||||
|
|
||||||
selectedFields = {'Runs.run_id',...
|
selectedFields = {'Runs.run_id',...
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ for occ = 1:proc_occ
|
|||||||
% %%%%% VNLE + DFE %%%%
|
% %%%%% VNLE + DFE %%%%
|
||||||
if 0
|
if 0
|
||||||
|
|
||||||
eq_vnle_dfe = EQ("Ne",vnle_order,"Nb",[0,0,0],"training_length",len_tr,"training_loops",5,"dd_loops",5,"K",2,"DCmu",mu_dc,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",0);
|
eq_vnle_dfe = EQ("Ne",vnle_order,"Nb",[0,0,0],"training_length",len_tr,"training_loops",5,"dd_loops",5,"K",2,"DCmu",mu_dc,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.001,"FFEmu",0,"plotfinal",0,"ideal_dfe",0);
|
||||||
eq_post = FFE("epochs_tr",5,"epochs_dd",5,"len_tr",4096*2,"mu_dd",1e-4,"mu_tr",0,"order",2001,"sps",1,"decide",0);
|
eq_post = FFE("epochs_tr",5,"epochs_dd",5,"len_tr",4096*2,"mu_dd",1e-4,"mu_tr",0,"order",2001,"sps",1,"decide",0);
|
||||||
|
|
||||||
[result] = vnle(eq_vnle_dfe,M,Scpe_sig,Symbols,Tx_bits,"precode_mode",duob_mode,"showAnalysis",1,"postFFE",[]);
|
[result] = vnle(eq_vnle_dfe,M,Scpe_sig,Symbols,Tx_bits,"precode_mode",duob_mode,"showAnalysis",1,"postFFE",[]);
|
||||||
|
|||||||
Reference in New Issue
Block a user