Final MPI Calculations here
This commit is contained in:
@@ -0,0 +1,254 @@
|
||||
%% BER over SIR from MpiReductionResults
|
||||
% 1) gather data from the database
|
||||
% 2) clean data and remove per-curve outliers
|
||||
% 3) plot BER over SIR grouped by algorithm
|
||||
|
||||
clear; clc;
|
||||
|
||||
%% 1) Gather data
|
||||
|
||||
studyName = "pam4_112_greater_3153";
|
||||
pathLengthToPlot = 0;
|
||||
selectedBlockUpdate = 1; % set [] to pool all block_update values
|
||||
selectedPamLevels = []; % set [] to use all PAM levels in the query result
|
||||
selectedAlgorithms = []; % set [] to use all algorithms in the query result
|
||||
|
||||
useBoundedLines = true;
|
||||
usePolyfit = true;
|
||||
polyfitOrderMax = 4;
|
||||
maxBerForPlot = 0.1;
|
||||
|
||||
db = DBHandler( ...
|
||||
"dataBase", "labor", ...
|
||||
"type", "mysql", ...
|
||||
"server", "192.168.178.192", ...
|
||||
"user", "silas", ...
|
||||
"password", "silas");
|
||||
db.refresh();
|
||||
|
||||
fp = QueryFilter();
|
||||
fp.where('Runs', 'interference_path_length', 'EQUALS', pathLengthToPlot);
|
||||
fp.where('Runs', 'fiber_length', 'EQUALS', 0);
|
||||
fp.where('Runs', 'db_mode', 'EQUALS', '"no_db"');
|
||||
fp.where('MpiReductionResults', 'study_name', 'EQUALS', char(studyName));
|
||||
if ~isempty(selectedBlockUpdate)
|
||||
fp.where('MpiReductionResults', 'block_update', 'EQUALS', selectedBlockUpdate);
|
||||
end
|
||||
|
||||
selectedFields = { ...
|
||||
'Runs.run_id', ...
|
||||
'Runs.sir', ...
|
||||
'Runs.pam_level', ...
|
||||
'Runs.symbolrate', ...
|
||||
'Runs.interference_path_length', ...
|
||||
'Runs.power_mpi_interference', ...
|
||||
'MpiReductionResults.occurrence_idx', ...
|
||||
'MpiReductionResults.storage_name', ...
|
||||
'MpiReductionResults.algorithm', ...
|
||||
'MpiReductionResults.algorithm_variant', ...
|
||||
'MpiReductionResults.eq_class', ...
|
||||
'MpiReductionResults.block_update', ...
|
||||
'MpiReductionResults.BER', ...
|
||||
'MpiReductionResults.BER_precoded', ...
|
||||
'MpiReductionResults.SNR', ...
|
||||
'MpiReductionResults.GMI', ...
|
||||
'MpiReductionResults.AIR'};
|
||||
selectedFields = selectedFields(:);
|
||||
|
||||
[rawData, query] = db.queryDB(fp, selectedFields);
|
||||
disp(query);
|
||||
fprintf("Fetched %d MPI reduction rows.\n", height(rawData));
|
||||
|
||||
%% 2) Clean data
|
||||
|
||||
data = rawData;
|
||||
numericFields = ["run_id", "sir", "pam_level", "symbolrate", ...
|
||||
"interference_path_length", "occurrence_idx", "block_update", ...
|
||||
"power_mpi_interference", "BER", "BER_precoded", "SNR", "GMI", "AIR"];
|
||||
for fieldIdx = 1:numel(numericFields)
|
||||
fieldName = numericFields(fieldIdx);
|
||||
if ismember(fieldName, string(data.Properties.VariableNames))
|
||||
data.(char(fieldName)) = numericColumn(data.(char(fieldName)));
|
||||
end
|
||||
end
|
||||
|
||||
stringFields = ["storage_name", "algorithm", "algorithm_variant", "eq_class"];
|
||||
for fieldIdx = 1:numel(stringFields)
|
||||
fieldName = stringFields(fieldIdx);
|
||||
if ismember(fieldName, string(data.Properties.VariableNames))
|
||||
data.(char(fieldName)) = stringColumn(data.(char(fieldName)));
|
||||
end
|
||||
end
|
||||
|
||||
data = data(isfinite(data.BER) & data.BER > 0 & data.BER < maxBerForPlot, :);
|
||||
data.sir_exact = -7 - data.power_mpi_interference;
|
||||
if isempty(data)
|
||||
warning("PLOT_mpi_reduction_db_ber_vs_sir:NoRows", ...
|
||||
"No rows remain after initial BER/path/study/block filtering.");
|
||||
return
|
||||
end
|
||||
|
||||
if isempty(selectedPamLevels)
|
||||
selectedPamLevels = unique(data.pam_level(isfinite(data.pam_level))).';
|
||||
else
|
||||
data = data(ismember(data.pam_level, selectedPamLevels), :);
|
||||
end
|
||||
|
||||
if isempty(selectedAlgorithms)
|
||||
selectedAlgorithms = unique(data.algorithm, "stable").';
|
||||
else
|
||||
selectedAlgorithms = string(selectedAlgorithms);
|
||||
data = data(ismember(data.algorithm, selectedAlgorithms), :);
|
||||
end
|
||||
|
||||
if isempty(data)
|
||||
warning("PLOT_mpi_reduction_db_ber_vs_sir:NoSelectedRows", ...
|
||||
"No rows remain after selectedPamLevels/selectedAlgorithms filtering.");
|
||||
return
|
||||
end
|
||||
|
||||
data.clean_keep = true(height(data), 1);
|
||||
[groupId, groupPam, groupAlgorithm, groupSir] = findgroups(data.pam_level, data.algorithm, data.sir);
|
||||
for groupIdx = 1:max(groupId)
|
||||
rowMask = groupId == groupIdx;
|
||||
berValues = data.BER(rowMask);
|
||||
if nnz(rowMask) > 3
|
||||
data.clean_keep(rowMask) = ~isoutlier(berValues);
|
||||
end
|
||||
end
|
||||
cleanData = data(data.clean_keep, :);
|
||||
|
||||
summaryTable = groupsummary(cleanData, ["pam_level", "algorithm", "sir"], ...
|
||||
{"mean", "min", "max"}, "BER");
|
||||
sirExactTable = groupsummary(cleanData, ["pam_level", "algorithm", "sir"], ...
|
||||
"median", "sir_exact");
|
||||
summaryTable.sir_exact = sirExactTable.median_sir_exact;
|
||||
summaryTable = sortrows(summaryTable, ["pam_level", "algorithm", "sir"]);
|
||||
|
||||
fprintf("Cleaned to %d rows across %d PAM/algorithm/SIR groups.\n", ...
|
||||
height(cleanData), height(summaryTable));
|
||||
disp(groupcounts(cleanData, ["pam_level", "algorithm"]));
|
||||
|
||||
%% 3) Plot data
|
||||
|
||||
if exist("linspecer", "file")
|
||||
algColors = linspecer(numel(selectedAlgorithms));
|
||||
else
|
||||
algColors = lines(numel(selectedAlgorithms));
|
||||
end
|
||||
|
||||
figure(); clf;
|
||||
tiledlayout(numel(selectedPamLevels), 1, "TileSpacing", "compact");
|
||||
|
||||
for pamIdx = 1:numel(selectedPamLevels)
|
||||
pamLevel = selectedPamLevels(pamIdx);
|
||||
nexttile; hold on;
|
||||
|
||||
for algIdx = 1:numel(selectedAlgorithms)
|
||||
algorithmName = selectedAlgorithms(algIdx);
|
||||
algColor = algColors(algIdx, :);
|
||||
rawMask = cleanData.pam_level == pamLevel & cleanData.algorithm == algorithmName;
|
||||
curveMask = summaryTable.pam_level == pamLevel & summaryTable.algorithm == algorithmName;
|
||||
|
||||
if ~any(curveMask)
|
||||
continue
|
||||
end
|
||||
scatter(cleanData.sir_exact(rawMask), cleanData.BER(rawMask), ...
|
||||
30, ...
|
||||
"Marker", ".", ...
|
||||
"MarkerEdgeColor", algColor, ...
|
||||
"HandleVisibility", "off");
|
||||
|
||||
sirValues = summaryTable.sir_exact(curveMask).';
|
||||
meanBer = summaryTable.mean_BER(curveMask).';
|
||||
minBer = summaryTable.min_BER(curveMask).';
|
||||
maxBer = summaryTable.max_BER(curveMask).';
|
||||
valid = isfinite(sirValues) & isfinite(meanBer) & meanBer > 0;
|
||||
|
||||
if useBoundedLines && exist("boundedline", "file") && any(valid)
|
||||
yLower = max(meanBer - minBer, 0);
|
||||
yUpper = max(maxBer - meanBer, 0);
|
||||
yBounds = [yLower(:), yUpper(:)];
|
||||
|
||||
[hl, hp] = boundedline(sirValues(valid).', meanBer(valid).', yBounds(valid, :), ...
|
||||
'alpha', 'transparency', 0.08, ...
|
||||
'cmap', algColor, ...
|
||||
'nan', 'fill', ...
|
||||
'orientation', 'vert');
|
||||
set(hl, "LineStyle", "none", "Marker", "none", "HandleVisibility", "off");
|
||||
set(hp, "LineStyle", "none", "HandleVisibility", "off");
|
||||
end
|
||||
|
||||
plot(sirValues(valid), meanBer(valid), ...
|
||||
"LineStyle", "none", ...
|
||||
"Marker", "o", ...
|
||||
"MarkerSize", 5, ...
|
||||
"LineWidth", 1.2, ...
|
||||
"Color", algColor, ...
|
||||
"MarkerFaceColor", algColor, ...
|
||||
"DisplayName", char(algorithmName));
|
||||
|
||||
if usePolyfit
|
||||
fitMask = valid & meanBer > 0;
|
||||
if nnz(fitMask) >= 2
|
||||
fitOrder = min(polyfitOrderMax, nnz(fitMask) - 1);
|
||||
fitCoeff = polyfit(sirValues(fitMask), log10(meanBer(fitMask)), fitOrder);
|
||||
xFit = linspace(min(sirValues(fitMask)), max(sirValues(fitMask)), 300);
|
||||
yFit = 10 .^ polyval(fitCoeff, xFit);
|
||||
|
||||
plot(xFit, yFit, ...
|
||||
"LineStyle", "--", ...
|
||||
"LineWidth", 1.1, ...
|
||||
"Color", algColor, ...
|
||||
"HandleVisibility", "off");
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
yline(2.2e-4, "LineWidth", 1, "LineStyle", "--", "HandleVisibility", "off");
|
||||
yline(3.8e-3, "LineWidth", 1, "LineStyle", "--", "HandleVisibility", "off");
|
||||
yline(2e-2, "LineWidth", 1, "LineStyle", "--", "HandleVisibility", "off");
|
||||
|
||||
title(sprintf("PAM %.0f, path %.0f m, block update %s", ...
|
||||
pamLevel, pathLengthToPlot, blockUpdateLabel(selectedBlockUpdate)));
|
||||
xlabel("SIR (dB)");
|
||||
ylabel("BER");
|
||||
set(gca, "YScale", "log");
|
||||
ylim([9e-5, maxBerForPlot]);
|
||||
grid on;
|
||||
box on;
|
||||
legend("Location", "best", "Interpreter", "none");
|
||||
end
|
||||
|
||||
if exist("beautifyBERplot", "file")
|
||||
beautifyBERplot("logscale", true, "setcolors", false, "setmarkers", false);
|
||||
end
|
||||
|
||||
%% Local helpers
|
||||
|
||||
function values = numericColumn(values)
|
||||
if iscell(values)
|
||||
values = string(values);
|
||||
end
|
||||
if isstring(values) || ischar(values)
|
||||
values = str2double(values);
|
||||
end
|
||||
values = double(values);
|
||||
end
|
||||
|
||||
function values = stringColumn(values)
|
||||
if iscell(values)
|
||||
values = string(values);
|
||||
elseif ischar(values)
|
||||
values = string(values);
|
||||
end
|
||||
values = strip(string(values));
|
||||
end
|
||||
|
||||
function label = blockUpdateLabel(selectedBlockUpdate)
|
||||
if isempty(selectedBlockUpdate)
|
||||
label = "pooled";
|
||||
else
|
||||
label = string(selectedBlockUpdate);
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user