Many changes in DBHandler
new general processing structure just before splitting off the projects folder from this repo
This commit is contained in:
@@ -1,96 +1,129 @@
|
||||
function [eq_package] = duobinary_signaling(eq_, mlse_,M ,rx_signal, tx_symbols, tx_bits,options)
|
||||
%Duobinary Signaling
|
||||
function [db_results] = duobinary_signaling(eq_, mlse_, M, rx_signal, tx_symbols, tx_bits, options)
|
||||
% DUOBINARY_SIGNALING Processes signals through duobinary signaling
|
||||
%
|
||||
% Inputs:
|
||||
% eq_ - Equalizer object
|
||||
% mlse_ - MLSE object
|
||||
% M - Modulation order
|
||||
% rx_signal - Received signal
|
||||
% tx_symbols - Transmitted symbols
|
||||
% tx_bits - Transmitted bits
|
||||
% options - Optional parameters
|
||||
%
|
||||
% Outputs:
|
||||
% db_results - Results from duobinary signaling processing
|
||||
|
||||
arguments
|
||||
eq_
|
||||
mlse_
|
||||
M
|
||||
rx_signal
|
||||
tx_symbols
|
||||
tx_bits
|
||||
options.postFFE = [];
|
||||
eq_
|
||||
mlse_
|
||||
M
|
||||
rx_signal
|
||||
tx_symbols
|
||||
tx_bits
|
||||
options.precode_mode db_mode
|
||||
options.showAnalysis = 0
|
||||
options.eth_style_symbol_mapping = 0
|
||||
options.postFFE = []
|
||||
options.database = []
|
||||
end
|
||||
|
||||
%% Process signals through equalizer
|
||||
[eq_signal, eq_noise] = eq_.process(rx_signal, tx_symbols);
|
||||
|
||||
[eq_signal, eq_noise] = eq_.process(rx_signal,tx_symbols);
|
||||
|
||||
% Apply post-FFE if provided
|
||||
if ~isempty(options.postFFE)
|
||||
[eq_signal,eq_noise] = options.postFFE.process(eq_signal,tx_symbols);
|
||||
[eq_signal, eq_noise] = options.postFFE.process(eq_signal, tx_symbols);
|
||||
end
|
||||
|
||||
|
||||
% Process through MLSE
|
||||
eq_signal = mlse_.process(eq_signal);
|
||||
|
||||
% Apply duobinary encoding and decoding
|
||||
eq_signal = Duobinary().encode(eq_signal);
|
||||
eq_signal = Duobinary().decode(eq_signal);
|
||||
|
||||
% M = numel(unique(eq_signal.signal));
|
||||
rx_bits = PAMmapper(M,0).demap(eq_signal);
|
||||
% Demap symbols to bits
|
||||
rx_bits = PAMmapper(M, 0, "eth_style", options.eth_style_symbol_mapping).demap(eq_signal);
|
||||
|
||||
[bits_db,errors_db,ber_db,~] = calc_ber(rx_bits.signal,tx_bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||
%% Calculate BER and metrics
|
||||
[bits_db, errors_db, ber_db, error_pos] = calc_ber(rx_bits.signal, tx_bits.signal, "skip_front", 100, "skip_end", 150, "returnErrorLocation", 1);
|
||||
|
||||
eq_package.ber = ber_db;
|
||||
|
||||
resultsDBsignaling = 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
|
||||
'numBits', bits_db, ... % Beispiel: 1.000.000 Bits
|
||||
'numBitErr', errors_db, ... % Beispiel: 120 Bitfehler
|
||||
'BER_precoded', [], ... % BER = 120 / 1.000.000
|
||||
'numBitErr_precoded', [], ... % Beispiel: 120 Bitfehler
|
||||
'BER', ber_db, ... % BER = 120 / 1.000.000
|
||||
'SNR', [], ... % Beispielhafte SNR
|
||||
'SNR_level', jsonencode([]), ... % SNR-Level als JSON-codiertes Array
|
||||
'GMI', [], ... % Beispielhafter GMI-Wert
|
||||
'AIR', [], ... % Beispielhafter AIR-Wert
|
||||
'EVM', [], ... % Beispielhafte EVM
|
||||
'EVM_level', jsonencode([]), ... % EVM-Level als JSON-codiertes Array
|
||||
'Alpha', [] ... % Beispielhafter Alpha-Wert
|
||||
);
|
||||
% Calculate performance metrics
|
||||
[snr, snr_lvl] = calc_snr(tx_symbols.signal, eq_noise.signal);
|
||||
[gmi] = calc_air(eq_signal, tx_symbols, "skip_front", 10000, "skip_end", 10000);
|
||||
air = tx_symbols.fs .* floor(log2(double(M))*10)/10 .* gmi ./ log2(double(M));
|
||||
[evm_total, evm_lvl] = calc_evm(eq_signal, tx_symbols);
|
||||
[std_total, std_lvl] = calc_std(eq_signal, tx_symbols);
|
||||
[std_rxraw_total, std_rxraw_lvl] = calc_std(rx_signal.resample("fs_out", tx_symbols.fs), tx_symbols);
|
||||
|
||||
%% Prepare output structure
|
||||
% Determine postFFE order
|
||||
if ~isempty(options.postFFE)
|
||||
npostFFE = options.postFFE.order;
|
||||
else
|
||||
npostFFE = 0;
|
||||
end
|
||||
|
||||
equalizerConfigDBsignaling = struct( ...
|
||||
'eq_id', NaN, ... % Auto-Inkrement, wird in der DB gesetzt
|
||||
'equalizer_structure', int32(equalizer_structure.db_encoded), ... % 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', 1, ... % 0 oder 1
|
||||
'diff_precode', 1, ... % 0 oder 1
|
||||
'postFFE', ~isempty(options.postFFE), ... % Beispielwert
|
||||
'NpostFFE', npostFFE, ... % Beispielwert
|
||||
'Ne1', eq_.Ne(1), ... % Feedforward Koeffizienten 1. Ordnung
|
||||
'Ne2', eq_.Ne(2), ... % Feedforward Koeffizienten 2. Ordnung
|
||||
'Ne3', eq_.Ne(3), ... % Feedforward Koeffizienten 3. Ordnung
|
||||
'Nb1', eq_.Nb(1), ... % Decision Feedback Koeffizienten 1. Ordnung
|
||||
'Nb2', eq_.Nb(2), ... % Decision Feedback Koeffizienten 2. Ordnung
|
||||
'Nb3', eq_.Nb(3), ... % Decision Feedback Koeffizienten 3. Ordnung
|
||||
'K', eq_.K, ... % Samples pro Symbol
|
||||
'DCmu', eq_.DCmu, ... % Anpassungsrate für DC-Tap
|
||||
'ideal_dfe', eq_.ideal_dfe, ... % Flag für ideal DFE (0 oder 1)
|
||||
'training_length', eq_.training_length, ... % Anzahl Trainingssymbole
|
||||
'training_loops', eq_.training_loops, ... % Anzahl Trainingsdurchläufe
|
||||
'TRmu1', eq_.FFEmu, ... % mu für DD-Modus (1. Ordnung)
|
||||
'TRmu2', eq_.FFEmu, ... % mu für DD-Modus (2. Ordnung)
|
||||
'TRmu3', eq_.FFEmu, ... % mu für DD-Modus (3. Ordnung)
|
||||
'TRmuDFE', eq_.DFEmu, ... % mu für DFE-Modus im DD
|
||||
'dd_loops', 5, ... % Anzahl Durchläufe im DD-Modus
|
||||
'DDmu1', eq_.DDmu(1), ... % mu für DD-Modus (1. Ordnung)
|
||||
'DDmu2', eq_.DDmu(2), ... % mu für DD-Modus (2. Ordnung)
|
||||
'DDmu3', eq_.DDmu(3), ... % mu für DD-Modus (3. Ordnung)
|
||||
'DDmuDFE', eq_.DDmu(4), ... % mu für DFE-Modus im DD
|
||||
'MLSE_mode', 'viterbi', ... % Beispiel: MLSE-Modus als String
|
||||
'MLSE_trellis_states', jsonencode(mlse_.trellis_states), ... % Trellis-States, z.B. als JSON-String oder kommasepariert
|
||||
'comment', 'function: duobinary_target.m', ... % Zusätzliche Kommentare
|
||||
'config_hash', NaN ...
|
||||
);
|
||||
% Create results structure
|
||||
db_results = struct();
|
||||
db_results.metrics = Metricstruct;
|
||||
db_results.metrics.result_id = NaN;
|
||||
db_results.metrics.run_id = NaN;
|
||||
db_results.metrics.eqParam_id = NaN;
|
||||
db_results.metrics.date_of_processing = datetime('now');
|
||||
db_results.metrics.BER = ber_db;
|
||||
db_results.metrics.numBits = bits_db;
|
||||
db_results.metrics.numBitErr = errors_db;
|
||||
db_results.metrics.SNR = snr;
|
||||
db_results.metrics.SNR_level = snr_lvl;
|
||||
db_results.metrics.STD = std_total;
|
||||
db_results.metrics.STD_level = std_lvl;
|
||||
db_results.metrics.STDrx = std_rxraw_total;
|
||||
db_results.metrics.STDrx_level = std_rxraw_lvl;
|
||||
db_results.metrics.GMI = gmi;
|
||||
db_results.metrics.AIR = air;
|
||||
db_results.metrics.EVM = evm_total;
|
||||
db_results.metrics.EVM_level = evm_lvl;
|
||||
db_results.metrics.MLSE_dir = mlse_.DIR;
|
||||
|
||||
eq_package.resultsDBsignaling = resultsDBsignaling;
|
||||
eq_package.equalizerConfigDBsignaling = equalizerConfigDBsignaling;
|
||||
% Create configuration structure
|
||||
eq_.e = [];
|
||||
eq_.e2 = [];
|
||||
eq_.e3 = [];
|
||||
db_results.config = Equalizerstruct();
|
||||
db_results.config.eq = jsonencode(eq_);
|
||||
mlse_.DIR = [];
|
||||
db_results.config.mlse = jsonencode(mlse_);
|
||||
db_results.config.equalizer_structure = int32(equalizer_structure.db_encoded);
|
||||
db_results.config.comment = 'function: duobinary_signaling';
|
||||
|
||||
%% Display analysis if requested
|
||||
if options.showAnalysis
|
||||
displayAnalysis(eq_noise, eq_signal, rx_signal, eq_, tx_symbols, M, options.postFFE);
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
%% Helper Function
|
||||
function displayAnalysis(eq_noise, eq_signal, rx_signal, eq_, tx_symbols, M, postFFE)
|
||||
% Display analysis plots and metrics
|
||||
figure(336);
|
||||
showEQNoisePSD(eq_noise, "fignum", 336, "displayname", 'Residual Noise after Duobinary');
|
||||
|
||||
if ~isempty(postFFE)
|
||||
showEQcoefficients('n1', postFFE.e, "displayname", 'Coefficients', 'fignum', 338);
|
||||
end
|
||||
|
||||
showEQfilter(eq_.e, eq_signal.fs.*2);
|
||||
|
||||
figure(341); clf;
|
||||
showLevelHistogram(eq_signal, tx_symbols, "fignum", 341);
|
||||
|
||||
warning off
|
||||
figure(400); clf;
|
||||
showLevelScatter(eq_signal, tx_symbols, "fignum", 400);
|
||||
|
||||
figure(401); clf;
|
||||
showLevelScatter(rx_signal.resample("fs_out", tx_symbols.fs), tx_symbols, "fignum", 401);
|
||||
warning on
|
||||
end
|
||||
Reference in New Issue
Block a user