function [output] = dsp_run_id(run_id,options) arguments run_id options.append_to_db = 0; options.max_occurences = 4; options.parameters = struct(); options.database_path options.database_name options.storage_path end % database = DBHandler("pathToDB",[options.database_path,options.database_name],"type","sqlite"); database = DBHandler("type","mysql"); filterParams = database.tables; filterParams.Configurations = struct('run_id', run_id); selectedFields = {'Runs.run_id','Runs.tx_bits_path','Runs.tx_signal_path','Runs.tx_symbols_path','Runs.rx_sync_path','Runs.rx_raw_path',... 'Configurations.db_mode','Configurations.pam_level','Configurations.bitrate','Configurations.symbolrate','Configurations.fiber_length','Configurations.wavelength','Configurations.precomp_amp','Measurements.power_rop','Configurations.v_bias',... 'Configurations.interference_attenuation'}; [dataTable,sql_query] = database.queryDB(filterParams, selectedFields); [~, uniqueIdx] = unique(dataTable.run_id); % Get unique run_id indices dataTable = dataTable(uniqueIdx,:); % Extract unique configurations for each run_id fsym = dataTable.symbolrate; M = double(dataTable.pam_level); duob_mode = db_mode.(strrep(char(dataTable.db_mode),'"','')); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% len_tr = 4096*2; vnle_order1 = 50; vnle_order2 = 5; vnle_order3 = 5; dfe_order = [0 0 0]; pf_ncoeffs = 1; mu_ffe1 = 0.0001; mu_ffe2 = 0.0008; mu_ffe3 = 0.001; mu_dfe = 0.0004; mu_dc = 0.00; mu_ffe = [mu_ffe1 mu_ffe2 mu_ffe3]; vnle_order=[vnle_order1,vnle_order2,vnle_order3]; dc_buffer_len = 224; ffe_buffer_len = 1; smoothing_buffer_length = 4096; smoothing_buffer_update = 224; % 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 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% eq_ = EQ("Ne",vnle_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); pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1); mlse_ = MLSE_viterbi("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels); mlse_db_ = MLSE_viterbi("DIR",[1,1],"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); output = struct(); vnle_pf_package = {}; vnle_package = {}; dbtgt_package = {}; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Tx_signal = load([options.storage_path, char(dataTable.tx_signal_path)]); Tx_signal = Tx_signal.Digi_sig; Tx_bits = load([options.storage_path, char(dataTable.tx_bits_path)]); Tx_bits = Tx_bits.Bits; Symbols_mapped = PAMmapper(M,0).map(Tx_bits); Symbols_mapped.fs = dataTable.symbolrate; Symbols = load([options.storage_path, char(dataTable.tx_symbols_path)]); Symbols = Symbols.Symbols; found_sync = 0; try Scpe_load = load([options.storage_path, char(dataTable.rx_sync_path)]); Scpe_cell = Scpe_load.S; [~,~,found_sync] = Scpe_cell{2}.tsynch("reference",Symbols,"fs_ref",dataTable.symbolrate,"debug_plots",0); end if ~found_sync Scpe_sig_raw = load([options.storage_path, char(dataTable.rx_raw_path(1))]); Scpe_sig_raw = Scpe_sig_raw.Scpe_sig_raw; 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",dataTable.symbolrate,"debug_plots",1); end if ~found_sync if length(Symbols_mapped.signal) == sum(Symbols_mapped.signal == Symbols.signal) warning('Could not synchronize the received signal with the stored symbols!') else [~,Scpe_cell,found_sync] =Scpe_sig_raw.tsynch("reference",Symbols_mapped,"fs_ref",dataTable.symbolrate,"debug_plots",0); end if ~found_sync warning('Could not synchronize the received signal with the stored symbols!') end end record_realizations = min(options.max_occurences,length(Scpe_cell)); for occ = 4:record_realizations Scpe_sig = Scpe_cell{occ}; %%%%%% Sample to 2x fsym %%%%%% Scpe_sig = Scpe_sig.resample("fs_out",2*fsym); %%%%%% Sync Rx signal with reference %%%%%% [Scpe_sig,~] = Scpe_sig.tsynch("reference",Symbols,"fs_ref",fsym,"debug_plots",0); Scpe_sig = Filter('filtdegree',4,"f_cutoff",Symbols.fs.*0.6,"fs",Scpe_sig.fs,"filterType",filtertypes.gaussian,"active",true).process(Scpe_sig); Scpe_sig = Scpe_sig - mean(Scpe_sig.signal); if duob_mode ~= db_mode.db_encoded vnle_pf = 0; dbtgt = 0; % %%%%% VNLE + DFE %%%% if 1 eq_ = FFE_DCremoval_adaptive_mu("epochs_tr",5,"epochs_dd",3,"len_tr",4096*2,"mu_dd",... 0.0002,"mu_tr",0,"order",25,"sps",2,"decide",0,... "mu_dc",mu_dc,... "dc_buffer_len",dc_buffer_len, ... "ffe_buffer_len",ffe_buffer_len,... "smoothing_buffer_length",smoothing_buffer_length,... "smoothing_buffer_update",smoothing_buffer_update); result = vnle(eq_,M,Scpe_sig,Symbols,Tx_bits,"precode_mode",duob_mode,'showAnalysis',1,"postFFE",[],"eth_style_symbol_mapping",0); vnle_package{occ} = result; fprintf("FFE Results: %.2e\n", result.ber_vnle); if options.append_to_db database.addProcessingResult(run_id, result.resultsVNLE, result.equalizerConfigVNLE); end end %%%%% VNLE + PF + MLSE %%%% if vnle_pf [result] = vnle_postfilter_mlse(eq_,pf_,mlse_,M,Scpe_sig,Symbols,Tx_bits,"precode_mode",duob_mode,'showAnalysis',1,"postFFE",[],"eth_style_symbol_mapping",0); vnle_pf_package{occ} = result; if options.append_to_db database.addProcessingResult(run_id,result.resultsMLSE, result.equalizerConfigMLSE); database.addProcessingResult(run_id,result.resultsVNLE, result.equalizerConfigVNLE); end end %%%%% Duobinary Targeting %%%% if dbtgt [result] = duobinary_target(eq_, mlse_db_, M, Scpe_sig, Symbols, Tx_bits, "precode_mode", duob_mode,'showAnalysis',0,"postFFE",[]); dbtgt_package{occ} = result; if options.append_to_db database.addProcessingResult(run_id, result.resultsDBtgt, result.equalizerConfigDBtgt); end end % fprintf("BER VNLE: %.2e | %.2e; BER MLSE: %.2e | %.2e; BER DB tgt: %.2e | %.2e \n",vnle_pf_package{occ}.resultsVNLE.BER,vnle_pf_package{occ}.resultsVNLE.BER_precoded ,vnle_pf_package{occ}.resultsMLSE.BER,vnle_pf_package{occ}.resultsMLSE.BER_precoded,dbtgt_package{occ}.resultsDBtgt.BER,dbtgt_package{occ}.resultsDBtgt.BER_precoded) % % fprintf("BER VNLE: %.2e | %.2e; BER MLSE: %.2e | %.2e \n",vnle_pf_package{occ}.resultsVNLE.BER,vnle_pf_package{occ}.resultsVNLE.BER_precoded ,vnle_pf_package{occ}.resultsMLSE.BER,vnle_pf_package{occ}.resultsMLSE.BER_precoded); if vnle_pf % occ = 1; % or whatever your loop index is % Extract VNLE results for readability vnle_result = vnle_pf_package{occ}.resultsVNLE; mlse_result = vnle_pf_package{occ}.resultsMLSE; % Print header fprintf("==== EQUALIZATION RUN-ID %d | PAM-%d | %.2f GBd ====\n\n", run_id, M, Symbols.fs.*1e-9); s % VNLE Results fprintf(">> VNLE Results:\n"); fprintf(" BER %.2e\n", vnle_result.BER); fprintf(" BER (pre-code) %.2e\n", vnle_result.BER_precoded); fprintf(" SNR: %.2f dB\n", vnle_result.SNR); fprintf(" GMI: %.4f\n", vnle_result.GMI); fprintf(" Linerate: %.2f Gbps\n", Symbols.fs .* floor(log2(M)*10)/10 .*1e-9); fprintf(" AIR: %.2f Gbps\n", vnle_result.AIR.*1e-9); fprintf("\n"); % MLSE Results fprintf(">> MLSE Results:\n"); fprintf(" BER : %.2e\n", mlse_result.BER); fprintf(" BER (pre-code): %.2e\n", mlse_result.BER_precoded); fprintf(" Channel Alpha : %.2f\n", mlse_result.Alpha); fprintf("\n"); end if dbtgt dbtgt = dbtgt_package{occ}.resultsDBtgt; % DB Target Results fprintf(">> DB Target Results:\n"); fprintf(" BER: %.2e\n", dbtgt.BER); fprintf(" BER (pre-code): %.2e\n", dbtgt.BER_precoded); fprintf("\n"); end else %%%%%% %db signaling => db encoded %%%%% if 1 mlse_db_enc = MLSE_viterbi("DIR",[1,1],"duobinary_output",0,"M",M,"trellis_states",PAMmapper(M,0).levels); eq_db_enc = EQ("Ne",vnle_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); [result] = duobinary_signaling(eq_db_enc, mlse_db_enc,M, Scpe_sig ,Symbols, Tx_bits); dbenc_package{occ} = result; if options.append_to_db database.addProcessingResult(run_id, result.resultsDBsignaling, result.equalizerConfigDBsignaling); end end fprintf("BER DB: %.2e \n",dbenc_package{occ}.resultsDBsignaling.BER); end % autoArrangeFigures; disp('- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ') fprintf('\n') end output.dataTable = dataTable; output.vnle_pf_package = vnle_pf_package; output.vnle_package = vnle_package; output.dbtgt_package = dbtgt_package; end