249 lines
9.4 KiB
Matlab
249 lines
9.4 KiB
Matlab
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_ffe1 = 0;
|
|
% mu_ffe2 = 0;
|
|
% mu_ffe3 = 0;
|
|
% mu_dfe =0;
|
|
% mu_dc = 0.00;
|
|
|
|
mu_ffe = [mu_ffe1 mu_ffe2 mu_ffe3];
|
|
vnle_order=[vnle_order1,vnle_order2,vnle_order3];
|
|
|
|
% 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_dfe_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 = 1: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 = 1;
|
|
dbtgt = 0;
|
|
% %%%%% VNLE + DFE %%%%
|
|
if 0
|
|
|
|
eq_vnle_dfe = EQ("Ne",vnle_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);
|
|
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);
|
|
|
|
[result] = vnle(eq_vnle_dfe,M,Scpe_sig,Symbols,Tx_bits,"precode_mode",duob_mode,"showAnalysis",1,"postFFE",[]);
|
|
vnle_dfe_package{occ} = result;
|
|
|
|
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 = vnle_pf_package{occ}.resultsVNLE;
|
|
mlse = 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);
|
|
|
|
% VNLE Results
|
|
fprintf(">> VNLE Results:\n");
|
|
fprintf(" BER %.2e\n", vnle.BER);
|
|
fprintf(" BER (pre-code) %.2e\n", vnle.BER_precoded);
|
|
fprintf(" SNR: %.2f dB\n", vnle.SNR);
|
|
fprintf(" GMI: %.4f\n", vnle.GMI);
|
|
fprintf(" Linerate: %.2f Gbps\n", Symbols.fs .* floor(log2(M)*10)/10 .*1e-9);
|
|
fprintf(" AIR: %.2f Gbps\n", vnle.AIR.*1e-9);
|
|
fprintf("\n");
|
|
|
|
% MLSE Results
|
|
fprintf(">> MLSE Results:\n");
|
|
fprintf(" BER : %.2e\n", mlse.BER);
|
|
fprintf(" BER (pre-code): %.2e\n", mlse.BER_precoded);
|
|
fprintf(" Channel Alpha : %.2f\n", mlse.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.dbtgt_package = dbtgt_package;
|
|
|
|
end |