function [results] = dsp_ief_file(varargin) mu_ffe1 = 0.0001; mu_ffe2 = 0.0008; mu_ffe3 = 0.001; mu_dc = 0.00; mu_dfe = 0.0004; vnle_order1 = 100; vnle_order2 = 3; vnle_order3 = 3; tcorrect = 0; %%% 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 ssdPath = "D:\36_IMDD_Kiel\Data"; % code = "20250221T004802"; % code = "20250221T032043"; filename = findFileByCode(ssdPath, filecode{1}); % Extract parameters from the filename using an updated regex tokens = regexp(filename, 'Pmod_([-0-9p]+)dBm_P_PD_([-0-9p]+)dBm_.*?_(\d+)GBd_(\d+)PAM__\d+T\d+', 'tokens'); if isempty(tokens) error('Filename format not recognized.'); end tokens = tokens{1}; % Convert values config.P_laser = str2double(strrep(tokens{1}, 'p', '.')); config.P_pd = str2double(strrep(tokens{2}, 'p', '.')); config.fsym = str2double(tokens{3}) * 1e9; % Convert GBd to Hz config.M = str2double(tokens{4}); % Display results fprintf('Loaded file: %s\n', filename); fprintf('P_laser: %.3f dBm\n', config.P_laser); fprintf('P_pd: %.3f dBm\n', config.P_pd); fprintf('fsym: %.1f GBd\n', config.fsym*1e-9); fprintf('M: %d\n', config.M); %%% Load Data filepath = fullfile(filename); ief_ = h5info(filepath); config.fs_rx = h5readatt(filepath,'/','fs'); %sampling frequency at Rx config.fs_tx = h5readatt(filepath, '/','fs_Tx'); %sampling frequency at Tx config.fsym = h5readatt(filepath, '/','R'); %Baudrate config.M = h5readatt(filepath, '/','M'); % PAM- 'M' config.ROF = h5readatt(filepath, '/','ROF'); config.PulseShape =h5readatt(filepath, '/','PulseShape'); yOrg = h5readatt(filepath, ief_.Groups(4).Groups(1).Name, 'YOrg'); yInc = h5readatt(filepath, ief_.Groups(4).Groups(1).Name, 'YInc'); dataRx = double(h5read(filepath, '/Waveforms/Channel 2/Channel 2Data')); % rohdaten des CH4 bitsTx = h5read(filepath, '/Settings/dataTx'); %Binär bitsTx = reshape(bitsTx,log2(config.M),[])'; %%% Build Tx Signal (Bits, Pam Map, Symbols) Tx_bits = Informationsignal(bitsTx); Tx_symbols = PAMmapper(config.M,0,"eth_style",1).map(Tx_bits); Tx_symbols.fs = config.fsym; %%% Build Rx Signal (Rx, normalize,remove mean) loadAfterTR = 0; if loadAfterTR rx_sig = load("testSilas.mat","signal_TR3"); rx_sig=rx_sig.signal_TR3; Rx_Sig_resamp = Informationsignal(rx_sig,"fs",config.fsym*2); else dataRx = dataRx*yInc+yOrg; Rx_Sig = Informationsignal(dataRx,"fs",config.fs_rx); Rx_Sig.signal = Rx_Sig.signal - mean(Rx_Sig.signal); Rx_Sig = Rx_Sig.normalize("mode","rms"); Rx_Sig.spectrum("fignum",2,"displayname",'Rx Signal','normalizeTo0dB',1); Rx_Sig = Filter('filtdegree',4,"f_cutoff",Tx_symbols.fs.*0.9,"fs",Rx_Sig.fs,"filterType",filtertypes.gaussian,"active",true).process(Rx_Sig); Rx_Sig.spectrum("fignum",2,"displayname",'Rx Signal filt','normalizeTo0dB',1); mf = Pulseformer("alpha",config.ROF,"fsym",config.fsym,"fdac",Rx_Sig.fs,"matched",1,"pulse","rrc","pulselength",32); Rx_matched = mf.process(Rx_Sig); Rx_matched.spectrum("fignum",2,"displayname",'Rx Signal m','normalizeTo0dB',1); %%%%%% Sample to 2x fsym %%%%%% Rx_Sig_resamp = Rx_Sig.resample("fs_out",2*config.fsym); end %%%%%% Sync Rx signal with reference (S is a cell array with all occurences) %%%%%% [Rx_Sig_sync,S,isFlipped] = Rx_Sig_resamp.tsynch("reference",Tx_symbols,"fs_ref",config.fsym,"debug_plots",1); % Rx_Sig_sync.eye(fsym,M,"fignum",4,"displayname",'eye diagram'); % timing syncroization ?? % SYMSYNC = comm.SymbolSynchronizer("Modulation","PAM/PSK/QAM","SamplesPerSymbol",2); % % synd = SYMSYNC(Rx_Sig_sync.signal); % Rx_Sig_sync.signal = synd; % % [Rx_Sig_sync,S,isFlipped] = Rx_Sig_sync.tsynch("reference",Tx_symbols,"fs_ref",config.fsym,"debug_plots",1); % % filter Bw output = struct(); vnle_package = {}; vnle_pf_package = {}; dbtgt_package = {}; for s = 1%:length(S) Rx_Sig_sync = S{s}; Rx_Sig_sync = Rx_Sig_sync.normalize("mode","rms"); if 1 Tx_symbols.spectrum("fignum",3,"displayname",'Tx Symbols','normalizeTo0dB',1); Rx_Sig_sync.spectrum("fignum",3,"displayname",'No Matched Filter','normalizeTo0dB',1); Nsym = 64; sampsPerSym = 2; rcrFilt = comm.RaisedCosineReceiveFilter(... 'Shape', 'Square root', ... 'RolloffFactor', config.ROF, ... 'FilterSpanInSymbols', Nsym, ... 'InputSamplesPerSymbol', sampsPerSym, ... 'DecimationFactor', 1); yr = rcrFilt([Rx_Sig_sync.signal;zeros(Nsym*sampsPerSym/2, 1)]); fltDelay = Nsym / (2*config.fsym); yr = yr(fltDelay*Rx_Sig_sync.fs+1:end); Rx_matched = Rx_Sig_sync; Rx_matched.signal = yr; % Rx_matched = Rx_matched.resample("fs_out",2*config.fsym); % length(Rx_matched); % symbolSync = comm.SymbolSynchronizer("Modulation","PAM/PSK/QAM","SamplesPerSymbol",2,"TimingErrorDetector","Mueller-Muller (decision-directed)"); % Rx_syncd = Rx_matched; % [Rx_syncd.signal,tError] = symbolSync(Rx_syncd.signal); % Rx_syncd.fs = config.fsym; % length(Rx_syncd); % figure();hold on; % stem(Tx_symbols.normalize("mode","oneone").signal); % stem(Rx_syncd.normalize("mode","oneone").signal); % % figure();hold on; % plot(Rx_Sig_sync.normalize("mode","oneone").signal); % plot(Rx_matched.normalize("mode","oneone").signal); Rx_syncd = Rx_syncd.resample("fs_out",2*config.fsym); Rx_matched.spectrum("fignum",3,"displayname",'After Matched Filter','normalizeTo0dB',1); Rx_syncd.spectrum("fignum",3,"displayname",'Zero Crossing TR','normalizeTo0dB',1); end mu_ffe = [mu_ffe1 mu_ffe3 mu_ffe3]; vnle_order=[vnle_order1,vnle_order2,vnle_order3]; eq_ = EQ("Ne",vnle_order,"Nb",[0,0,0],"training_length",4096*2,"training_loops",5,"dd_loops",5,"K",2,"DCmu",mu_dc,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",1,"ideal_dfe",1); %%%%% VNLE only (or DFE) %%%% if 1 [result] = vnle(eq_,config.M,Rx_syncd,Tx_symbols,Tx_bits,"precode_mode",db_mode.no_db,"showAnalysis",1,'eth_style',1); vnle_package{s} = result; end %%%%% VNLE + PF + MLSE %%%% if 0 pf_ = Postfilter("ncoeff",1,"useBurg",1); mlse_ = MLSE_viterbi("duobinary_output",0,'M',config.M,'trellis_states',PAMmapper(config.M,0).levels); doub_mode = db_mode.no_db; [result] = vnle_postfilter_mlse(eq_,pf_,mlse_,config.M,Rx_Sig_sync,Tx_symbols,Tx_bits,"precode_mode",doub_mode,'showAnalysis',1,'eth_style_symbol_mapping',1); vnle_pf_package{s} = result; end %%%%% Duobinary Targeting %%%% if 0 mlse_db = MLSE_viterbi("DIR",[1,1],"duobinary_output",0,"M",config.M,"trellis_states",PAMmapper(config.M,0).levels); doub_mode = db_mode.db_emulate; [result] = duobinary_target(eq_, mlse_db, config.M, Rx_Sig_sync, Tx_symbols, Tx_bits, "precode_mode", doub_mode,'showAnalysis',1,'eth_style_symbol_mapping',1); dbtgt_package{s} = result; end end results.vnle_package = vnle_package; results.vnle_pf_package = vnle_pf_package; results.dbtgt_package = dbtgt_package; end