Files
imdd_silas/Classes/04_DSP/TransmissionPerformance.m
Silas Oettinghaus 74066d0669 Changes from mwork PC.
PDP 2025

MPI analysis

new focus on database and SQL
2025-03-21 08:11:40 +01:00

247 lines
11 KiB
Matlab

classdef TransmissionPerformance
% TransmissionPerformance
%
% This class calculates the best possible net data rate (in bits/s)
% from a given gross rate (bits/s) and a measured channel quality
% parameter (either bit error ratio (BER) or NGMI). The class uses
% lookup tables for three different FEC modes:
%
% 1. SD+HD concatenated (uses overall code rate and an NGMI threshold)
% 2. SD+HD concatenated with punctured LDPC (uses overall code rate and an NGMI threshold)
% 3. HD-only (uses a code rate and a BER threshold)
%
% The basic algorithm is as follows:
% 1. Given a measured quality (NGMI or BER) for each measurement, find in
% the table the first (i.e. “best”) entry that is satisfied by the
% measured value. For NGMI the condition is measured NGMI >= threshold,
% while for BER the condition is measured BER <= threshold.
% 2. Use the corresponding overall code rate to compute:
%
% net rate = gross rate * code rate.
%
% USAGE EXAMPLE (array inputs):
%
% tp = TransmissionPerformance;
% % Suppose we have 3 measurements:
% % Gross rates: 10, 15, and 20 Gbps
% % Measured NGMI: 0.92, 0.88, and 0.85
% % Measured BER: 1e-4, 7e-3, and 2e-2
% netrates = tp.calculatenetrate([10e9 15e9 20e9], ...
% 'NGMI', [0.92 0.88 0.85], ...
% 'BER', [1e-4 7e-3 2e-2]);
%
% The returned structure netrates will contain the net rates (and the
% used code rates and thresholds) for each mode in vector form.
properties (Constant)
%% Lookup Table for SD+HD concatenated (using NGMI)
% Overall code rate and NGMI threshold for each row.
OVERALLCODERATES_SDHD = [0.7519, 0.7602, 0.7684, 0.7766, 0.7850, ...
0.7932, 0.8014, 0.8098, 0.8180, 0.8262, ...
0.8345, 0.8428, 0.8510, 0.8593, 0.8676, ...
0.8733, 0.8790, 0.8848, 0.8905, 0.8962, ...
0.9019, 0.9077, 0.9134, 0.9191, 0.9248, ...
0.9306, 0.9363, 0.9420, 0.9477, 0.9535];
NGMITHRESHOLDS_SDHD = [0.8116, 0.8167, 0.8241, 0.8317, 0.8401, ...
0.8459, 0.8512, 0.8574, 0.8685, 0.8746, ...
0.8829, 0.8892, 0.8958, 0.9022, 0.9090,...
0.9150, 0.9210, 0.9270, 0.9330, 0.9390, ...
0.9450, 0.9510, 0.9570, 0.9630, 0.9690, ...
0.9750, 0.9810, 0.9870, 0.9930, 0.9990];
ISPUNCT_LDPI = [zeros(1,15),ones(1,15)];
%% Lookup Table for HD-only mode (using BER)
% For HD-only, the table gives the code rate and the maximum acceptable BER.
CODE_RATES_HD = [0.7500, 0.8000, 0.8123, 0.8333, 0.8571, ...
0.8750, 0.8889, 0.9000, 0.9091, 0.9167, 0.9412];
BERTHRESHOLDS_HD = [2.12e-2, 1.76e-2, 1.62e-2, 1.44e-2, 1.25e-2, ...
1.03e-2, 9.29e-3, 8.33e-3, 7.54e-3, 7.04e-3, 4.70e-3];
%% LUT for KP4-FEC and Inner Code https://grouper.ieee.org/groups/802/3/dj/public/23_03/patra_3dj_01b_2303.pdf
CODE_RATE_KP4_AND_INNER = [0.885799];
BERTHRESHOLDS_KP4_AND_INNER = 4.85e-3;
% https://www.ieee802.org/3/bs/public/14_11/parthasarathy_3bs_01a_1114.pdf
CODE_RATE_KP4 = [1/(1+0.052)];%Reed-Solomon RS(544, 514) == KP4
BERTHRESHOLDS_KP4 = 2.2e-4;
CODE_RATE_HDFEC = [1/(1+0.067)]; %Beyond 300 Gbps Short-Reach Links Using TFLN MZMs With 500 mVpp and Linear Equalization
BERTHRESHOLDS_HDFEC = 3.8e-3;
CODE_RATE_O_FEC = [1/(1+0.153)]; %Stefano im Meeting
BERTHRESHOLDS_O_FEC = 2e-2;
end
methods
function netrates = calculateNetRate(obj, grossRate, varargin)
% calculatenetrate Calculate the net data rate(s) from measured data.
%
% netrates = tp.calculatenetrate(grossRate, 'BER', berValue, 'NGMI', ngmiValue)
%
% INPUTS:
% grossRate - (scalar or vector) gross data rate(s) [bits/s]
%
% Optional name/value pairs:
% 'BER' - (scalar or vector) measured bit error ratio(s)
% 'NGMI' - (scalar or vector) measured NGMI value(s)
%
% At least one of 'BER' or 'NGMI' must be provided.
%
% OUTPUT:
% netrates - a structure with the following fields (if available):
% .SDHD - for SD+HD concatenated (using NGMI)
% .SDHD_LDPC - for SD+HD with punctured LDPC (using NGMI)
% .HD - for HD-only (using BER)
%
% Each sub-structure contains fields:
% .CodeRate - the chosen overall code rate from the table (vector)
% .Threshold - the threshold value used from the table (vector)
% .<BER/NGMI> - net rate computed as grossRate * CodeRate (vector)
% Parse inputs.
p = inputParser;
addRequired(p, 'grossRate', @(x) isnumeric(x));
addParameter(p, 'BER', [], @(x) isnumeric(x));
addParameter(p, 'NGMI', [], @(x) isnumeric(x));
parse(p, grossRate, varargin{:});
ber = p.Results.BER;
ngmi = p.Results.NGMI;
if isempty(ber) && isempty(ngmi)
error('At least one of ''BER'' or ''NGMI'' must be provided.');
end
% Determine the number of measurements.
numMeasurements = max([numel(grossRate), numel(ngmi), numel(ber)]);
% Broadcast scalars if needed.
if isscalar(grossRate) && numMeasurements > 1
grossRate = repmat(grossRate, 1, numMeasurements);
elseif numel(grossRate) ~= numMeasurements
error('grossRate must be scalar or have %d elements.', numMeasurements);
end
if ~isempty(ngmi)
if isscalar(ngmi) && numMeasurements > 1
ngmi = repmat(ngmi, 1, numMeasurements);
elseif numel(ngmi) ~= numMeasurements
error('NGMI must be scalar or have %d elements.', numMeasurements);
end
end
if ~isempty(ber)
if isscalar(ber) && numMeasurements > 1
ber = repmat(ber, 1, numMeasurements);
elseif numel(ber) ~= numMeasurements
error('BER must be scalar or have %d elements.', numMeasurements);
end
end
% Initialize the output structure.
netrates = struct;
if ~isempty(ngmi)
netrates.SDHD.GrossRate = NaN(1, numMeasurements);
netrates.SDHD.NetRate = NaN(1, numMeasurements);
netrates.SDHD.punctLDPI = NaN(1, numMeasurements);
netrates.SDHD.CodeRate = NaN(1, numMeasurements);
netrates.SDHD.Threshold = NaN(1, numMeasurements);
end
if ~isempty(ber)
netrates.HD.GrossRate = NaN(1, numMeasurements);
netrates.HD.NetRate = NaN(1, numMeasurements);
netrates.HD.CodeRate = NaN(1, numMeasurements);
netrates.HD.Threshold = NaN(1, numMeasurements);
netrates.KP4_hamming.GrossRate = NaN(1, numMeasurements);
netrates.KP4_hamming.NetRate = NaN(1, numMeasurements);
netrates.KP4_hamming.CodeRate = NaN(1, numMeasurements);
netrates.KP4_hamming.Threshold = NaN(1, numMeasurements);
netrates.O_FEC.GrossRate = NaN(1, numMeasurements);
netrates.O_FEC.NetRate = NaN(1, numMeasurements);
netrates.O_FEC.CodeRate = NaN(1, numMeasurements);
netrates.O_FEC.Threshold = NaN(1, numMeasurements);
end
% Process each measurement individually.
for i = 1:numMeasurements
% --- NGMI-based modes ---
if ~isempty(ngmi)
% SD+HD concatenated mode.
idx = find(obj.NGMITHRESHOLDS_SDHD <= ngmi(i), 1, 'last');
if ~isempty(idx)
codeRate = obj.OVERALLCODERATES_SDHD(idx);
netrates.SDHD.NetRate(i) = grossRate(i) * codeRate;
netrates.SDHD.GrossRate(i) = grossRate(i) ;
netrates.SDHD.CodeRate(i) = codeRate;
netrates.SDHD.Threshold(i) = obj.NGMITHRESHOLDS_SDHD(idx);
netrates.SDHD.punctLDPI(i) = obj.ISPUNCT_LDPI(idx);
end
end
% --- BER-based mode (HD-only) ---
if ~isempty(ber)
% Loop through the BER thresholds from the best (highest code rate)
% to the worst until the measured BER is acceptable.
idxBER = [];
for j = length(obj.BERTHRESHOLDS_HD):-1:1
if ber(i) <= obj.BERTHRESHOLDS_HD(j)
idxBER = j;
break;
end
end
if ~isempty(idxBER)
codeRate = obj.CODE_RATES_HD(idxBER);
netrates.HD.NetRate(i) = grossRate(i) * codeRate;
netrates.HD.GrossRate(i) = grossRate(i) ;
netrates.HD.CodeRate(i) = codeRate;
netrates.HD.Threshold(i) = obj.BERTHRESHOLDS_HD(idxBER);
end
idxBER = [];
for j = length(obj.BERTHRESHOLDS_KP4_AND_INNER):-1:1
if ber(i) <= obj.BERTHRESHOLDS_KP4_AND_INNER(j)
idxBER = j;
break;
end
end
if ~isempty(idxBER)
codeRate = obj.CODE_RATE_KP4_AND_INNER(idxBER);
netrates.KP4_hamming.NetRate(i) = grossRate(i) * codeRate;
netrates.KP4_hamming.GrossRate(i) = grossRate(i) ;
netrates.KP4_hamming.CodeRate(i) = codeRate;
netrates.KP4_hamming.Threshold(i) = obj.BERTHRESHOLDS_KP4_AND_INNER(idxBER);
end
idxBER = [];
for j = length(obj.BERTHRESHOLDS_O_FEC):-1:1
if ber(i) <= obj.BERTHRESHOLDS_O_FEC(j)
idxBER = j;
break;
end
end
if ~isempty(idxBER)
codeRate = obj.CODE_RATE_O_FEC(idxBER);
netrates.O_FEC.NetRate(i) = grossRate(i) * codeRate;
netrates.O_FEC.GrossRate(i) = grossRate(i) ;
netrates.O_FEC.CodeRate(i) = codeRate;
netrates.O_FEC.Threshold(i) = obj.BERTHRESHOLDS_O_FEC(idxBER);
end
end
end
end
end
end