From 4cef384d1506a8794d834501c30f7feb78d5e464 Mon Sep 17 00:00:00 2001 From: Silas Oettinghaus Date: Wed, 25 Mar 2026 12:55:50 +0100 Subject: [PATCH] Split dsp_runid into run preprocessing and scope DSP pipeline --- Functions/EQ_structures/dsp_runid.m | 381 +++++---------------- Functions/EQ_structures/dsp_scope_signal.m | 188 ++++++++++ Functions/Job_Processing/preprocessRunId.m | 36 ++ 3 files changed, 309 insertions(+), 296 deletions(-) create mode 100644 Functions/EQ_structures/dsp_scope_signal.m create mode 100644 Functions/Job_Processing/preprocessRunId.m diff --git a/Functions/EQ_structures/dsp_runid.m b/Functions/EQ_structures/dsp_runid.m index 43187eb..28ae128 100644 --- a/Functions/EQ_structures/dsp_runid.m +++ b/Functions/EQ_structures/dsp_runid.m @@ -1,4 +1,4 @@ -function [output] = dsp_runid(run_id, options) +function output = dsp_runid(run_id, options) arguments run_id @@ -13,307 +13,96 @@ arguments end try - % Initialize output structures + output = initializeOutput(); + database = []; + + if options.mode == "load_run_id" || options.append_to_db + database = DBHandler("dataBase", [options.dataBase], "type", options.database_type, ... + 'user', "silas", 'password', "silas", 'server', "134.245.243.254"); + end + + if options.mode == "load_run_id" + dspInput = preprocessRunId(run_id, database, options); + elseif options.mode == "load_files" + dspInput = loadDspInputFromFiles(run_id, options); + else + error('dsp_runid:UnsupportedMode', 'Mode "%s" is not supported by the refactored dsp_runid path.', options.mode); + end + + options.max_occurences = min(options.max_occurences, length(dspInput.Scpe_cell)); + for r = 1:options.max_occurences + scopeOutput = dsp_scope_signal(dspInput.Scpe_cell{r}, dspInput.Symbols, dspInput.Tx_bits, ... + "fsym", dspInput.fsym, ... + "M", dspInput.M, ... + "duob_mode", dspInput.duob_mode, ... + "parameters", options.parameters); + + output.ffe_package{r} = scopeOutput.ffe_package; + output.mlse_package{r} = scopeOutput.mlse_package; + output.vnle_package{r} = scopeOutput.vnle_package; + output.dbtgt_package{r} = scopeOutput.dbtgt_package; + output.dbenc_package{r} = scopeOutput.dbenc_package; + output.mlmlse_package{r} = scopeOutput.mlmlse_package; + + if options.append_to_db + appendScopeOutputToDatabase(database, run_id, scopeOutput); + end + end + +catch ME + save('workerError.mat', 'ME'); + rethrow(ME); +end + +end + +function output = initializeOutput() output.ffe_package = {}; output.mlse_package = {}; output.vnle_package = {}; output.dbtgt_package = {}; output.dbenc_package = {}; output.mlmlse_package = {}; - - if options.mode == "load_run_id" || options.append_to_db - % Initialize database connection - database = DBHandler("dataBase", [options.dataBase], "type", options.database_type, 'user',"silas","password","silas","server","134.245.243.254"); - - if 0 - % 2. Check if an equalizer configuration with the same hash exists - queryStr = sprintf('SELECT COUNT(DISTINCT eq_id) AS unique_eq_count, COUNT(*) AS entries_for_run FROM `Results` WHERE run_id = %d', run_id); - existing_results = database.fetch(queryStr); - - if existing_results.unique_eq_count >= 6 - if (existing_results.entries_for_run / existing_results.unique_eq_count) > 5 - return - end - end - end - - end - - if options.mode == "load_run_id" - - dataTable = queryRunid(run_id, database); - fsym = dataTable.symbolrate; - M = double(dataTable.pam_level); - duob_mode = db_mode(strrep(dataTable.db_mode,'"','')); - - % if database.checkIfRunExists('Results','run_id',run_id) - % disp(['Already got at least one reulst for run id: ',num2str(run_id),' ']) - % return - % end - - % Load and Sync signal data from DB - [Tx_bits, Symbols, Scpe_cell, ~] = loadAndSyncSignalDataFromDb(dataTable, options); - - elseif options.mode == "load_files" - - Tx_bits = load(options.load_file_path.tx_bits_path); - Symbols = load(options.load_file_path.tx_symbols_path); - Scpe_sig_raw = load(options.load_file_path.rx_raw_path); - - Tx_bits = Tx_bits.Bits; - Symbols = Symbols.Symbols; - Scpe_sig_raw = Scpe_sig_raw.Scpe_sig_raw; - - fsym = Symbols.fs; - M = Symbols.logbook.ModifierCopy{1}.M; - duob_mode = Symbols.logbook.ModifierCopy{1}.duobinary_mode; - - Scpe_sig_resampled = Scpe_sig_raw.resample("fs_in", Scpe_sig_raw.fs, "fs_out", 2*fsym); - [~, Scpe_cell, ~, found_sync] = Scpe_sig_resampled.tsynch("reference", Symbols, "fs_ref", fsym, "debug_plots", 1); - - else - - % Run quick Simulation - tx_simulation; - - end - - % Handle Settings and argument replacement - - len_tr = 4096*2; - - ffe_order = [50, 5, 5]; - dfe_order = [0, 0, 0]; - pf_ncoeffs = 1; - mu_ffe = [0.0001, 0.0008, 0.001]; - mu_dfe = 0.0004; - mu_dc = 0.005; - dc_buffer_len = 1; - - mu_tr = 0; - mu_dd = 0.05; - adaption= 1; - use_dd_mode = 1; - - use_ffe = 0; - use_dfe = 0; - use_vnle_mlse = 0; - use_dbtgt = 0; - use_dbenc = 0; - use_ml_mlse = 1; - - addProcessingResultToDatabase = 0; - - % Overwrite default parameters if given in options.parameters - paramStruct = options.parameters; - if ~isempty(paramStruct) - paramNames = fieldnames(paramStruct); - for i = 1:numel(paramNames) - thisName = paramNames{i}; - thisValue = paramStruct.(thisName); - eval([thisName ' = thisValue;']); - end - end - - % Configure equalizers - - options.max_occurences = min(options.max_occurences,length(Scpe_cell)); - for r = 1:options.max_occurences - - %FFE - % eq_dfe = FFE("epochs_tr",5,"epochs_dd",2,"len_tr",2^13,"mu_dd",mu_dd,"mu_tr",mu_tr,"order",25,"sps",2,"decide",0, "adaption",adaption_method(adaption),"dd_mode",use_dd_mode); - - - % - pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1); - % mlse_ = MLSE_viterbi("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels); - mlse_ = MLSE("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels); - - eq_post = FFE("epochs_tr",5,"epochs_dd",5,"len_tr",4096*2,"mu_dd",1e-4,"mu_tr",0,"order",2001,"sps",1,"decide",0,"adaption_technique","lms"); - eq_post = FFE("epochs_tr",5,"epochs_dd",2,"len_tr",2^13,"mu_dd",mu_dd,"mu_tr",mu_tr,"order",25,"sps",2,"decide",0, "adaption",adaption_method(adaption),"dd_mode",use_dd_mode); - % Duobinary signaling (db encoded) - mlse_db_enc = MLSE("DIR", [1,1], "duobinary_output", 0, "M", M, "trellis_states", PAMmapper(M,0).levels); - eq_db_enc = EQ("Ne", ffe_order, "Nb", dfe_order, "training_length", len_tr, ... - "training_loops", 5, "dd_loops", 5, "K", 2, "DCmu", mu_dc, ... - "DDmu", [mu_ffe mu_dfe], "DFEmu", 0.005, "FFEmu", 0, "plotfinal", 0, "ideal_dfe", 1); - - % Preprocess signal - Scpe_sig = preprocessSignal(Scpe_cell{r}, Symbols, fsym); - - Scpe_sig.spectrum("fignum",200,"normalizeTo0dB",1,"displayname",'Rx','addDCoffset',-6); - - Scpe_sig.spectrum("fignum",201,"normalizeTo0dB",0,"displayname",'Rx'); - - ylim([-30,3]); - xlim([-5,100]); - % Scpe_sig.spectrum("fignum",22233,"normalizeTo0dB",0,"displayname",'Rx'); - % Scpe_sig.eye(fsym,M,"fignum",1024); - - Scpe_sig.signal = Scpe_sig.signal(1:2*Symbols.length); - Scpe_sig.signal = real(Scpe_sig.signal); - - if duob_mode ~= db_mode.db_encoded - - if use_ffe - - ffe_order = [50, 0, 0]; - eq_dfe = EQ("Ne",ffe_order,"Nb",[0,0,0],"training_length",len_tr,"training_loops",5,"dd_loops",5,"K",2,"DCmu",mu_dc,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",0); - - ffe_results = ffe(eq_dfe,M,Scpe_sig,Symbols,Tx_bits,... - "precode_mode",duob_mode,... - 'showAnalysis',0,... - "postFFE",[],... - "eth_style_symbol_mapping",0); - - output.ffe_package{r} = ffe_results; - - ffe_results.metrics.print; - ffe_results.config.equalizer_structure = "ffe"; - - if options.append_to_db - database.addProcessingResult(run_id, ffe_results.metrics, ffe_results.config); - end - - end - - if use_dfe - - ffe_order = [50, 5, 5]; - eq_dfe = EQ("Ne",ffe_order,"Nb",[2,0,0],"training_length",len_tr,"training_loops",5,"dd_loops",5,"K",2,"DCmu",mu_dc,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",0); - - dfe_results = ffe(eq_dfe,M,Scpe_sig,Symbols,Tx_bits,... - "precode_mode",duob_mode,... - 'showAnalysis',0,... - "postFFE",[],... - "eth_style_symbol_mapping",0); - - output.ffe_package{r} = dfe_results; - dfe_results.config.equalizer_structure = "dfe"; - - dfe_results.metrics.print; - - if options.append_to_db - database.addProcessingResult(run_id, dfe_results.metrics, dfe_results.config); - end - - end - - if use_vnle_mlse - - pf_ncoeffs = 1; - ffe_order = [50, 5, 5]; - eq_ = EQ("Ne",ffe_order,"Nb",dfe_order,"training_length",len_tr,"training_loops",5,"dd_loops",5,"K",2,"DCmu",mu_dc,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",0); - % eq_ = VNLE("epochs_tr",5,"epochs_dd",5,"len_tr",4096*2,"mu_dd",[0.0004 0.0005 0.0006],"mu_tr",0.0004,"order",[50,5,5],"sps",2,"decide",0); - pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1); - - useviterbi = 0; - if useviterbi - mlse_ = MLSE_viterbi("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels); - else - - if duob_mode == db_mode.no_db && M == 6 %only for PAM-6 and no duobinary precoding, otherwise leads to false sequence estimation - trellexlusion = 1; - else - trellexlusion = 0; - end - - %state_mode 3 -> stat lvl; state_mode 2 -> use target lvls - %scale_mode 2 -> mmse adaption - - mlse_ = MLSE("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels,'scale_mode',2,'trellis_exclusion',trellexlusion,'trellis_state_mode',2); - - end - - [ffe_results, mlse_results] = vnle_postfilter_mlse(eq_, pf_, mlse_, M, Scpe_sig, Symbols, Tx_bits, ... - "precode_mode", duob_mode,... - 'showAnalysis', 0, ... - "postFFE", [],... - "eth_style_symbol_mapping", 0); - - ffe_results.metrics.print; - ffe_results.config.equalizer_structure = "vnle"; - mlse_results.metrics.print; - - output.mlse_package{r} = mlse_results; - output.vnle_package{r} = ffe_results; - - if options.append_to_db - database.addProcessingResult(run_id, mlse_results.metrics, mlse_results.config); - database.addProcessingResult(run_id, ffe_results.metrics, ffe_results.config); - end - - end - - if use_ml_mlse - - %ML-based MLSE (L=2) - mu_ml = 0.01; training_epochs = 100; - ml_mlse_equalizer = ML_MLSE("epochs_tr",training_epochs,"epochs_dd",1, ... - "len_tr",length(Scpe_sig)/4,"mu_dd",mu_ml,"mu_tr",mu_ml,"order",11,"sps",2, ... - "traceback_depth",128,"L",1,"delta",4,"adaptive_mu",0); - - [ml_mlse_results] = ml_mlse(ml_mlse_equalizer, M, Scpe_sig, Symbols, Tx_bits,"precode_mode",duob_mode); - output.mlmlse_package{r} = ml_mlse_results; - - if options.append_to_db - database.addProcessingResult(run_id, ml_mlse_results.metrics, ml_mlse_results.config); - end - - end - - - if use_dbtgt - - useviterbi = 0; - if useviterbi - mlse_db_ = MLSE_viterbi("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels); - else - if duob_mode == db_mode.no_db && M == 6 %only for PAM-6 and no duobinary precoding, otherwise leads to false sequence estimation - trellexlusion = 1; - else - trellexlusion = 0; - end - mlse_db_ = MLSE("DIR",[1,1],"duobinary_output",0,"M",M,"trellis_states",PAMmapper(M,0).levels,'scale_mode',2,'trellis_exclusion',trellexlusion,'trellis_state_mode',3); - end - ffe_order = [50, 5, 5]; - eq_ = EQ("Ne",ffe_order,"Nb",dfe_order,"training_length",len_tr,"training_loops",5,"dd_loops",5,"K",2,"DCmu",mu_dc,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1); - - dbt_results = duobinary_target(eq_, mlse_db_, M, Scpe_sig, Symbols, Tx_bits, ... - "precode_mode", duob_mode, ... - 'showAnalysis', 0,... - "postFFE", []); - - dbt_results.metrics.print; - - output.dbtgt_package{r} = dbt_results; - - if options.append_to_db - database.addProcessingResult(run_id, dbt_results.metrics, dbt_results.config); - end - - end - end - - if duob_mode == db_mode.db_encoded - - mlse_db_enc = MLSE_viterbi("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels); - mlse_db_enc = MLSE("DIR", [1,1], "duobinary_output", 0, "M", M, "trellis_states", PAMmapper(M,0).levels); - - db_results = duobinary_signaling(eq_db_enc, mlse_db_enc, M, Scpe_sig, Symbols, Tx_bits, "precode_mode",duob_mode, "showAnalysis",0,"postFFE",[]); - output.dbenc_package{r} = db_results; - if options.append_to_db - database.addProcessingResult(run_id, db_results.metrics, db_results.config); - end - - end - - - end - -catch ME - save('workerError.mat','ME'); - rethrow(ME); end +function dspInput = loadDspInputFromFiles(run_id, options) + %#ok + Tx_bits = load(options.load_file_path.tx_bits_path); + Symbols = load(options.load_file_path.tx_symbols_path); + Scpe_sig_raw = load(options.load_file_path.rx_raw_path); -end \ No newline at end of file + Tx_bits = Tx_bits.Bits; + Symbols = Symbols.Symbols; + Scpe_sig_raw = Scpe_sig_raw.Scpe_sig_raw; + + fsym = Symbols.fs; + M = Symbols.logbook.ModifierCopy{1}.M; + duob_mode = Symbols.logbook.ModifierCopy{1}.duobinary_mode; + + Scpe_sig_resampled = Scpe_sig_raw.resample("fs_in", Scpe_sig_raw.fs, "fs_out", 2*fsym); + [~, Scpe_cell, ~, found_sync] = Scpe_sig_resampled.tsynch("reference", Symbols, "fs_ref", fsym, "debug_plots", 1); + + dspInput = struct(); + dspInput.run_id = run_id; + dspInput.dataTable = table(); + dspInput.Tx_bits = Tx_bits; + dspInput.Symbols = Symbols; + dspInput.Scpe_cell = Scpe_cell; + dspInput.found_sync = found_sync; + dspInput.fsym = fsym; + dspInput.M = M; + dspInput.duob_mode = duob_mode; +end + +function appendScopeOutputToDatabase(database, run_id, scopeOutput) + packageNames = fieldnames(scopeOutput); + + for i = 1:numel(packageNames) + package = scopeOutput.(packageNames{i}); + if isempty(package) + continue + end + + database.addProcessingResult(run_id, package.metrics, package.config); + end +end diff --git a/Functions/EQ_structures/dsp_scope_signal.m b/Functions/EQ_structures/dsp_scope_signal.m new file mode 100644 index 0000000..32f5578 --- /dev/null +++ b/Functions/EQ_structures/dsp_scope_signal.m @@ -0,0 +1,188 @@ +function output = dsp_scope_signal(Scpe_sig_raw, Symbols, Tx_bits, options) +%DSP_SCOPE_SIGNAL Run the common DSP chain starting from a scope signal. + + arguments + Scpe_sig_raw + Symbols + Tx_bits + options.fsym + options.M + options.duob_mode + options.parameters struct = struct() + end + + output.ffe_package = []; + output.mlse_package = []; + output.vnle_package = []; + output.dbtgt_package = []; + output.dbenc_package = []; + output.mlmlse_package = []; + + fsym = options.fsym; + M = options.M; + duob_mode = options.duob_mode; + + len_tr = 4096*2; + + ffe_order = [50, 5, 5]; + dfe_order = [0, 0, 0]; + pf_ncoeffs = 1; + mu_ffe = [0.0001, 0.0008, 0.001]; + mu_dfe = 0.0004; + mu_dc = 0.005; + dc_buffer_len = 1; %#ok + + mu_tr = 0; + mu_dd = 0.05; + adaption = 1; + use_dd_mode = 1; + + use_ffe = 1; + use_dfe = 1; + use_vnle_mlse = 0; + use_dbtgt = 0; + use_dbenc = 0; + use_ml_mlse = 0; + + addProcessingResultToDatabase = 0; %#ok + + paramStruct = options.parameters; + if ~isempty(paramStruct) + paramNames = fieldnames(paramStruct); + for i = 1:numel(paramNames) + thisName = paramNames{i}; + thisValue = paramStruct.(thisName); + eval([thisName ' = thisValue;']); + end + end + + pf_ = Postfilter("ncoeff", pf_ncoeffs, "useBurg", 1); %#ok + mlse_ = MLSE("duobinary_output", 0, 'M', M, 'trellis_states', PAMmapper(M,0).levels); %#ok + + eq_post = FFE("epochs_tr",5,"epochs_dd",5,"len_tr",4096*2,"mu_dd",1e-4,"mu_tr",0,"order",2001,"sps",1,"decide",0,"adaption_technique","lms"); %#ok + eq_post = FFE("epochs_tr",5,"epochs_dd",2,"len_tr",2^13,"mu_dd",mu_dd,"mu_tr",mu_tr,"order",25,"sps",2,"decide",0, "adaption",adaption_method(adaption),"dd_mode",use_dd_mode); %#ok + + mlse_db_enc = MLSE("DIR", [1,1], "duobinary_output", 0, "M", M, "trellis_states", PAMmapper(M,0).levels); %#ok + eq_db_enc = EQ("Ne", ffe_order, "Nb", dfe_order, "training_length", len_tr, ... + "training_loops", 5, "dd_loops", 5, "K", 2, "DCmu", mu_dc, ... + "DDmu", [mu_ffe mu_dfe], "DFEmu", 0.005, "FFEmu", 0, "plotfinal", 0, "ideal_dfe", 1); + + Scpe_sig = preprocessSignal(Scpe_sig_raw, Symbols, fsym); + Scpe_sig.spectrum("fignum",200,"normalizeTo0dB",1,"displayname",'Rx','addDCoffset',-6); + Scpe_sig.spectrum("fignum",201,"normalizeTo0dB",0,"displayname",'Rx'); + + ylim([-30,3]); + xlim([-5,100]); + + Scpe_sig.signal = Scpe_sig.signal(1:2*Symbols.length); + Scpe_sig.signal = real(Scpe_sig.signal); + + if duob_mode ~= db_mode.db_encoded + if use_ffe + ffe_order = [50, 0, 0]; + eq_dfe = EQ("Ne",ffe_order,"Nb",[0,0,0],"training_length",len_tr,"training_loops",5,"dd_loops",5,"K",2,"DCmu",mu_dc,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",0); + + ffe_results = ffe(eq_dfe, M, Scpe_sig, Symbols, Tx_bits, ... + "precode_mode", duob_mode, ... + 'showAnalysis', 0, ... + "postFFE", [], ... + "eth_style_symbol_mapping", 0); + + output.ffe_package = ffe_results; + ffe_results.metrics.print; + ffe_results.config.equalizer_structure = "ffe"; + end + + if use_dfe + ffe_order = [50, 5, 5]; + eq_dfe = EQ("Ne",ffe_order,"Nb",[2,0,0],"training_length",len_tr,"training_loops",5,"dd_loops",5,"K",2,"DCmu",mu_dc,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",0); + + dfe_results = ffe(eq_dfe, M, Scpe_sig, Symbols, Tx_bits, ... + "precode_mode", duob_mode, ... + 'showAnalysis', 0, ... + "postFFE", [], ... + "eth_style_symbol_mapping", 0); + + output.ffe_package = dfe_results; + dfe_results.config.equalizer_structure = "dfe"; + dfe_results.metrics.print; + end + + if use_vnle_mlse + pf_ncoeffs = 1; + ffe_order = [50, 5, 5]; + eq_ = EQ("Ne",ffe_order,"Nb",dfe_order,"training_length",len_tr,"training_loops",5,"dd_loops",5,"K",2,"DCmu",mu_dc,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",0); + pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1); + + useviterbi = 0; + if useviterbi + mlse_ = MLSE_viterbi("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels); + else + if duob_mode == db_mode.no_db && M == 6 + trellexlusion = 1; + else + trellexlusion = 0; + end + + mlse_ = MLSE("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels,'scale_mode',2,'trellis_exclusion',trellexlusion,'trellis_state_mode',2); + end + + [ffe_results, mlse_results] = vnle_postfilter_mlse(eq_, pf_, mlse_, M, Scpe_sig, Symbols, Tx_bits, ... + "precode_mode", duob_mode, ... + 'showAnalysis', 0, ... + "postFFE", [], ... + "eth_style_symbol_mapping", 0); + + ffe_results.metrics.print; + ffe_results.config.equalizer_structure = "vnle"; + mlse_results.metrics.print; + + output.mlse_package = mlse_results; + output.vnle_package = ffe_results; + end + + if use_ml_mlse + mu_ml = 0.01; + training_epochs = 100; + ml_mlse_equalizer = ML_MLSE("epochs_tr",training_epochs,"epochs_dd",1, ... + "len_tr",length(Scpe_sig)/4,"mu_dd",mu_ml,"mu_tr",mu_ml,"order",11,"sps",2, ... + "traceback_depth",128,"L",1,"delta",4,"adaptive_mu",0); + + ml_mlse_results = ml_mlse(ml_mlse_equalizer, M, Scpe_sig, Symbols, Tx_bits, "precode_mode", duob_mode); + output.mlmlse_package = ml_mlse_results; + end + + if use_dbtgt + useviterbi = 0; + if useviterbi + mlse_db_ = MLSE_viterbi("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels); + else + if duob_mode == db_mode.no_db && M == 6 + trellexlusion = 1; + else + trellexlusion = 0; + end + mlse_db_ = MLSE("DIR",[1,1],"duobinary_output",0,"M",M,"trellis_states",PAMmapper(M,0).levels,'scale_mode',2,'trellis_exclusion',trellexlusion,'trellis_state_mode',3); + end + + ffe_order = [50, 5, 5]; + eq_ = EQ("Ne",ffe_order,"Nb",dfe_order,"training_length",len_tr,"training_loops",5,"dd_loops",5,"K",2,"DCmu",mu_dc,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1); + + dbt_results = duobinary_target(eq_, mlse_db_, M, Scpe_sig, Symbols, Tx_bits, ... + "precode_mode", duob_mode, ... + 'showAnalysis', 0, ... + "postFFE", []); + + dbt_results.metrics.print; + output.dbtgt_package = dbt_results; + end + end + + if duob_mode == db_mode.db_encoded + mlse_db_enc = MLSE_viterbi("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels); %#ok + mlse_db_enc = MLSE("DIR", [1,1], "duobinary_output", 0, "M", M, "trellis_states", PAMmapper(M,0).levels); + + db_results = duobinary_signaling(eq_db_enc, mlse_db_enc, M, Scpe_sig, Symbols, Tx_bits, "precode_mode",duob_mode, "showAnalysis",0,"postFFE",[]); + output.dbenc_package = db_results; + end +end diff --git a/Functions/Job_Processing/preprocessRunId.m b/Functions/Job_Processing/preprocessRunId.m new file mode 100644 index 0000000..ba21d00 --- /dev/null +++ b/Functions/Job_Processing/preprocessRunId.m @@ -0,0 +1,36 @@ +function dspInput = preprocessRunId(run_id, database, options) +%PREPROCESSRUNID Load one run_id and prepare the canonical DSP input. + + arguments + run_id + database + options struct + end + + dataTable = queryRunid(run_id, database); + [Tx_bits, Symbols, Scpe_cell, found_sync] = loadAndSyncSignalDataFromDb(dataTable, options); + + dspInput = struct(); + dspInput.run_id = run_id; + dspInput.dataTable = dataTable; + dspInput.Tx_bits = Tx_bits; + dspInput.Symbols = Symbols; + dspInput.Scpe_cell = Scpe_cell; + dspInput.found_sync = found_sync; + dspInput.fsym = dataTable.symbolrate; + dspInput.M = double(dataTable.pam_level); + dspInput.duob_mode = parseDbMode(dataTable.db_mode); +end + +function mode = parseDbMode(rawMode) + if isnumeric(rawMode) + mode = db_mode(rawMode); + return + end + + if iscell(rawMode) + rawMode = rawMode{1}; + end + + mode = db_mode(strrep(string(rawMode), '"', '')); +end