function [output] = dsp_runid(run_id, options) arguments run_id options.append_to_db = 0; options.max_occurences = 4; options.parameters = struct(); options.database_type options.dataBase options.load_file_path = struct(); options.storage_path options.mode end try % Initialize output structures 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 ); 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 = 1; use_dfe = 1; use_vnle_mlse = 1; use_dbtgt = 1; use_dbenc = 1; 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); 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),"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 end