few changes in WDM stuff
cleaned up the base system... but its not yet a good minimal example...
This commit is contained in:
199
projects/WDM/plot_BER_vs_ROP.m
Normal file
199
projects/WDM/plot_BER_vs_ROP.m
Normal file
@@ -0,0 +1,199 @@
|
||||
%% =========================
|
||||
% Routine A: BER vs ROP plots
|
||||
%% =========================
|
||||
function S = plot_BER_vs_ROP(res, varargin)
|
||||
% S = plot_BER_vs_ROP(res, 'fec', 3.8e-3, 'eval_list', [], 'colormap', 'Spectral')
|
||||
%
|
||||
% Creates one BER-vs-ROP figure per evaluated distance.
|
||||
% Returns S struct with FEC crossings: S.Sffe, S.Sdfe, S.Svnle, S.Smlse, S.Sdbt
|
||||
%
|
||||
% res.* assumed: res.ffe{ch,rop,realiz,eval_distance} etc.
|
||||
|
||||
p = inputParser;
|
||||
p.addParameter('fec', 3.8e-3, @(x)isnumeric(x)&&isscalar(x));
|
||||
p.addParameter('eval_list', [], @(x)isnumeric(x));
|
||||
p.addParameter('colormap', 'Spectral', @(x)ischar(x) || isstring(x));
|
||||
p.parse(varargin{:});
|
||||
fec = p.Results.fec;
|
||||
|
||||
% -------------------- Basic metadata --------------------
|
||||
rop = res.settings.rop(:);
|
||||
wavelengthplan = res.settings.wavelengthplan(:);
|
||||
distances = res.eval_dist_km(:);
|
||||
|
||||
N_ch = numel(wavelengthplan);
|
||||
N_rop = numel(rop);
|
||||
|
||||
% -------------------- Determine dims robustly --------------------
|
||||
dims = size(res.ffe);
|
||||
if numel(dims) < 4, dims(end+1:4) = 1; end
|
||||
N_distances = dims(4);
|
||||
|
||||
if numel(distances) ~= N_distances
|
||||
distances = (1:N_distances).';
|
||||
end
|
||||
|
||||
% -------------------- Choose eval distances --------------------
|
||||
eval_list = p.Results.eval_list;
|
||||
if isempty(eval_list)
|
||||
eval_list = 1:N_distances;
|
||||
end
|
||||
|
||||
% -------------------- Colors --------------------
|
||||
try
|
||||
cols = cbrewer2(char(p.Results.colormap), N_ch);
|
||||
catch
|
||||
cols = linspecer(N_ch);
|
||||
end
|
||||
|
||||
% -------------------- Crossings containers --------------------
|
||||
S = struct();
|
||||
S.rop = rop;
|
||||
S.wavelengthplan = wavelengthplan;
|
||||
S.distances = distances;
|
||||
S.fec = fec;
|
||||
|
||||
S.Sffe = cell(N_distances, N_ch);
|
||||
S.Sdfe = cell(N_distances, N_ch);
|
||||
S.Svnle = cell(N_distances, N_ch);
|
||||
S.Smlse = cell(N_distances, N_ch);
|
||||
S.Sdbt = cell(N_distances, N_ch);
|
||||
|
||||
% -------------------- Plot per distance --------------------
|
||||
for eval_ptr = eval_list
|
||||
|
||||
figure('Name', sprintf('BER vs ROP @ %s', distLabel(distances, eval_ptr)));
|
||||
hold on;
|
||||
|
||||
for ch = 1:N_ch
|
||||
|
||||
% Extract cell slices
|
||||
ffe_cells = sliceCells4D(res.ffe , ch, eval_ptr, N_rop);
|
||||
dfe_cells = sliceCells4D(res.dfe , ch, eval_ptr, N_rop);
|
||||
vnle_cells = sliceCells4D(res.vnle, ch, eval_ptr, N_rop);
|
||||
mlse_cells = sliceCells4D(res.mlse, ch, eval_ptr, N_rop);
|
||||
dbt_cells = sliceCells4D(res.dbt , ch, eval_ptr, N_rop);
|
||||
|
||||
% Crossings (only depends on cells)
|
||||
[S.Sffe{eval_ptr,ch}, ~] = fecCrossings(rop, ffe_cells, fec);
|
||||
[S.Sdfe{eval_ptr,ch}, ~] = fecCrossings(rop, dfe_cells, fec);
|
||||
[S.Svnle{eval_ptr,ch}, ~] = fecCrossings(rop, vnle_cells, fec);
|
||||
[S.Smlse{eval_ptr,ch}, ~] = fecCrossings(rop, mlse_cells, fec);
|
||||
[S.Sdbt{eval_ptr,ch}, ~] = fecCrossings(rop, dbt_cells, fec);
|
||||
|
||||
% BER matrices (complete realizations only)
|
||||
ffe_mat = extractCompleteBER(ffe_cells); % N_rop x K
|
||||
|
||||
if ~isempty(ffe_mat)
|
||||
% Your current style: plot each realization curve (no boundedline)
|
||||
plot(rop, ffe_mat, 'Color', cols(ch,:), ...
|
||||
'DisplayName', sprintf('FFE @ %dnm', round(wavelengthplan(ch))));
|
||||
end
|
||||
end
|
||||
|
||||
set(gca,'XScale','linear','YScale','log', ...
|
||||
'TickLabelInterpreter','latex','FontSize',11);
|
||||
|
||||
yline([3.8e-3, 2.2e-4], 'HandleVisibility','off','LineWidth',1.5);
|
||||
|
||||
ylabel('BER');
|
||||
xlabel('ROP [dB]');
|
||||
title(sprintf('BER vs. ROP @ %s', distLabel(distances, eval_ptr)));
|
||||
xlim([min(rop) max(rop)]);
|
||||
ylim([1e-5 0.3]);
|
||||
grid on;
|
||||
legend show;
|
||||
beautifyBERplot;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
%% =========================
|
||||
% Shared helpers (unchanged)
|
||||
%% =========================
|
||||
|
||||
function cells2D = sliceCells4D(C4, ch, eval_ptr, N_rop)
|
||||
dims = size(C4);
|
||||
if numel(dims) < 4, dims(end+1:4) = 1; end
|
||||
N_realiz = dims(3);
|
||||
|
||||
cells2D = cell(N_rop, N_realiz);
|
||||
|
||||
chMax = dims(1);
|
||||
ropMax = dims(2);
|
||||
rMax = dims(3);
|
||||
eMax = dims(4);
|
||||
|
||||
if ch > chMax || eval_ptr > eMax
|
||||
return;
|
||||
end
|
||||
|
||||
ropUse = min(N_rop, ropMax);
|
||||
rUse = min(N_realiz, rMax);
|
||||
|
||||
tmp = squeeze(C4(ch, 1:ropUse, 1:rUse, eval_ptr));
|
||||
tmp = reshape(tmp, ropUse, rUse);
|
||||
|
||||
cells2D(1:ropUse, 1:rUse) = tmp;
|
||||
end
|
||||
|
||||
function lbl = distLabel(distances, eval_ptr)
|
||||
if eval_ptr <= numel(distances)
|
||||
d = distances(eval_ptr);
|
||||
if isfinite(d)
|
||||
lbl = sprintf('%.0f km', d);
|
||||
return;
|
||||
end
|
||||
end
|
||||
lbl = sprintf('eval\\_%d', eval_ptr);
|
||||
end
|
||||
|
||||
function [S, noCrossingMask] = fecCrossings(rop, cellsNxR, fec)
|
||||
Y = extractCompleteBER(cellsNxR);
|
||||
if isempty(Y)
|
||||
S = [];
|
||||
noCrossingMask = [];
|
||||
return;
|
||||
end
|
||||
|
||||
ok = mean(Y,1,'omitnan') <= 0.1;
|
||||
Y = Y(:, ok);
|
||||
if isempty(Y)
|
||||
S = [];
|
||||
noCrossingMask = [];
|
||||
return;
|
||||
end
|
||||
|
||||
nR = size(Y,2);
|
||||
S = nan(1,nR);
|
||||
noCrossingMask = true(1,nR);
|
||||
|
||||
rop = rop(:);
|
||||
for j = 1:nR
|
||||
y = Y(:,j);
|
||||
above = (y > fec);
|
||||
idx = find(above(1:end-1) & ~above(2:end), 1, 'first');
|
||||
if ~isempty(idx)
|
||||
x1 = rop(idx); y1 = y(idx);
|
||||
x2 = rop(idx+1); y2 = y(idx+1);
|
||||
if isfinite(y1) && isfinite(y2) && y2 ~= y1
|
||||
t = (fec - y1) / (y2 - y1);
|
||||
S(j) = x1 + t*(x2 - x1);
|
||||
noCrossingMask(j) = false;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Y = extractCompleteBER(cellSlice)
|
||||
if isempty(cellSlice), Y = []; return; end
|
||||
nR = size(cellSlice,2);
|
||||
keep = false(1,nR);
|
||||
for r = 1:nR
|
||||
col = cellSlice(:,r);
|
||||
keep(r) = all(cellfun(@(c) ~isempty(c), col));
|
||||
end
|
||||
if ~any(keep), Y = []; return; end
|
||||
Y = cellfun(@(c) c.metrics.BER, cellSlice(:,keep), 'UniformOutput', true);
|
||||
end
|
||||
Reference in New Issue
Block a user