function [output] = dsp_mpi(varargin) simulation_mode = 0; %%% Change folder curFolder = pwd; funcFolder=fileparts(mfilename('fullpath')); if ~isempty(funcFolder) cd(funcFolder); end %%% Run parameters % TX M = 4; fsym = 180e9; apply_pulsef = 1; fdac = 256e9; fadc = 256e9; random_key = 1; interference_attenuation = 0; is_mpi = 1; precomp = 0; db_precode = 0; db_encode = 0; rcalpha = 0.05; kover = 16; vbias_rel = 0.5; u_pi = 2.9; vbias = -vbias_rel*u_pi; laser_wavelength = 1293; laser_linewidth = 0; tx_bw_nyquist = 0.8; % Channel link_length = 1; % RX rop = -5; rx_bw_nyquist = 0.8; vnle_order1 = 50; vnle_order2 = 5; vnle_order3 = 5; vnle_order=[vnle_order1,vnle_order2,vnle_order3]; dfe_order = [0 0 0]; pf_ncoeffs = 1; alpha = 0; len_tr = 4096*2; mu_ffe1 = 0.0001; mu_ffe2 = 0.0008; mu_ffe3 = 0.001; mu_dc = 0.005; mu_dc = 0; mu_ffe = [mu_ffe1 mu_ffe3 mu_ffe3]; mu_dfe = 0.0004; dfe_ = sum(dfe_order)>0; doub_mode = db_mode.no_db; %%% change specific parameter if given in varargin % Parse optional input arguments if ~isempty(varargin) var_s = varargin{1}; if isstruct(var_s) fields = fieldnames(var_s); for i = 1:numel(fields) if isnumeric(fields{i}) eval([fields{i}, ' = ', num2str( var_s.(fields{i}) ), ';']); fprintf("%s <-- %.2f \n", fields{i}, var_s.(fields{i})); else eval([fields{i}, ' = ', 'var_s.(fields{',num2str(i),'})' , ';']); end end else error('Optional variables should be passed as a struct.'); end end if doub_mode ~= db_mode.db_encoded if precomp == 0 && db_precode == 1 doub_mode = db_mode.db_precoded; db_precode = 1; % preceded data (in my measurement set, this corresponds to low precomp too!) discard_precode = 0; % emulate_precode = 0; legendentry = 'low precomp; precoded'; disp('low precomp; precoded') elseif precomp == 1 && db_precode == 1 doub_mode = db_mode.db_emulate; db_precode = 0; % preceded data (in my measurement set, this corresponds to low precomp too!) discard_precode = 0; % emulate_precode = 1; legendentry = 'high precomp; precoded'; disp('high precomp; precoded') elseif precomp == 0 && db_precode == 0 doub_mode = db_mode.db_discard; db_precode = 1; % preceded data (in my measurement set, this corresponds to low precomp too!) discard_precode = 1; % emulate_precode = 0; legendentry = 'no precomp; not precoded'; disp('no precomp; not precoded') elseif precomp == 1 && db_precode == 0 doub_mode = db_mode.no_db; db_precode = 0; % preceded data (in my measurement set, this corresponds to low precomp too!) discard_precode = 0; % emulate_precode = 0; legendentry = 'high precomp; not precoded'; disp('high precomp; not precoded') end else end fsym_ = floor( bitrate*1e-9./log2(M) ).*1e9; if fsym_ ~= fsym fsym = fsym_; % fprintf('Adapted symbolrate to %d GBd, to match provided bitrate of %d GBit/s using PAM %d \n',fsym.*1e-9,bitrate.*1e-9, M); end f_nyquist = fsym/2; basePath = 'C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor\'; database = DBHandler("pathToDB",[basePath,'silas_labor.db']); useGui = 0; % db = DBHandler("pathToDB",[basePath,'silas_labor.db']); filterParams = database.tables; % filterParams.Runs.run_id = 2958; % no db % filterParams.Runs.run_id = 2937; % no db filterParams.Configurations = struct( ... 'bitrate', bitrate, ... 'db_mode', db_precode+db_encode, ... 'fiber_length', link_length, ... 'interference_attenuation', [], ... 'interference_path_length', [], ... 'is_mpi', is_mpi, ... 'pam_level', M, ... 'precomp_amp', [], ... 'rop_attenuation', 0, ... 'symbolrate', [], ... 'v_awg', [], ... 'v_bias', [], ... 'wavelength', laser_wavelength ... ); selectedFields = {'Runs.run_id','Runs.tx_bits_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 fprintf('Found %d entries for requested Configuration. IDs are: %s \n \n',size(dataTable,1),jsonencode(dataTable.run_id(1:min(size(dataTable,1),100)))); output = struct(); vnle_pf_package = {}; vnle_dfe_package = {}; dbtgt_package = {}; disp(num2str(bitrate)) for iatt = 1:numel(dataTable.interference_attenuation) current_run_id = dataTable.run_id(iatt); Tx_bits = load([basePath, char(dataTable.tx_bits_path(iatt))]); Tx_bits = Tx_bits.Bits; Symbols_mapped = PAMmapper(M,0).map(Tx_bits); Symbols_mapped.fs = fsym; Symbols = load([basePath, char(dataTable.tx_symbols_path(iatt))]); Symbols = Symbols.Symbols; Scpe_load = load([basePath, char(dataTable.rx_sync_path(iatt))]); Scpe_cell = Scpe_load.S; [~,~,found]=Scpe_cell{2}.tsynch("reference",Symbols,"fs_ref",fsym,"debug_plots",1); if ~found Raw_signal = load([basePath, char(dataTable.rx_raw_path(1))]); Raw_signal = Raw_signal.Scpe_sig_raw; [~,Scpe_cell,found] =Raw_signal.tsynch("reference",Symbols,"fs_ref",fsym,"debug_plots",1); end if ~found 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] =Raw_signal.tsynch("reference",Symbols_mapped,"fs_ref",fsym,"debug_plots",0); end if ~found warning('Could not synchronize the received signal with the stored symbols!') end end fsym = Symbols.fs; if db_precode Symbols_precoded = Symbols; end proc_occ = min(15,length(Scpe_cell)); for occ = 1:proc_occ 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.5,"fs",Scpe_sig.fs,"filterType",filtertypes.gaussian,"active",true).process(Scpe_sig); Scpe_sig = Scpe_sig - mean(Scpe_sig.signal); %%% EQUALIZING % eq_mlse = FFE_DCremoval("epochs_tr",5,"epochs_dd",5,"len_tr",len_tr,"mu_dd",mu_ffe(1),"mu_tr",0,"order",ffe_order(1),"sps",2,"decide",0,"dc_buffer_len",1,"mu_dc",0.05); % eq_mlse = FFE("epochs_tr",5,"epochs_dd",5,"len_tr",len_tr,"mu_dd",mu_ffe(1),"mu_tr",0,"order",ffe_order(1),"sps",2,"decide",0); % eq_mlse = FFE_DCremoval("epochs_tr",5,"epochs_dd",5,"len_tr",len_tr,"mu_dd",mu_ffe(1),"mu_tr",0,"order",ffe_order(1),"sps",2,"decide",0,"dc_buffer_len",512,"mu_dc",0.05); mu_ffe = [mu_ffe1 mu_ffe2 mu_ffe3]; vnle_order=[vnle_order1,vnle_order2,vnle_order3]; % %%%%% 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_2 = 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",doub_mode,"showAnalysis",1,"postFFE",[]); vnle_dfe_package{iatt,occ} = result; end %%%%% VNLE + PF + MLSE %%%% if 1 try % len_tr = length(Symbols)-1000; eq_vnle_ = 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); % eq_vnle_ = VNLE("epochs_tr",5,"epochs_dd",5,"len_tr",4096*2,"mu_dd",[0.0004 0.0005 0.0006],"mu_tr",0,"order",vnle_order,"sps",2,"decide",0); pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1); mlse_ = MLSE_viterbi("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels); eq_2 = 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_postfilter_mlse(eq_vnle_,pf_,mlse_,M,Scpe_sig,Symbols,Tx_bits,"precode_mode",doub_mode,'showAnalysis',0,"postFFE",[]); vnle_pf_package{iatt,occ} = result; database.addProcessingResult(current_run_id,result.resultsMLSE, result.equalizerConfigMLSE); database.addProcessingResult(current_run_id,result.resultsVNLE, result.equalizerConfigVNLE); catch warning(['VNLE+MLSE fail: run id: ', num2str(current_run_id)],' occ:', num2str(occ), ' iatten: ',num2str(iatt)) end end %%%%% Duobinary Targeting %%%% if 1 try mlse_db = MLSE_viterbi("DIR",[1,1],"duobinary_output",0,"M",M,"trellis_states",PAMmapper(M,0).levels); eq_db = 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); eq_2 = 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] = duobinary_target(eq_db, mlse_db, M, Scpe_sig, Symbols, Tx_bits, "precode_mode", doub_mode,'showAnalysis',0,"postFFE",[]); dbtgt_package{iatt,occ} = result; database.addProcessingResult(current_run_id,result.resultsDBtgt, result.equalizerConfigDBtgt); catch warning(['VNLE DB+MLSE fail: run id: ', num2str(current_run_id)],' occ:', num2str(occ), ' iatten: ',num2str(iatt)) end end %%%%%% %db signaling => db encoded %%%%% if 0 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{iatt,occ} = result; end % autoArrangeFigures; disp('- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ') fprintf('\n') end if ~isempty(curFolder) cd(curFolder); end end output.dataTable = dataTable; output.vnle_dfe_package = vnle_dfe_package; output.vnle_pf_package = vnle_pf_package; output.dbtgt_package = dbtgt_package;