285 lines
8.9 KiB
Matlab
285 lines
8.9 KiB
Matlab
|
|
database_type = 'mysql';
|
|
dataBase = 'labor_highspeed';%'C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor\silas_labor_newdsp_newstructure.db';
|
|
db = DBHandler("dataBase", [dataBase], "type", database_type);
|
|
|
|
fp = QueryFilter();
|
|
% fp.where('Runs', 'run_id','EQUALS', 987);
|
|
M = 6;
|
|
fp.where('Runs', 'pam_level','EQUALS', M);
|
|
% fp.where('Runs', 'bitrate','LESS_THAN', 310e9);
|
|
fp.where('Runs', 'fiber_length','EQUALS', 2);
|
|
fp.where('Runs', 'is_mpi','EQUALS', 0);
|
|
% fp.where('Runs', 'interference_path_length','EQUALS', 1000);
|
|
% fp.where('Runs', 'loop_id','GREATER_THAN', 11);
|
|
% fp.where('Runs', 'sir','EQUALS',18);
|
|
fp.where('Runs', 'wavelength','EQUALS', 1310);
|
|
% fp.where('Runs', 'db_mode','EQUALS', 0);
|
|
fp.where('Runs', 'rop_attenuation','EQUALS', 0);
|
|
|
|
fields = db.getTableFieldNames('power_state_info');
|
|
fields = [fields; db.getTableFieldNames('dashboard_ungrouped_aug_nov_2025')];
|
|
[dataTable,~] = db.queryDB(fp, fields);
|
|
|
|
eqstructures = unique(dataTable.equalizer_structure);
|
|
% Create the figure
|
|
showFiltered = true;
|
|
showPrecoded = false;
|
|
show_bitrate = true;
|
|
figure(5);
|
|
hold on
|
|
|
|
for eqs = [equalizer_structure.vnle]
|
|
|
|
% figure('Name',string([char(eqs),'']));
|
|
% hold on
|
|
|
|
for pre_emph = [0,1]
|
|
|
|
dbmode_filtered = dataTable(dataTable.db_mode == ~pre_emph,:);
|
|
|
|
eq_choice = equalizer_structure(eqs);
|
|
|
|
if sum(eqstructures == eq_choice)~=1
|
|
disp(eq_choice)
|
|
continue
|
|
end
|
|
|
|
eq_filtered = dbmode_filtered(dbmode_filtered.equalizer_structure == eq_choice,:);
|
|
|
|
% ===== NEW: compute averages + per-row keep masks (robust filtering) =====
|
|
[Tav, keepMask, keepMaskP] = avgBerBySymbolrate(eq_filtered); % <= NEW
|
|
|
|
% x-values (bitrate) for raw points (same mapping as your lines)
|
|
M = unique(eq_filtered.pam_level); % (assumes single PAM per curve)
|
|
if show_bitrate
|
|
x_raw = eq_filtered.symbolrate.*1e-9 .* floor(log2(M)*10)/10;
|
|
else
|
|
x_raw = eq_filtered.symbolrate.*1e-9;
|
|
end
|
|
|
|
% ===== NEW: scatter kept raw BER points (hidden from legend) =====
|
|
cols = cbrewer2('Paired',12);
|
|
thisColor = cols((2*eqs)+1+pre_emph,:);
|
|
scatter(x_raw(keepMask), ... % kept points
|
|
eq_filtered.BER(keepMask), ...
|
|
14, thisColor, 'filled', ...
|
|
'MarkerFaceAlpha', 0.35, ...
|
|
'MarkerEdgeAlpha', 0.35, ...
|
|
'HandleVisibility','off');
|
|
|
|
if showPrecoded
|
|
scatter(x_raw(keepMaskP), ... % kept precoded points
|
|
eq_filtered.BER_precoded(keepMaskP), ...
|
|
14, thisColor, 'filled', ...
|
|
'Marker', 'square', ...
|
|
'MarkerFaceAlpha', 0.35, ...
|
|
'MarkerEdgeAlpha', 0.35, ...
|
|
'HandleVisibility','off');
|
|
end
|
|
|
|
% ===== NEW: optionally show filtered-out points in red =====
|
|
if showFiltered
|
|
bad = ~keepMask;
|
|
if any(bad)
|
|
scatter(x_raw(bad), eq_filtered.BER(bad), ...
|
|
18, 'r', 'x', 'LineWidth', 1.2, ...
|
|
'HandleVisibility','off');
|
|
end
|
|
badp = ~keepMaskP;
|
|
if any(badp)
|
|
scatter(x_raw(badp), eq_filtered.BER_precoded(badp), ...
|
|
18, 'r', '+', 'LineWidth', 1.2, ...
|
|
'HandleVisibility','off');
|
|
end
|
|
end
|
|
|
|
% Keep your sorting and one-per-symbolrate behavior (using Tav)
|
|
symbolrate_sorted = sortrows(Tav,{'symbolrate','avg_BER_calc'}, 'ascend');
|
|
[~, ia] = unique(symbolrate_sorted.symbolrate, 'first');
|
|
symbolrate_sorted = symbolrate_sorted(ia, :);
|
|
|
|
if show_bitrate
|
|
% Bitrate for the averaged curves (unchanged)
|
|
xraw = symbolrate_sorted.symbolrate.*1e-9 .* floor(log2(M)*10)/10;
|
|
else
|
|
xraw = symbolrate_sorted.symbolrate.*1e-9;
|
|
end
|
|
% Use the MATLAB-averaged BERs
|
|
ber = symbolrate_sorted.avg_BER_calc;
|
|
ber_precoded = symbolrate_sorted.avg_BER_precoded_calc;
|
|
|
|
|
|
dname = strrep([char(eq_choice)],'_',' ');
|
|
if pre_emph
|
|
dname = [dname,' with pre-emph.'];
|
|
else
|
|
dname = [dname,' w/o pre-emph.'];
|
|
end
|
|
|
|
plot(xraw, ber, ...
|
|
'LineWidth', 1.5, 'MarkerSize', 5, ...
|
|
'Marker','o','LineStyle','-', ...
|
|
'Color',thisColor,'MarkerEdgeColor',thisColor,'MarkerFaceColor',[1,1,1], ...
|
|
'DisplayName', dname);
|
|
|
|
if showPrecoded
|
|
plot(xraw, ber_precoded, ...
|
|
'LineWidth', 1.5, 'MarkerSize', 5, ...
|
|
'Marker','square','LineStyle',':', ...
|
|
'Color',thisColor,'MarkerEdgeColor',thisColor,'MarkerFaceColor',[1,1,1], ...
|
|
'DisplayName', [dname,'; pre-coded']);
|
|
end
|
|
|
|
grid on;
|
|
|
|
if show_bitrate
|
|
xlabel('Net bitrate [GBps]', 'FontSize', 12);
|
|
else
|
|
xlabel('Symbol rate [GBd]', 'FontSize', 12);
|
|
end
|
|
ylabel('BER', 'FontSize', 12);
|
|
title('BER vs. Baud Rate','FontSize', 14, 'FontWeight', 'bold');
|
|
|
|
set(gca, 'XScale', 'linear', ...
|
|
'YScale', 'log', ...
|
|
'TickLabelInterpreter', 'latex', ...
|
|
'FontSize', 11);
|
|
|
|
xticks(xraw);
|
|
if show_bitrate
|
|
% xticks(200:25:500);
|
|
% xlim([350 500]);
|
|
xlim([min(xraw), max(xraw)]);
|
|
else
|
|
xlim([min(xraw), max(xraw)]);
|
|
end
|
|
|
|
ylim([1e-4, 0.5]);
|
|
|
|
end
|
|
yline([2.2e-4, 4.85e-3, 2e-2],'LineWidth',1,'LineStyle','--','HandleVisibility','off');
|
|
end
|
|
|
|
function [Tav, keepAll, keepAllP] = avgBerBySymbolrate(T, ZT, MIN_G)
|
|
% Minimal robust averaging of BER per symbolrate (+ masks for kept points).
|
|
% Usage: [Tav, keepAll, keepAllP] = avgBerBySymbolrate(T, ZT, MIN_G)
|
|
% Defaults: ZT=3 (MAD z-thresh in log10), MIN_G=2 (min points to filter)
|
|
|
|
if nargin < 2, ZT = 5; end
|
|
if nargin < 5, MIN_G = 0; end
|
|
|
|
hasP = ismember('BER_precoded', T.Properties.VariableNames);
|
|
hasNB = ismember('numBits', T.Properties.VariableNames);
|
|
|
|
[G,~,idx] = unique(T.symbolrate);
|
|
nG = numel(G);
|
|
|
|
avgBER = nan(nG,1);
|
|
avgBERp = nan(nG,1);
|
|
keepAll = false(height(T),1);
|
|
keepAllP = false(height(T),1);
|
|
|
|
for gi = 1:nG
|
|
r = idx==gi;
|
|
|
|
x = T.BER(r);
|
|
nb = hasNB * T.numBits(r) + ~hasNB; % if missing, nb==1 (scalar expansion ok)
|
|
|
|
[avgBER(gi), keepAll(r)] = rmeanBer(x, nb, ZT, MIN_G);
|
|
|
|
if hasP
|
|
xp = T.BER_precoded(r);
|
|
[avgBERp(gi), keepAllP(r)] = rmeanBer(xp, nb, ZT, MIN_G);
|
|
end
|
|
end
|
|
|
|
Tav = table(G, avgBER, avgBERp, ...
|
|
'VariableNames', {'symbolrate','avg_BER_calc','avg_BER_precoded_calc'});
|
|
end
|
|
|
|
function [mu, keep] = rmeanBer(x, nb, ZT, MIN_G, onlyHighOutliers, minKeepThreshold)
|
|
% Robust arithmetic mean of BER with log-domain MAD filtering (returns keep mask)
|
|
%
|
|
% Params:
|
|
% x : BER values
|
|
% nb : numBits (for floor)
|
|
% ZT : MAD z-threshold
|
|
% MIN_G : min group size before filtering
|
|
% onlyHighOutliers : (bool) if true, only discard values above mean
|
|
% minKeepThreshold : values below this BER are always kept
|
|
%
|
|
% Returns:
|
|
% mu : robust mean
|
|
% keep : logical mask of kept samples
|
|
|
|
if nargin < 5, onlyHighOutliers = false; end
|
|
if nargin < 6, minKeepThreshold = 0; end
|
|
|
|
x(~isfinite(x)) = NaN;
|
|
|
|
if ~isscalar(nb), nb(~isfinite(nb)) = NaN; end
|
|
if isscalar(nb) && ~isfinite(nb), nb = 1; end
|
|
|
|
floorVal = realmin;
|
|
if ~isscalar(nb) || (isscalar(nb) && isfinite(nb) && nb~=1)
|
|
fv = 0.5 ./ max(nb, eps); % rule-of-three style floor
|
|
if isscalar(fv), floorVal = fv; else, floorVal = fv; end
|
|
end
|
|
|
|
xAdj = x;
|
|
bad = ~isfinite(xAdj) | xAdj <= 0;
|
|
if isscalar(floorVal)
|
|
xAdj(bad) = floorVal;
|
|
else
|
|
xAdj(bad) = floorVal(bad);
|
|
end
|
|
|
|
valid = isfinite(xAdj) & xAdj > 0;
|
|
keep = false(size(xAdj));
|
|
|
|
if nnz(valid)==0
|
|
mu = NaN; return
|
|
end
|
|
if nnz(valid) < MIN_G
|
|
mu = mean(xAdj(valid),'omitnan'); keep(valid)=true; return
|
|
end
|
|
|
|
lx = log10(xAdj(valid));
|
|
med = median(lx,'omitnan');
|
|
mad = median(abs(lx-med),'omitnan');
|
|
|
|
if mad<=0 || ~isfinite(mad)
|
|
keep(valid) = true;
|
|
mu = mean(xAdj(valid),'omitnan');
|
|
return
|
|
end
|
|
|
|
sigma = 1.4826*mad;
|
|
ksel = abs(lx-med) <= ZT*sigma;
|
|
|
|
% convert to linear indices
|
|
vIdx = find(valid);
|
|
|
|
% === Extension A: only drop high outliers ===
|
|
if onlyHighOutliers
|
|
logMean = mean(lx,'omitnan');
|
|
highIdx = lx > logMean;
|
|
ksel = ksel | ~highIdx; % always keep values below/equal to mean
|
|
end
|
|
|
|
% === Extension B: always keep values below minKeepThreshold ===
|
|
belowThr = xAdj(valid) < minKeepThreshold;
|
|
ksel = ksel | belowThr;
|
|
|
|
keep(vIdx(ksel)) = true;
|
|
|
|
if any(keep)
|
|
mu = mean(xAdj(keep),'omitnan');
|
|
else
|
|
mu = mean(xAdj(valid),'omitnan');
|
|
keep(valid) = true;
|
|
end
|
|
end
|
|
|