function BER = first_analysis_optimize(baud_rate, power, num_pf_coeff, taps_ffe, taps_dfe, M, trlength) %% base = "C:\Users\magf\Desktop\Desktop\MATLAB-Zeugs\FSO Equalizer\Sweep Data\"; mode = 0; %0 oder 1 % M = 2; all_files = dir(fullfile(base, "**/*.mat")); if M == 2 tx_data_path = fullfile(base, "14G_PAM2\tx_info\tx_info_PAM2_14Gbd0.75RRC.mat"); filename = fullfile(base, "14G_PAM2\M=2_Rs=1.4e10_Fs=8e10_I=" + current + "mA_RoP=" + power + "mW_L=31m_PS=RRC_rolloff=0.75_Mode=Rise.mat"); elseif M == 4 tx_data_path = fullfile(base, baud_rate + "G_PAM4\tx_info\tx_info_PAM4_" + baud_rate + "Gbd0.6RRC.mat"); filename = fullfile(base, baud_rate + "G_PAM4\M=4_Rs="+ baud_rate + "e9_Fs=8e10_I=255mA_RoP=" + power + "mW_L=31m_PS=RRC_rolloff=0.6_Mode=Rise.mat"); end if mode == 1 [f, p] = uigetfile(fullfile(base, "**/*.mat")); if f~=0 filename = fullfile(p,f); end end tx_data = load(tx_data_path); datas = load(filename); %% str = filename; M_ = str2double(regexp(str, 'M=([^_]+)', 'tokens', 'once')); assert(M==M_); fsym = str2double(regexp(str, 'Rs=([^_]+)', 'tokens', 'once')); fs = str2double(regexp(str, 'Fs=([^_]+)', 'tokens', 'once')); I = sscanf(char(regexp(str, 'I=([^_]+)', 'tokens', 'once')), '%f'); rop = sscanf(char(regexp(str, 'RoP=([^_]+)', 'tokens', 'once')), '%f'); L = sscanf(char(regexp(str, 'L=([^_]+)', 'tokens', 'once')), '%f'); pulseshape = string( regexp(str, 'PS=([^_]+)', 'tokens', 'once')); rolloff = str2double(regexp(str, 'rolloff=([^_]+)', 'tokens', 'once')); mode = string( regexp(str, 'Mode=([^\.]+)', 'tokens', 'once')); %% % Tx data Bits = Informationsignal(tx_data.tx_data,"fs",fsym); Symbols = Informationsignal(real(tx_data.tx_PAM_sym),"fs",fsym); mapping_style = M==4; % Pam2 is like move-it; PAM-4 is different, same mapping like ETH peopled used in Zurich... hence the "eth_style" argument here and there PM = PAMmapper(M,0,"eth_style",mapping_style); % one should rename "eth style" as this is simply a different mapping scheme Symbols_ = PM.map(Bits) .* PM.scaling; assert(isequal(Symbols.signal,Symbols_.signal)); Bits_ = PM.demap(Symbols); [bits,errors,ber,errorIndice] = calc_ber(Bits_.signal,Bits.signal); assert(ber == 0); %% For comparison, apply pulsef on Tx Symbols Pform = Pulseformer("fsym",fsym,"fdac",fs,"pulse","rrc","pulselength",16,"alpha",rolloff); Digi_sig_compare = Pform.process(Symbols); MF = Pulseformer("fsym",fsym,"fdac",2*fsym,"pulse","rrc","pulselength",16,"alpha",rolloff); Rx_sig_compare = MF.process(Digi_sig_compare); %% % Rx Data traceData = datas.tr.lastData(2).trace.ch3; %FYI: Voltage=(RawData−YReference)×YIncrement+YOrigin scoperead_volts = (traceData.RawData - traceData.YReference) * traceData.YIncrement + traceData.YOrigin; demystified = isequal(traceData.YData,scoperead_volts); assert(demystified); Scope_sig = Electricalsignal(traceData.YData,"fs",fs); Scope_sig.plot("displayname",'raw','fignum',100); Scope_sig.spectrum("displayname",'raw','fignum',101) % 1) matched filter % pulse is symmetric, hence we can use pulsef firectly as matched filter. % It feels off (bit I think correct) that the fsym is now the output freq.!! % -> output 2 sps to omit timing recovery!? Matched_Filter = Pulseformer("fsym",fsym,"fdac",2*fsym,"pulse","rrc","pulselength",16,"alpha",rolloff,"matched",1); Rx_matched = Matched_Filter.process(Scope_sig); Rx_matched.spectrum("displayname",'Signal after matched filter','fignum',1); % timing sync -> at this point we still have no symbol timing recovery, we % try to do this with 2sps EQ! [~,Rx_synced_cell,inverted,sequenceFound,sequenceStarts] = Rx_matched.tsynch("reference", Symbols, "fs_ref", fsym, "debug_plots", 1); Rx_matched_1 = Rx_synced_cell{1}; % Rx_Time_Rec = Rx_matched; % Rx_Time_Rec = Timing_Recovery_Move_It('f_sim', 28e9, 'gamma', 0.1).process(Rx_matched_1); Time_Rec = 1; if Time_Rec [Rx_Time_Rec, Timing_Error] = Timing_Recovery("modulation", 'PAM/PSK/QAM', "timing_error_detector",'Gardner (non-data-aided)','sps',2,'damping_factor',0.0123793,'normalized_loop_bandwidth',4.50865e-06,'detector_gain',3.33311).process(Rx_matched_1); sps = 1; else sps = 2; end baud_rate_num = str2double(baud_rate); Rx_Time_Rec.fs = baud_rate_num*10^9; % Rx_Time_Rec.signal = resample(Rx_Time_Rec.signal, 12e9, 6e9); % Rx_matched_1.plot("fignum",231231) % Rx_Time_Rec.plot("fignum",231231) %% not working.. Rx_synced = Rx_Time_Rec; % Rx_synced = Rx_synced_cell{1}; len_tr = trlength; mu_ffe1 = 0.0001; mu_ffe2 = 0.0008; mu_ffe3 = 0.001; mu_dc = 0.004; mu_ffe = [mu_ffe1 mu_ffe3 mu_ffe3]; mu_dfe = 0.0004; duob_mode = db_mode.no_db; Rx_synced.plot("displayname",'RX: Matched+Sync+2sps','fignum',103); Rx_synced.spectrum("displayname",'RX: Matched+Sync+2sps','fignum',104); Digi_sig_compare.normalize("mode","rms").spectrum("displayname",'Tx: RC-shaped','fignum',1,'normalizeTo0dB',1); Rx_sig_compare.normalize("mode","rms").spectrum("displayname",'Tx: RC-shaped + matched filtered ','fignum',1,'normalizeTo0dB',1); Rx_synced.normalize("mode","rms").spectrum("displayname",'RX: matched filtered + synced','fignum',1,'normalizeTo0dB',1); if M == 2 ber_in_paper = 10^(-2.6); %fig 3a) 4 Gb/s MWIR FSO Transmission using Directly Modulated QCL and an Uncooled UTC-PD at Room-Temperature elseif M == 4 ber_in_paper = 10^(-2.5); end %% -------------------- FFE -------------------- % % requires some more digging what is going on :-) % eq_ffe = EQ("Ne",[400, 0, 0],"Nb",[0,0,0], ... % "training_length",len_tr,"training_loops",5,"dd_loops",5, ... % "K",sps,"DCmu",mu_dc,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005, ... % "FFEmu",0,"plotfinal",0,"ideal_dfe",1); % % ffe_results = ffe(eq_ffe,M,Rx_synced,Symbols,Bits, ... % "precode_mode",duob_mode,'showAnalysis',0,"postFFE",[], ... % "eth_style_symbol_mapping",mapping_style); % % % ffe_results.metrics.print % fprintf('My EQ: %.1e \n',ffe_results.metrics.BER); % fprintf('Paper: %.1e \n \n',ber_in_paper); % BER_value = ffe_results.metrics.BER; %% -------------------- VNLE + MLSE -------------------- pf_ncoeffs = num_pf_coeff; eq_v = EQ("Ne",taps_ffe,"Nb",taps_dfe, ... "training_length",len_tr,"training_loops",5,"dd_loops",5, ... "K",sps,"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("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0,"eth_style",mapping_style).levels); [vnle_results, mlse_results] = vnle_postfilter_mlse(eq_v, pf_, mlse_, M, Rx_synced, Symbols, Bits, ... "precode_mode", duob_mode, 'showAnalysis', 1, "postFFE", [], "eth_style_symbol_mapping", mapping_style); mlse_results.metrics.print fprintf('My EQ: %.1e \n',mlse_results.metrics.BER); fprintf('Paper: %.1e \n \n',ber_in_paper); BER = mlse_results.metrics.BER; %% -------------------- ML-based MLSE (L=2) -------------------- % ml_mlse_equalizer = ML_MLSE("epochs_tr",150,"epochs_dd",1, ... % "len_tr",length(Rx_synced),"mu_dd",0.03,"mu_tr",0.03,"order",80,"sps",1, ... % "traceback_depth",256,"L",1,"delta",4,"adaptive_mu",0); % % [ml_mlse_results] = ml_mlse(ml_mlse_equalizer, M, Rx_synced, Symbols, Bits,"precode_mode",duob_mode,"eth_style_symbol_mapping",mapping_style); % fprintf('ML-based MLSE:\n'); % fprintf('My EQ: %.1e \n',ml_mlse_results.metrics.BER); % fprintf('Paper: %.1e \n \n',ber_in_paper); end