Merge branch 'main' of https://cau-git.rz.uni-kiel.de/nt/mitarbeiter/silas/imdd_simulation
This commit is contained in:
@@ -3,30 +3,30 @@
|
||||
params = struct;
|
||||
|
||||
params.M = [4];
|
||||
params.datarate = [250];
|
||||
params.rop = [-10];
|
||||
params.sir = 40;%15:1:40;
|
||||
params.random_key_laser_phase = 1;
|
||||
params.datarate = [448];
|
||||
params.rop = [0];
|
||||
params.sir = 45;
|
||||
params.random_key_laser_phase = 10:20;
|
||||
|
||||
precomp_mode = 0; %0=do nothing ; 1= measure; 2=precomp active
|
||||
postfilter = 0; % noise whiten. approach -> Postfilter + MLSE
|
||||
postfilter = 1; % noise whiten. approach -> Postfilter + MLSE
|
||||
|
||||
db_precode = 0;
|
||||
db_encode = 0;
|
||||
db_channelapproach = 1;
|
||||
db_channelapproach = 0;
|
||||
|
||||
laser_linewidth = 0e5;
|
||||
laser_linewidth = 5e5;
|
||||
random_key_sequence = 15;
|
||||
random_key_laser_phase = 66;
|
||||
sir = 60;
|
||||
sir = 20;
|
||||
|
||||
if ismac
|
||||
precomp_path = "/Users/silasoettinghaus/Documents/MATLAB/imdd_simulation/projects/standard_system";
|
||||
else
|
||||
precomp_path = "C:\Users\sioe\Documents\MATLAB\imdd_simulation\projects\standard_system\";
|
||||
precomp_path = "C:\Users\Silas\Documents\MATLAB\imdd_simulation\projects\standard_system\";
|
||||
end
|
||||
|
||||
precomp_fn = "400G_simulative_setup_meas";
|
||||
precomp_fn = "400G_simulative_setup";
|
||||
|
||||
usemrds = 0;
|
||||
|
||||
@@ -47,130 +47,130 @@ disp(['Start Simulation of ',num2str(endcnt),' loops...'])
|
||||
tic
|
||||
|
||||
for random_key_laser_phase = wh.parameter.random_key_laser_phase.values
|
||||
for M = wh.parameter.M.values
|
||||
for datarate = wh.parameter.datarate.values
|
||||
for M = wh.parameter.M.values
|
||||
for datarate = wh.parameter.datarate.values
|
||||
|
||||
% SETUP HERE: %%
|
||||
kover = 16;
|
||||
M8199 = M8199B("kover",kover);
|
||||
fdac = M8199.fdac;
|
||||
fsym = round(datarate / log2(M)) * 1e9;
|
||||
rrcalpha = 0.05;
|
||||
Pform = Pulseformer("fsym",fsym,"fdac",4*fsym,"pulse","rrc","pulselength",16,"rrcalpha",rrcalpha);
|
||||
% SETUP HERE: %%
|
||||
kover = 16;
|
||||
M8199 = M8199B("kover",kover);
|
||||
fdac = M8199.fdac;
|
||||
fsym = round(datarate / log2(M)) * 1e9;
|
||||
rrcalpha = 0.05;
|
||||
Pform = Pulseformer("fsym",fsym,"fdac",4*fsym,"pulse","rrc","pulselength",16,"rrcalpha",rrcalpha);
|
||||
|
||||
% MAIN SIGNAL
|
||||
% MAIN SIGNAL
|
||||
|
||||
%%%%% Symbol Generation MAIN %%%%%%
|
||||
[Digi_sig,Symbols,Bits] = PAMsource("fsym",fsym,"M",M,"order",18,"useprbs",1,...
|
||||
"fs_out",M8199.fdac,"applyclipping",0,"clipfactor",1.5,...
|
||||
"applypulseform",0,"pulseformer",Pform,"randkey",random_key_sequence,...
|
||||
"db_precode",db_precode,"db_encode",db_encode,...
|
||||
"mrds_code",usemrds,"mrds_blocklength",512).process();
|
||||
%%%%% Symbol Generation MAIN %%%%%%
|
||||
[Digi_sig,Symbols,Bits] = PAMsource("fsym",fsym,"M",M,"order",19,"useprbs",1,...
|
||||
"fs_out",M8199.fdac,"applyclipping",0,"clipfactor",1.5,...
|
||||
"applypulseform",0,"pulseformer",Pform,"randkey",random_key_sequence,...
|
||||
"db_precode",db_precode,"db_encode",db_encode,...
|
||||
"mrds_code",usemrds,"mrds_blocklength",512).process();
|
||||
|
||||
%%%%% Symbol Generation INTERFERENCE %%%%%%
|
||||
[Digi_sig_I,Symbols_I,Bits_I] = PAMsource("fsym",fsym,"M",M,"order",18,"useprbs",0,...
|
||||
"fs_out",M8199.fdac,"applyclipping",0,"clipfactor",1.5,...
|
||||
"applypulseform",0,"pulseformer",Pform,"randkey",random_key_sequence+1,...
|
||||
"db_precode",db_precode,"db_encode",db_encode,...
|
||||
"mrds_code",usemrds,"mrds_blocklength",512).process();
|
||||
%%%%% Symbol Generation INTERFERENCE %%%%%%
|
||||
[Digi_sig_I,Symbols_I,Bits_I] = PAMsource("fsym",fsym,"M",M,"order",19,"useprbs",0,...
|
||||
"fs_out",M8199.fdac,"applyclipping",0,"clipfactor",1.5,...
|
||||
"applypulseform",0,"pulseformer",Pform,"randkey",random_key_sequence+1,...
|
||||
"db_precode",db_precode,"db_encode",db_encode,...
|
||||
"mrds_code",usemrds,"mrds_blocklength",512).process();
|
||||
|
||||
% Digi_sig.eye(fsym,M);
|
||||
% Digi_sig.normalize("mode","rms").spectrum("displayname",'Tx Signal','fignum',10);
|
||||
% Digi_sig.eye(fsym,M);
|
||||
% Digi_sig.normalize("mode","rms").spectrum("displayname",'Tx Signal','fignum',10);
|
||||
|
||||
if precomp_mode == 1 %measure
|
||||
precomp_est = ChannelFreqResp("Nacq",1024,"Navg",64,"Ncp",63,'f_ref',Digi_sig.fs);
|
||||
Digi_sig = precomp_est.buildOFDM();
|
||||
Digi_sig_I = precomp_est.buildOFDM();
|
||||
elseif precomp_mode == 2 %apply
|
||||
Digi_sig = ChannelFreqResp("Nacq",1024,"Navg",64,"Ncp",63,'f_ref',Digi_sig.fs).precomp(Digi_sig,'maxampdb',3,'loadPath',precomp_path,'fileName',precomp_fn);
|
||||
Digi_sig_I = ChannelFreqResp("Nacq",1024,"Navg",64,"Ncp",63,'f_ref',Digi_sig_I.fs).precomp(Digi_sig_I,'maxampdb',3,'loadPath',precomp_path,'fileName',precomp_fn);
|
||||
Digi_sig.spectrum("fignum",11,"displayname",'after precomp');
|
||||
end
|
||||
if precomp_mode == 1 %measure
|
||||
freqresp = ChannelFreqResp("Nacq",1024,"Navg",64,"Ncp",63,'f_ref',Digi_sig.fs);
|
||||
Digi_sig = freqresp.buildOFDM();
|
||||
Digi_sig_I = freqresp.buildOFDM();
|
||||
elseif precomp_mode == 2 %apply
|
||||
Digi_sig = ChannelFreqResp("Nacq",1024,"Navg",64,"Ncp",63,'f_ref',Digi_sig.fs).precomp(Digi_sig,'maxampdb',3,'loadPath',precomp_path,'fileName',precomp_fn);
|
||||
Digi_sig_I = ChannelFreqResp("Nacq",1024,"Navg",64,"Ncp",63,'f_ref',Digi_sig_I.fs).precomp(Digi_sig_I,'maxampdb',3,'loadPath',precomp_path,'fileName',precomp_fn);
|
||||
Digi_sig.spectrum("fignum",11,"displayname",'after precomp');
|
||||
end
|
||||
|
||||
|
||||
|
||||
%%%%% AWG MAIN %%%%%%
|
||||
El_sig = M8199.process(Digi_sig);
|
||||
%%%%% AWG MAIN %%%%%%
|
||||
El_sig = M8199.process(Digi_sig);
|
||||
|
||||
%%%%% Lowpass el. components %%%%%%
|
||||
El_sig = Filter('filtdegree',2,"f_cutoff",100e9,"fs",fdac*kover,"filterType",filtertypes.butterworth,"active",true).process(El_sig);
|
||||
%%%%% Lowpass el. components %%%%%%
|
||||
El_sig = Filter('filtdegree',2,"f_cutoff",100e9,"fs",fdac*kover,"filterType",filtertypes.butterworth,"active",true).process(El_sig);
|
||||
|
||||
%%%%% Electrical Driver Amplifier %%%%%%
|
||||
El_sig = Amplifier("amp_mode","ideal_no_noise","gain_mode","gain","amplification_db",3).process(El_sig);
|
||||
%%%%% Electrical Driver Amplifier %%%%%%
|
||||
El_sig = Amplifier("amp_mode","ideal_no_noise","gain_mode","gain","amplification_db",3).process(El_sig);
|
||||
|
||||
fprintf('Driver output power: %s dBm\n', num2str(El_sig.power));
|
||||
fprintf('Driver output peak voltage: %s Vpp \n', num2str(max(El_sig.signal)-min(El_sig.signal)));
|
||||
fprintf('Driver output power: %s dBm\n', num2str(El_sig.power));
|
||||
fprintf('Driver output peak voltage: %s Vpp \n', num2str(max(El_sig.signal)-min(El_sig.signal)));
|
||||
|
||||
% El_sig.spectrum("displayname",'Transmit PDS','fignum',10);
|
||||
% El_sig.spectrum("displayname",'Transmit PDS','fignum',10);
|
||||
|
||||
%%%%% AWG INTERFERENCE %%%%%%
|
||||
El_sig_I = M8199.process(Digi_sig_I);
|
||||
%%%%% AWG INTERFERENCE %%%%%%
|
||||
El_sig_I = M8199.process(Digi_sig_I);
|
||||
|
||||
%%%%% Lowpass el. components %%%%%%
|
||||
El_sig_I = Filter('filtdegree',3,"f_cutoff",100e9,"fs",fdac*kover,"filterType",filtertypes.butterworth,"active",true).process(El_sig_I);
|
||||
%%%%% Lowpass el. components %%%%%%
|
||||
El_sig_I = Filter('filtdegree',3,"f_cutoff",100e9,"fs",fdac*kover,"filterType",filtertypes.butterworth,"active",true).process(El_sig_I);
|
||||
|
||||
%%%%% Electrical Driver Amplifier %%%%%%
|
||||
El_sig_I = Amplifier("amp_mode","ideal_no_noise","gain_mode","gain","amplification_db",3).process(El_sig_I);
|
||||
%%%%% Electrical Driver Amplifier %%%%%%
|
||||
El_sig_I = Amplifier("amp_mode","ideal_no_noise","gain_mode","gain","amplification_db",3).process(El_sig_I);
|
||||
|
||||
|
||||
|
||||
|
||||
% MAIN SIGNAL
|
||||
%%%%% MODULATE E/O CONVERSION %%%%%%
|
||||
vbias_rel = 0.7;
|
||||
u_pi = 2.9;
|
||||
vbias = -vbias_rel*u_pi;
|
||||
% MAIN SIGNAL
|
||||
%%%%% MODULATE E/O CONVERSION %%%%%%
|
||||
vbias_rel = 0.5;
|
||||
u_pi = 2.9;
|
||||
vbias = -vbias_rel*u_pi;
|
||||
|
||||
[Opt_sig] = EML("mode",eml_mode.im_cosinus,"power",3,"fsimu",El_sig.fs,"lambda",1290,"bias",vbias,"u_pi",u_pi,"linewidth",laser_linewidth,"randomkey",random_key_laser_phase).process(El_sig);
|
||||
Optfilter = Filter('filtdegree',3,"f_cutoff",110e9,"fs",fdac*kover,"filterType",filtertypes.gaussian,"active",true);
|
||||
Opt_sig = Optfilter.process(Opt_sig);
|
||||
Opt_sig = Amplifier("amp_mode","ideal_no_noise","gain_mode","output_power","amplification_db",0).process(Opt_sig);
|
||||
[Opt_sig] = EML("mode",eml_mode.im_cosinus,"power",3,"fsimu",El_sig.fs,"lambda",1290,"bias",vbias,"u_pi",u_pi,"linewidth",laser_linewidth,"randomkey",random_key_laser_phase).process(El_sig);
|
||||
Optfilter = Filter('filtdegree',3,"f_cutoff",110e9,"fs",fdac*kover,"filterType",filtertypes.gaussian,"active",true);
|
||||
Opt_sig = Optfilter.process(Opt_sig);
|
||||
Opt_sig = Amplifier("amp_mode","ideal_no_noise","gain_mode","output_power","amplification_db",0).process(Opt_sig);
|
||||
|
||||
[Opt_sig_I] = EML("mode",eml_mode.im_cosinus,"power",3,"fsimu",El_sig_I.fs,"lambda",1290,"bias",vbias,"u_pi",u_pi,"linewidth",laser_linewidth,"randomkey",random_key_laser_phase+1).process(El_sig_I);
|
||||
Optfilter = Filter('filtdegree',3,"f_cutoff",110e9,"fs",fdac*kover,"filterType",filtertypes.gaussian,"active",true);
|
||||
Opt_sig_I = Optfilter.process(Opt_sig_I);
|
||||
Opt_sig_I = Amplifier("amp_mode","ideal_no_noise","gain_mode","output_power","amplification_db",0).process(Opt_sig_I);
|
||||
[Opt_sig_I] = EML("mode",eml_mode.im_cosinus,"power",3,"fsimu",El_sig_I.fs,"lambda",1290,"bias",vbias,"u_pi",u_pi,"linewidth",laser_linewidth,"randomkey",random_key_laser_phase+1).process(El_sig_I);
|
||||
Optfilter = Filter('filtdegree',3,"f_cutoff",110e9,"fs",fdac*kover,"filterType",filtertypes.gaussian,"active",true);
|
||||
Opt_sig_I = Optfilter.process(Opt_sig_I);
|
||||
Opt_sig_I = Amplifier("amp_mode","ideal_no_noise","gain_mode","output_power","amplification_db",0).process(Opt_sig_I);
|
||||
|
||||
|
||||
%%%%% Interference Signal Fiber Prop 2x fiber length %%%%%%
|
||||
Opt_sig_I = Fiber("fsimu",Opt_sig_I.fs,"fiber_length",2*link_length/1000,"alpha",0.3,"D",0,"lambda0",1310,"gamma",0,"Dslope",0.07).process(Opt_sig_I);
|
||||
%%%%% Interference Signal Fiber Prop 2x fiber length %%%%%%
|
||||
Opt_sig_I = Fiber("fsimu",Opt_sig_I.fs,"fiber_length",2*link_length/1000,"alpha",0.3,"D",0,"lambda0",1310,"gamma",0,"Dslope",0.07).process(Opt_sig_I);
|
||||
|
||||
% ber=zeros(i_);
|
||||
% patten=zeros(i_);
|
||||
i_ = wh.parameter.rop.length;
|
||||
j_ = wh.parameter.sir.length;
|
||||
|
||||
ber_vnle=zeros(i_,j_);
|
||||
ber_mlse=zeros(i_,j_,3);
|
||||
|
||||
for j = 1:j_
|
||||
|
||||
sir = wh.parameter.sir.values(j);
|
||||
|
||||
%%%%% Set SIR %%%%%%
|
||||
Opt_sig_I_atten = Amplifier("amp_mode","ideal_no_noise","gain_mode","output_power","amplification_db",Opt_sig.power-sir).process(Opt_sig_I);
|
||||
|
||||
%%%%% ADD Interference and Main Signal %%%%%%
|
||||
Opt_sig_MPI = Opt_sig_I_atten + Opt_sig;
|
||||
|
||||
%%%%% Interference Signal Fiber Prop %%%%%%
|
||||
Opt_sig_MPI = Fiber("fsimu",Opt_sig.fs,"fiber_length",link_length/1000,"alpha",0.3,"D",0,"lambda0",1310,"gamma",0,"Dslope",0.07).process(Opt_sig_MPI);
|
||||
% ber=zeros(i_);
|
||||
% patten=zeros(i_);
|
||||
i_ = wh.parameter.rop.length;
|
||||
j_ = wh.parameter.sir.length;
|
||||
|
||||
ber_vnle=zeros(i_,j_);
|
||||
ber_mlse=zeros(i_,j_,3);
|
||||
|
||||
for j = 1:j_
|
||||
|
||||
sir = wh.parameter.sir.values(j);
|
||||
|
||||
%%%%% Set SIR %%%%%%
|
||||
Opt_sig_I_atten = Amplifier("amp_mode","ideal_no_noise","gain_mode","output_power","amplification_db",Opt_sig.power-sir).process(Opt_sig_I);
|
||||
|
||||
%%%%% ADD Interference and Main Signal %%%%%%
|
||||
Opt_sig_MPI = Opt_sig_I_atten + Opt_sig;
|
||||
|
||||
%%%%% Interference Signal Fiber Prop %%%%%%
|
||||
Opt_sig_MPI = Fiber("fsimu",Opt_sig.fs,"fiber_length",link_length/1000,"alpha",0.3,"D",0,"lambda0",1310,"gamma",0,"Dslope",0.07).process(Opt_sig_MPI);
|
||||
|
||||
|
||||
% Receiver ROP curve
|
||||
for i = 1:i_
|
||||
rop=wh.parameter.rop.values(i);
|
||||
|
||||
|
||||
% Set ROP
|
||||
Rx_sig = Amplifier("amp_mode","ideal_no_noise","gain_mode","output_power","amplification_db",rop).process(Opt_sig_MPI);
|
||||
% patten(i) = Rx_sig.power;
|
||||
|
||||
|
||||
%%%%%% Square Law %%%%%%
|
||||
Rx_sig = Photodiode("fsimu",fdac*kover,"dark_current",2e-08,"responsivity",1,"temperature",20,"nep",1.8e-11).process(Rx_sig);
|
||||
|
||||
|
||||
%%%%%% Lowpass PhDiode %%%%%%
|
||||
Rx_sig = Filter('filtdegree',2,"f_cutoff",70e9,"fs",fdac*kover,"filterType",filtertypes.gaussian,"active",true).process(Rx_sig);
|
||||
|
||||
|
||||
%%%%%% Scope %%%%%%
|
||||
fadc = 256e9;
|
||||
Lp_scpe = Filter('filtdegree',4,"f_cutoff",100e9,"fs",fadc,"filterType",filtertypes.butterworth,"active",true);
|
||||
@@ -178,161 +178,122 @@ for random_key_laser_phase = wh.parameter.random_key_laser_phase.values
|
||||
"delay",0,"fixed_delay",0,"filtertype",filtertypes.butterworth,...
|
||||
"samplingdelay",0,"rand_samplingdelay",0,"freq_offset",0,"samp_jitter",0,...
|
||||
"adcresolution",10,"quantbuffer",0.1,'block_dc',1,'lpf_active',1,'H_lpf',Lp_scpe).process(Rx_sig);
|
||||
|
||||
|
||||
if precomp_mode == 1
|
||||
precomp_est.estimate(Scpe_sig,"save",true,"savePath",precomp_path,"fileName",precomp_fn);
|
||||
precomp_est.plot();
|
||||
freqresp.estimate(Scpe_sig,"save",true,"savePath",precomp_path,"fileName",precomp_fn);
|
||||
freqresp.plot();
|
||||
end
|
||||
|
||||
|
||||
|
||||
% Scpe_sig_normalized = Scpe_sig.normalize("mode","rms");
|
||||
|
||||
% Scpe_sig.normalize("mode","rms").spectrum("displayname",'After Scope','fignum',10);
|
||||
|
||||
%
|
||||
% Scpe_sig_normalized.normalize("mode","rms").spectrum("displayname",'After Scope','fignum',23);
|
||||
|
||||
%%%%%% Sample to 2x fsym %%%%%%
|
||||
Scpe_sig = Scpe_sig.resample("fs_in",fadc,"fs_out",2*fsym);
|
||||
|
||||
|
||||
%%%%%% Sync Rx signal with reference %%%%%%
|
||||
[Scpe_sig,S] = Scpe_sig.tsynch("reference",Symbols,"fs_ref",fsym);
|
||||
|
||||
Scpe_sig.eye(fsym,M,"fignum",50,"displayname",'Simulated after Scope');
|
||||
|
||||
|
||||
%%%%% EQUALIZE %%%%%%
|
||||
Eq = FFE("epochs_tr",5,"epochs_dd",5,"len_tr",4096*2,"mu_dd",1e-4,"mu_tr",0,"order",25,"sps",2,"decide",0);
|
||||
Eq = FFE("epochs_tr",5,"epochs_dd",5,"len_tr",4096*2,"mu_dd",1e-4,"mu_tr",0,"order",25,"sps",2,"decide",0);
|
||||
% Eq = VNLE("epochs_tr",5,"epochs_dd",5,"len_tr",4096*2,"mu_dd",[0.0004 0.0005 0.0006],"mu_tr",0,"order",[50,7,7],"sps",2,"decide",1);
|
||||
|
||||
% Eq = EQ("Ne",[50,7,7],"Nb",[0,0,0],"training_length",4096*2,"training_loops",5,"dd_loops",5,"K",2,"DCmu",0.0,"DDmu",[0.0004 0.0004 0.0004 0.0004 ],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1);
|
||||
|
||||
|
||||
% Eq = EQ("Ne",[50,7,7],"Nb",[0,0,0],"training_length",4096*2,"training_loops",5,"dd_loops",5,"K",2,"DCmu",0.0,"DDmu",[0.0004 0.0004 0.0004 0.0004 ],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1);
|
||||
|
||||
% Eq = FFE_Kalman("epochs_tr",5,"epochs_dd",5,"len_tr",4096*2,"mu_dd",1e-4,"mu_tr",0,"order",25,"sps",2,"decide",0);
|
||||
|
||||
% Eq = FFE_Kalman_Feedback("epochs_tr",5,"epochs_dd",5,"len_tr",4096*2,"mu_dd",1e-4,"mu_tr",0,"order",25,"sps",2,"decide",0);
|
||||
|
||||
|
||||
% Eq = FFE_Kalman_Feedback("epochs_tr",5,"epochs_dd",5,"len_tr",4096*2,"mu_dd",1e-4,"mu_tr",0,"order",25,"sps",2,"decide",0);
|
||||
|
||||
% Eq = FFE_adaptive_decision("epochs_tr",5,"epochs_dd",5,"len_tr",4096*2,"mu_dd",1e-4,"mu_tr",0,"order",25,"sps",2,"decide",1,"buffer_length",80);
|
||||
|
||||
% Eq = FFE_DCremoval("epochs_tr",5,"epochs_dd",5,"len_tr",4096*2,"mu_dd",1e-4,"mu_tr",0,"order",25,"sps",2,"decide",0,"mu_dc",0.05,"dc_buffer_len",100);
|
||||
%
|
||||
% Eq = EQ("Ne",[50,7,7],"Nb",[0,0,0],"training_length",4096*2,"training_loops",5,"dd_loops",5,"K",2,"DCmu",0.0,"DDmu",[0.0004 0.0004 0.0004 0.0004 ],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1);
|
||||
|
||||
|
||||
% Eq = FFE_DCremoval("epochs_tr",5,"epochs_dd",5,"len_tr",4096*2,"mu_dd",1e-4,"mu_tr",0,"order",25,"sps",2,"decide",0,"mu_dc",0.05,"dc_buffer_len",100);
|
||||
%
|
||||
% Eq = EQ("Ne",[50,7,7],"Nb",[0,0,0],"training_length",4096*2,"training_loops",5,"dd_loops",5,"K",2,"DCmu",0.0,"DDmu",[0.0004 0.0004 0.0004 0.0004 ],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1);
|
||||
|
||||
if db_channelapproach
|
||||
% ref symbols and transm. sequence are precoded
|
||||
if db_precode
|
||||
[EQ_sig, Noi] = Eq.process(Scpe_sig,Duobinary().encode(Symbols));
|
||||
EQ_sig = MLSE("DIR",[1,1],"duobinary_output",1,"M",M,"trellis_states",PAMmapper(M,0).levels).process(EQ_sig);
|
||||
EQ_sig = Duobinary().decode(EQ_sig);
|
||||
Rx_bits = PAMmapper(M,0).demap(EQ_sig);
|
||||
[~,~,ber_vnle(i,j),~] = calc_ber(Rx_bits.signal,Bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||
else
|
||||
[EQ_sig, Noi] = Eq.process(Scpe_sig,Duobinary().encode(Symbols));
|
||||
|
||||
[EQ_sig, Noi] = Eq.process(Scpe_sig,Duobinary().encode(Symbols));
|
||||
EQ_sig = MLSE("DIR",[1,1],"duobinary_output",1,"M",M,"trellis_states",PAMmapper(M,0).levels).process(EQ_sig);
|
||||
EQ_sig = Duobinary().decode(EQ_sig);
|
||||
Rx_bits = PAMmapper(M,0).demap(EQ_sig);
|
||||
[~,~,ber_vnle(i,j),~] = calc_ber(Rx_bits.signal,Bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||
|
||||
EQ_sig.spectrum("displayname","Signal Spectrum after Postfilter","fignum",1234,"normalizeToNyquist",0);
|
||||
|
||||
EQ_sig.spectrum('displayname','EQ DB Out','fignum',12345,'normalizeTo0dB',0,'normalizeToNyquist',0,'color',cols(3,:));
|
||||
Noi.spectrum('displayname','Noise PSD optimal','fignum',1234,'normalizeTo0dB',0,'normalizeToNyquist',0,'color',cols(4,:));
|
||||
|
||||
EQ_sig = MLSE("DIR",[1,1],"duobinary_output",0,"M",M,"trellis_states",PAMmapper(M,0).levels).process(EQ_sig);
|
||||
|
||||
% 2: Entschiedene Symbole codieren
|
||||
EQ_sig = Duobinary().encode(EQ_sig);
|
||||
|
||||
% 3. Entschiedene und codierte Symbole dekodieren
|
||||
EQ_sig = Duobinary().decode(EQ_sig);
|
||||
|
||||
% 4. Demap EQ'd symbols
|
||||
Rx_bits = PAMmapper(M,0).demap(EQ_sig);
|
||||
|
||||
Symbols_db = Duobinary().precode(Symbols);
|
||||
Bits_ = PAMmapper(M,0).demap(Symbols_db);
|
||||
|
||||
[~,num_errors,ber_db,pos_errors] = calc_ber(Rx_bits.signal,Bits_.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||
|
||||
disp([' DB Precode -> Channel -> FFE -> Decode/ Mod ',sprintf('%.1E',ber_db),' | PD_in: ',num2str(pd_in),' dBm']);
|
||||
|
||||
end
|
||||
elseif db_encode
|
||||
|
||||
|
||||
[EQ_sig, Noi] = Eq.process(Scpe_sig,Symbols);
|
||||
EQ_sig = MLSE("DIR",[1,1],"duobinary_output",1,"M",M,"trellis_states",PAMmapper(M,0).levels).process(EQ_sig);
|
||||
EQ_sig = Duobinary().decode(EQ_sig);
|
||||
|
||||
|
||||
elseif postfilter
|
||||
|
||||
|
||||
[EQ_sig, Noi] = Eq.process(Scpe_sig,Symbols);
|
||||
|
||||
% EQ_sig.plot("displayname",'After VNLE','fignum',90,'clear',1);
|
||||
%%% REMOVE DC peak from Noi PSD
|
||||
S = Noi.signal;
|
||||
N1 = 1001;
|
||||
|
||||
% Quantization is too far from orig. symbols ->
|
||||
% error psd is quite different
|
||||
% Sym_ = PAMmapper(M,0).quantize(EQ_sig);
|
||||
% Noi_ = Sym_-EQ_sig;
|
||||
% Noi_.normalize('mode','rms').spectrum('displayname','Noise PSD','fignum',1234,'normalizeTo0dB',1,'normalizeToNyquist',1,'color',cols(nc+1,:));
|
||||
% recursion
|
||||
% Initialize the moving sum for the first window
|
||||
half_window = (N1 - 1) / 2;
|
||||
moving_sum = sum(S(1:N1));
|
||||
|
||||
Rx_bits = PAMmapper(M,0).demap(EQ_sig);
|
||||
[~,~,ber_ffe(i,j),~] = calc_ber(Rx_bits.signal,Bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||
% Calculate the first element of R1
|
||||
S_(1:half_window+1) = S(1:half_window+1) - (moving_sum / N1);
|
||||
|
||||
if 1
|
||||
figure(55);
|
||||
clf
|
||||
title(sprintf('PAM %d ; BER: %1.2e',M, ber_ffe(i,j)));
|
||||
constellation = unique(Symbols.signal);
|
||||
received = NaN(numel(constellation),length(Symbols));
|
||||
for lvl = 1:numel(constellation)
|
||||
%Separate the equalized signal into the
|
||||
%respective levels based on the actually
|
||||
%transmitted level!
|
||||
received(lvl,Symbols.signal==constellation(lvl)) = EQ_sig.signal(Symbols.signal==constellation(lvl));
|
||||
intermediate = received(lvl,:);
|
||||
cnt(lvl) = numel(intermediate(~isnan(intermediate)));
|
||||
hold on
|
||||
histogram(received(lvl,:),1000,"EdgeAlpha",0,'DisplayName',['Lvl ',num2str(lvl),' | ',num2str(cnt(lvl)),' entries']);
|
||||
end
|
||||
legend
|
||||
% Loop over the signal and apply the recursive moving average subtraction
|
||||
for n = (half_window+2):(length(S)-half_window)
|
||||
% Update the moving sum by subtracting the oldest value and adding the new one
|
||||
moving_sum = moving_sum - S(n-half_window-1) + S(n+half_window);
|
||||
|
||||
% Calculate the new value of R1
|
||||
S_(n) = S(n) - (moving_sum / N1);
|
||||
end
|
||||
|
||||
S_(n+1:length(S)) = S(n+1:end) - (moving_sum / N1);
|
||||
Noi.signal = S_;
|
||||
%%% END REMOVE DC PEAK %%%
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cols = linspecer(8);
|
||||
EQ_sig.normalize('mode','rms').spectrum('displayname','EQ Out','fignum',1234,'normalizeTo0dB',1,'normalizeToNyquist',1,'color',cols(nc,:));
|
||||
|
||||
Noi.normalize('mode','rms').spectrum('displayname','Noise PSD optimal','fignum',1234,'normalizeTo0dB',1,'normalizeToNyquist',1,'color',cols(nc+1,:));
|
||||
Rx_bits = PAMmapper(M,0).demap(EQ_sig);
|
||||
[~,~,ber_vnle(i,j),~] = calc_ber(Rx_bits.signal,Bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||
|
||||
EQ_sig.spectrum('displayname','EQ Out','fignum',12345,'normalizeTo0dB',0,'normalizeToNyquist',0,'color',cols(1,:));
|
||||
|
||||
|
||||
Noi.spectrum('displayname','Noise PSD optimal','fignum',22,'normalizeTo0dB',1,'normalizeToNyquist',0,'color',cols(2,:));
|
||||
|
||||
for nc = 1:3
|
||||
|
||||
|
||||
burg_coeff = arburg(Noi.signal,nc);
|
||||
|
||||
|
||||
EQ_sig_filt = EQ_sig.filter(burg_coeff,1);
|
||||
|
||||
|
||||
% EQ_sig.spectrum("displayname","Signal Spectrum after Postfilter","fignum",1234);
|
||||
|
||||
|
||||
EQ_sig_mlse = MLSE("DIR",burg_coeff,"duobinary_output",0,"M",M,"trellis_states",PAMmapper(M,0).levels).process(EQ_sig_filt);
|
||||
|
||||
|
||||
% EQ_sig.spectrum("displayname","Signal Spectrum after MLSE","fignum",1234);
|
||||
|
||||
|
||||
if 1
|
||||
cols = linspecer(12);
|
||||
|
||||
% EQ_sig_filt.normalize('mode','rms').spectrum('displayname','Noise PSD','fignum',1234,'normalizeTo0dB',1,'normalizeToNyquist',0,'color',cols(nc+2,:));
|
||||
|
||||
|
||||
|
||||
EQ_sig_filt.normalize('mode','rms').spectrum('displayname','Noise PSD','fignum',1234,'normalizeTo0dB',1,'normalizeToNyquist',1,'color',cols(nc+2,:));
|
||||
|
||||
% [h,w] = freqz(1,burg_coeff,length(Noi),"whole",Noi.fs);
|
||||
% h = h/max(abs(h));
|
||||
% hold on
|
||||
% w_ = (w - Noi.fs/2);
|
||||
% figure(123)
|
||||
% plot(w_.*1e-9,20*log10(fftshift(h)),'DisplayName',['', num2str(nc), ' coefficients for burg alg.']);
|
||||
|
||||
[h,w] = freqz(1,burg_coeff,length(Noi),"whole");
|
||||
[h,w] = freqz(1,burg_coeff,length(Noi),"whole",Noi.fs);
|
||||
% h = 1./h;
|
||||
h = h/max(abs(h));
|
||||
hold on
|
||||
w_ = (w - pi);
|
||||
plot(w_,20*log10(fftshift(h)),'DisplayName',['', num2str(nc), ' coefficients for burg alg.']);
|
||||
|
||||
w_ = (w - Noi.fs/2);
|
||||
figure(22)
|
||||
plot(w_.*1e-9,20*log10(fftshift(h)),'DisplayName',['', num2str(nc), ' coefficients for burg alg.']);
|
||||
|
||||
end
|
||||
|
||||
|
||||
Rx_bits = PAMmapper(M,0).demap(EQ_sig_mlse);
|
||||
[~,errors_bm,ber_mlse(i,j,nc),errors] = calc_ber(Rx_bits.signal,Bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||
% disp(['BER: ',sprintf('%.1E',ber_mlse(i,j)),' - - ROP: ',num2str(patten(i)),'dBm - - PAM-',num2str(M),' - - ',num2str(fsym*1e-9),' GBd']);
|
||||
@@ -341,41 +302,7 @@ for random_key_laser_phase = wh.parameter.random_key_laser_phase.values
|
||||
|
||||
else
|
||||
|
||||
% S = Scpe_sig.signal;
|
||||
% N1 = 101;
|
||||
%
|
||||
% % Initialize the running sum with the first window's sum
|
||||
% running_sum = mean( S(1:N1) );
|
||||
%
|
||||
% % Calculate the first output value
|
||||
% S_(1) = S(1) - running_sum;
|
||||
%
|
||||
% % Recursive running sum filter
|
||||
% for n = 2 : length(S) - N1
|
||||
% % Update running sum by removing the oldest sample and adding the newest
|
||||
% avg_win(n) = mean( S(n:n+N1) );
|
||||
% S_(n) = S(n) - avg_win(n);
|
||||
% end
|
||||
%
|
||||
% % movmean
|
||||
% S__ = S - movmean(S,[floor(N1/2),ceil(N1/2)]);
|
||||
%
|
||||
% % recursion
|
||||
% % Initialize the moving sum for the first window
|
||||
% half_window = (N1 - 1) / 2;
|
||||
% moving_sum = sum(S(1:N1));
|
||||
%
|
||||
% % Calculate the first element of R1
|
||||
% S___(half_window+1) = S(half_window+1) - (moving_sum / N1);
|
||||
%
|
||||
% % Loop over the signal and apply the recursive moving average subtraction
|
||||
% for n = (half_window+2):(length(S)-half_window)
|
||||
% % Update the moving sum by subtracting the oldest value and adding the new one
|
||||
% moving_sum = moving_sum - S(n-half_window-1) + S(n+half_window);
|
||||
%
|
||||
% % Calculate the new value of R1
|
||||
% S___(n) = S(n) - (moving_sum / N1);
|
||||
% end
|
||||
|
||||
|
||||
|
||||
[EQ_sig, Noi] = Eq.process(Scpe_sig,Symbols);
|
||||
@@ -384,41 +311,41 @@ for random_key_laser_phase = wh.parameter.random_key_laser_phase.values
|
||||
Noi.spectrum('displayname','Noise PSD','fignum',123,'normalizeTo0dB',1,'normalizeToNyquist',1);
|
||||
EQ_sig.plot("displayname",'After EQ','fignum',1113);
|
||||
end
|
||||
%
|
||||
%
|
||||
Rx_bits = PAMmapper(M,0).demap(EQ_sig);
|
||||
[~,errors_bm,ber_vnle(i,j),errors] = calc_ber(Rx_bits.signal,Bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
for j = 1:j_
|
||||
sir = wh.parameter.sir.values(j);
|
||||
for i = 1:i_
|
||||
rop=wh.parameter.rop.values(i);
|
||||
|
||||
wh.addValueToStorage(ber_vnle(i,j),'ber_vnle',M,datarate,rop,sir,random_key_laser_phase);
|
||||
wh.addValueToStorage(ber_mlse(i,j,:),'ber_mlse',M,datarate,rop,sir,random_key_laser_phase);
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
toc
|
||||
|
||||
% wh.save('C:\Users\Silas\Documents\MATLAB\imdd_simulation\projects\MPI_August\auswertung\')
|
||||
|
||||
|
||||
end
|
||||
|
||||
for j = 1:j_
|
||||
sir = wh.parameter.sir.values(j);
|
||||
for i = 1:i_
|
||||
rop=wh.parameter.rop.values(i);
|
||||
|
||||
wh.addValueToStorage(ber_vnle(i,j),'ber_vnle',M,datarate,rop,sir,random_key_laser_phase);
|
||||
wh.addValueToStorage(ber_mlse(i,j,:),'ber_mlse',M,datarate,rop,sir,random_key_laser_phase);
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
toc
|
||||
|
||||
% wh.save('C:\Users\Silas\Documents\MATLAB\imdd_simulation\projects\MPI_August\auswertung\')
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
disp('Simulation Done!')
|
||||
|
||||
|
||||
ber_mlse=[];
|
||||
ber_vnle=[];
|
||||
cols = linspecer(8);
|
||||
@@ -434,16 +361,16 @@ ber_mlse=squeeze(mean(ber_mlse,1));
|
||||
ber_vnle = mean(ber_vnle,1);
|
||||
% Create the initial plot
|
||||
|
||||
figure(44);
|
||||
figure(466);
|
||||
a = gca;
|
||||
hold on; % Retain the plot so new points can be added without complete redraw
|
||||
|
||||
dispname = ['Lw: ',num2str(laser_linewidth.*1e-6),' MHz'];
|
||||
|
||||
plot(wh.parameter.sir.values,ber_vnle,"LineWidth",0.5,"LineStyle","-","Marker",".","MarkerSize",15,"DisplayName",['VNLE ',dispname]);
|
||||
plot(wh.parameter.sir.values,ber_mlse(:,1),"LineWidth",0.5,"LineStyle","-","Marker",".","MarkerSize",15,"DisplayName",['MLSE 1 ',dispname]);
|
||||
plot(wh.parameter.sir.values,ber_mlse(:,2),"LineWidth",0.5,"LineStyle","-","Marker",".","MarkerSize",15,"DisplayName",['MLSE 2',dispname]);
|
||||
plot(wh.parameter.sir.values,ber_mlse(:,3),"LineWidth",0.5,"LineStyle","-","Marker",".","MarkerSize",15,"DisplayName",['MLSE 3',dispname]);
|
||||
cols = linspecer(6);
|
||||
plot(wh.parameter.sir.values,ber_vnle,"LineWidth",0.5,"LineStyle","--","Marker",".","MarkerSize",15,"DisplayName",['PAM',num2str(M),' VNLE ',dispname],'Color',cols(1,:));
|
||||
plot(wh.parameter.sir.values,ber_mlse(:,1),"LineWidth",0.5,"LineStyle","--","Marker",".","MarkerSize",15,"DisplayName",['PAM',num2str(M),'MLSE 1 ',dispname],'Color',cols(2,:));
|
||||
plot(wh.parameter.sir.values,ber_mlse(:,2),"LineWidth",0.5,"LineStyle","--","Marker",".","MarkerSize",15,"DisplayName",['PAM',num2str(M),'MLSE 2',dispname],'Color',cols(3,:));
|
||||
plot(wh.parameter.sir.values,ber_mlse(:,3),"LineWidth",0.5,"LineStyle","--","Marker",".","MarkerSize",15,"DisplayName",['PAM',num2str(M),'MLSE 3',dispname],'Color',cols(4,:));
|
||||
|
||||
yline(3.8e-3,'DisplayName','HD-FEC','LineStyle','--','HandleVisibility','off');
|
||||
xlabel('Received Optical Power (dBm)');
|
||||
|
||||
84
projects/HighSpeedExperiment_2024/analysis_script.m
Normal file
84
projects/HighSpeedExperiment_2024/analysis_script.m
Normal file
@@ -0,0 +1,84 @@
|
||||
|
||||
% cleanup measurement data
|
||||
% remove fots from files
|
||||
% merge measurments into database
|
||||
|
||||
|
||||
if 1
|
||||
|
||||
folderPath = "/Volumes/NT-Labor/2024/sioe/High Speed Messungen Oktober/mpi_measurement";
|
||||
|
||||
% Get list of all files in the folder and subfolders
|
||||
fileList = dir(fullfile(folderPath, '**', '*'));
|
||||
|
||||
|
||||
% Loop through each file
|
||||
big_wh_list = {};
|
||||
small_wh_list = {};
|
||||
|
||||
for i = 1:length(fileList)
|
||||
|
||||
fileName = fileList(i).name;
|
||||
iswh = strfind(fileName, 'wh');
|
||||
if ~isempty(iswh)
|
||||
|
||||
wh = load(fullfile(fileList(i).folder, fileName));
|
||||
wh = wh.obj;
|
||||
|
||||
if isa(wh,'DataStorage')
|
||||
if prod(wh.dim) > 2
|
||||
big_wh_list{end+1} = wh;
|
||||
|
||||
else
|
||||
small_wh_list{end+1} = wh;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
%%% merge MPI structs by copying the values %%%
|
||||
params.M = [4,6,8];
|
||||
params.bitrate = [224,336,448].*1e9;
|
||||
params.duobinary = [0,1];
|
||||
params.interference_atten = [0 3 6 9 12 15 18 21 24 27 30 45];
|
||||
wh_new=DataStorage(params);
|
||||
|
||||
|
||||
for w = 1:numel(big_wh_list)
|
||||
wh = big_wh_list{w};
|
||||
for m = wh.parameter.M.values
|
||||
for br = wh.parameter.bitrate.values
|
||||
for db = wh.parameter.duobinary.values
|
||||
for iatten = wh.parameter.interference_atten.values
|
||||
|
||||
storage_names = fieldnames(wh.sto);
|
||||
for i = 1:length(storage_names)
|
||||
|
||||
%get two things:
|
||||
%1) current data storage name
|
||||
cur_storage = storage_names{i};
|
||||
%2) the value saved at this storage and dimension
|
||||
value = wh.getStoValue(cur_storage,m,br,db,iatten);
|
||||
|
||||
% check if storage name already exists, if not
|
||||
% .addStorgae(...)
|
||||
if ~isfield(wh_new.sto,cur_storage)
|
||||
wh_new.addStorage(cur_storage);
|
||||
end
|
||||
|
||||
|
||||
if isempty(wh_new.getStoValue(cur_storage,m,br,db,iatten))
|
||||
% Finally, add the value to the repsective storage
|
||||
wh_new.addValueToStorage(value,cur_storage,m,br,db,iatten);
|
||||
else
|
||||
warning('double vaue?')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,150 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 1365 313" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;">
|
||||
<g transform="matrix(1,0,0,1,-350.052,-234.682)">
|
||||
<g id="g40994" transform="matrix(3.14734,0,0,3.14734,-400.995,-235.585)">
|
||||
<path id="rect40684" d="M277.516,207.069C277.516,206.587 277.125,206.197 276.643,206.197L240.002,206.197C239.52,206.197 239.129,206.587 239.129,207.069L239.129,243.711C239.129,244.192 239.52,244.583 240.002,244.583L276.643,244.583C277.125,244.583 277.516,244.192 277.516,243.711L277.516,207.069Z" style="fill:none;stroke:black;stroke-width:1px;"/>
|
||||
<g id="g40700" transform="matrix(1,0,0,1,53.6992,6.29287)">
|
||||
<path id="path40686" d="M211.915,223.139L198.35,223.139L201.742,217.266L205.133,211.392L208.524,217.266L211.915,223.139Z" style="fill:none;fill-rule:nonzero;stroke:black;stroke-width:1px;"/>
|
||||
<path id="path40688" d="M205.133,223.139L205.133,230.555" style="fill:none;fill-rule:nonzero;stroke:black;stroke-width:1px;"/>
|
||||
<path id="path40690" d="M205.133,211.392L205.133,205.096" style="fill:none;fill-rule:nonzero;stroke:black;stroke-width:1px;"/>
|
||||
<path id="path40694" d="M198.143,211.392L212.123,211.392" style="fill:none;fill-rule:nonzero;stroke:black;stroke-width:1px;"/>
|
||||
</g>
|
||||
<g id="path40702" transform="matrix(0.317729,-0,-0,0.317729,238.629,149.417)">
|
||||
<path d="M82.941,200.888L86.409,190.917L76.351,194.125C79.689,194.169 82.984,197.55 82.941,200.888Z" style="fill:rgb(255,0,0);fill-rule:nonzero;"/>
|
||||
<path d="M80.998,196.189C77.477,199.62 73.535,203.461 73.535,203.461" style="fill:none;fill-rule:nonzero;stroke:rgb(255,0,0);stroke-width:3.15px;"/>
|
||||
</g>
|
||||
<g id="path40702-1" transform="matrix(0.317729,-0,-0,0.317729,238.629,149.417)">
|
||||
<path d="M102.022,200.888L105.49,190.917L95.433,194.125C98.771,194.169 102.066,197.55 102.022,200.888Z" style="fill:rgb(255,0,0);fill-rule:nonzero;"/>
|
||||
<path d="M100.08,196.189C96.559,199.62 92.617,203.461 92.617,203.461" style="fill:none;fill-rule:nonzero;stroke:rgb(255,0,0);stroke-width:3.15px;"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="g40994-4" transform="matrix(3.07687,0,0,3.07687,-308.034,-474.106)">
|
||||
<g id="g41806">
|
||||
<path id="path41709" d="M272.852,307.633L280.529,307.633L288.207,302.14L295.884,302.141L303.561,307.633L311.239,307.633" style="fill:none;fill-rule:nonzero;stroke:rgb(2,0,0);stroke-width:1px;"/>
|
||||
<path id="path41709-4" d="M272.852,307.633L280.529,307.633L288.207,313.126L295.884,313.126L303.561,307.633L311.239,307.633" style="fill:none;fill-rule:nonzero;stroke:rgb(2,0,0);stroke-width:1px;"/>
|
||||
</g>
|
||||
<path id="rect40684-3" d="M311.239,289.332C311.239,288.84 310.839,288.44 310.346,288.44L273.745,288.44C273.252,288.44 272.852,288.84 272.852,289.332L272.852,325.934C272.852,326.427 273.252,326.827 273.745,326.827L310.346,326.827C310.839,326.827 311.239,326.427 311.239,325.934L311.239,289.332Z" style="fill:none;stroke:rgb(2,0,0);stroke-width:1px;"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,462.763,-27.6418)">
|
||||
<g id="g42228" transform="matrix(3.07687,0,0,3.07687,-770.796,-623.629)">
|
||||
<path id="rect40684-3-5" d="M311.239,289.332C311.239,288.84 310.839,288.44 310.346,288.44L273.745,288.44C273.252,288.44 272.852,288.84 272.852,289.332L272.852,325.934C272.852,326.427 273.252,326.827 273.745,326.827L310.346,326.827C310.839,326.827 311.239,326.427 311.239,325.934L311.239,289.332Z" style="fill:none;stroke:rgb(2,0,0);stroke-width:1px;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.916758,0,0,0.916758,-209.942,-134.558)">
|
||||
<g transform="matrix(36.36,0,0,36.36,410.943,511.232)">
|
||||
</g>
|
||||
<text x="325.44px" y="511.232px" style="font-family:'ArialMT', 'Arial';font-size:36.36px;">A<tspan x="348.342px 382.661px " y="511.232px 511.232px ">WG</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
<g id="use14586" transform="matrix(4.16667,0,0,4.16667,538.992,319.037)">
|
||||
<g id="path38721" transform="matrix(1.27892,-0.000404508,-0.000404508,1,-27.2331,0.0394952)">
|
||||
<path d="M71.975,37.134L122.852,37.061" style="fill:none;fill-rule:nonzero;stroke:rgb(255,0,0);stroke-width:0.73px;"/>
|
||||
</g>
|
||||
<circle id="circle38723" cx="90.574" cy="26.615" r="10.503" style="fill:none;stroke:rgb(255,0,0);stroke-width:0.73px;"/>
|
||||
<circle id="circle38725" cx="96.619" cy="26.638" r="10.503" style="fill:none;stroke:rgb(255,0,0);stroke-width:0.73px;"/>
|
||||
<circle id="circle38727" cx="102.664" cy="26.594" r="10.503" style="fill:none;stroke:rgb(255,0,0);stroke-width:0.73px;"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,-180.978,231.592)">
|
||||
<g transform="matrix(1.12196,0,0,1.12196,-146.494,-56.6939)">
|
||||
<circle cx="974.409" cy="265.748" r="29.528" style="fill:white;stroke:rgb(255,0,0);stroke-width:2.67px;stroke-miterlimit:1.5;"/>
|
||||
</g>
|
||||
<g transform="matrix(1.16567,-0.0445706,-0.0445706,1.1674,-141.533,6.43198)">
|
||||
<g transform="matrix(0.859131,0.032801,0.032801,0.857855,577.71,19.194)">
|
||||
<path d="M441.614,202.956L452.737,201.256L451.254,212.411L441.614,202.956Z" style="fill:rgb(255,0,0);"/>
|
||||
<path d="M382.592,272.779C382.592,272.779 431.613,222.795 447.694,206.398" style="fill:none;stroke:rgb(255,0,0);stroke-width:3px;stroke-miterlimit:1.5;"/>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,-20.5026,130.73)">
|
||||
<text x="933.238px" y="184.877px" style="font-family:'ArialMT', 'Arial';font-size:33.333px;">P</text>
|
||||
<g transform="matrix(20.8333,0,0,20.8333,1016.86,184.877)">
|
||||
</g>
|
||||
<text x="955.471px" y="184.877px" style="font-family:'ArialMT', 'Arial';font-size:20.833px;">launch</text>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,350.518,231.592)">
|
||||
<g transform="matrix(1.12196,0,0,1.12196,-146.494,-56.6939)">
|
||||
<circle cx="974.409" cy="265.748" r="29.528" style="fill:white;stroke:rgb(255,0,0);stroke-width:2.67px;stroke-miterlimit:1.5;"/>
|
||||
</g>
|
||||
<g transform="matrix(1.16567,-0.0445706,-0.0445706,1.1674,-141.533,6.43198)">
|
||||
<g transform="matrix(0.859131,0.032801,0.032801,0.857855,121.085,1.76038)">
|
||||
<path d="M973.11,202.956L984.233,201.256L982.75,212.411L973.11,202.956Z" style="fill:rgb(255,0,0);"/>
|
||||
<path d="M914.089,272.779C914.089,272.779 963.109,222.795 979.19,206.398" style="fill:none;stroke:rgb(255,0,0);stroke-width:3px;stroke-miterlimit:1.5;"/>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,-20.5026,130.73)">
|
||||
<text x="937.937px" y="184.877px" style="font-family:'ArialMT', 'Arial';font-size:33.333px;">PD</text>
|
||||
<g transform="matrix(20.8333,0,0,20.8333,1000.46,184.877)">
|
||||
</g>
|
||||
<text x="984.242px" y="184.877px" style="font-family:'ArialMT', 'Arial';font-size:20.833px;">in</text>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(1.04523e-16,1.70851,-1.55299,9.48961e-17,2134.48,-837.195)">
|
||||
<path d="M767.327,630.707L794.304,673.144L740.349,673.144L767.327,630.707Z" style="fill:none;stroke:rgb(255,20,3);stroke-width:1.84px;stroke-miterlimit:1.5;"/>
|
||||
</g>
|
||||
<g id="g409941" serif:id="g40994" transform="matrix(3.07687,0,0,3.07687,681.554,-221.053)">
|
||||
<path id="rect406841" serif:id="rect40684" d="M277.516,207.089C277.516,206.596 277.116,206.197 276.623,206.197L240.022,206.197C239.529,206.197 239.129,206.596 239.129,207.089L239.129,243.691C239.129,244.183 239.529,244.583 240.022,244.583L276.623,244.583C277.116,244.583 277.516,244.183 277.516,243.691L277.516,207.089Z" style="fill:none;stroke:black;stroke-width:1px;"/>
|
||||
<g id="g407001" serif:id="g40700" transform="matrix(1,0,0,1,53.6992,6.29287)">
|
||||
<path id="path406861" serif:id="path40686" d="M211.915,223.139L198.35,223.139L201.742,217.266L205.133,211.392L208.524,217.266L211.915,223.139Z" style="fill:none;fill-rule:nonzero;stroke:black;stroke-width:1px;"/>
|
||||
<path id="path406881" serif:id="path40688" d="M205.133,223.139L205.133,230.555" style="fill:none;fill-rule:nonzero;stroke:black;stroke-width:1px;"/>
|
||||
<path id="path406901" serif:id="path40690" d="M205.133,211.392L205.133,205.096" style="fill:none;fill-rule:nonzero;stroke:black;stroke-width:1px;"/>
|
||||
<path id="path406941" serif:id="path40694" d="M198.143,211.392L212.123,211.392" style="fill:none;fill-rule:nonzero;stroke:black;stroke-width:1px;"/>
|
||||
</g>
|
||||
<g id="path407021" serif:id="path40702" transform="matrix(0.325006,-0,-0,0.325006,-107.74,148.117)">
|
||||
<path d="M1147.45,199.771L1137.62,202.907L1141.01,193.159C1140.97,196.423 1144.19,199.728 1147.45,199.771Z" style="fill:rgb(255,0,0);fill-rule:nonzero;"/>
|
||||
<path d="M1150.21,190.644C1150.21,190.644 1146.35,194.399 1142.91,197.753" style="fill:none;fill-rule:nonzero;stroke:rgb(255,0,0);stroke-width:3.08px;"/>
|
||||
</g>
|
||||
<g id="path40702-11" serif:id="path40702-1" transform="matrix(0.325006,-0,-0,0.325006,-107.74,148.117)">
|
||||
<path d="M1166.11,199.771L1156.28,202.907L1159.67,193.159C1159.62,196.423 1162.84,199.728 1166.11,199.771Z" style="fill:rgb(255,0,0);fill-rule:nonzero;"/>
|
||||
<path d="M1168.86,190.644C1168.86,190.644 1165.01,194.399 1161.56,197.753" style="fill:none;fill-rule:nonzero;stroke:rgb(255,0,0);stroke-width:3.08px;"/>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,1525.75,150.876)">
|
||||
<g id="g422281" serif:id="g42228" transform="matrix(3.07687,0,0,3.07687,-770.796,-623.629)">
|
||||
<path id="rect40684-3-51" serif:id="rect40684-3-5" d="M311.239,289.332C311.239,288.84 310.839,288.44 310.346,288.44L273.745,288.44C273.252,288.44 272.852,288.84 272.852,289.332L272.852,325.934C272.852,326.427 273.252,326.827 273.745,326.827L310.346,326.827C310.839,326.827 311.239,326.427 311.239,325.934L311.239,289.332Z" style="fill:none;stroke:rgb(2,0,0);stroke-width:1px;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.916758,0,0,0.916758,-209.942,-134.558)">
|
||||
<g transform="matrix(36.36,0,0,36.36,405.909,511.232)">
|
||||
</g>
|
||||
<text x="330.473px" y="511.232px" style="font-family:'ArialMT', 'Arial';font-size:36.36px;">R<tspan x="356.074px " y="511.232px ">T</tspan>O</text>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(1.26861,0.00113446,0.00113446,1,277.224,235.237)">
|
||||
<g transform="matrix(0.788264,-0.000894252,-0.000894252,0.999996,57.4082,-0.620229)">
|
||||
<path d="M368.303,230.541L376.948,237.082L368.248,243.55L368.303,230.541Z" style="fill:rgb(255,0,0);"/>
|
||||
<path d="M304.499,236.776C304.499,236.776 351.883,236.976 370.01,237.053" style="fill:none;stroke:rgb(255,0,0);stroke-width:2.89px;stroke-miterlimit:1.5;"/>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(0.934186,-0.000277962,-0.000277962,0.999999,198.405,236.65)">
|
||||
<g transform="matrix(1.07045,0.000297545,0.000297545,1,162.33,-1.92253)">
|
||||
<path d="M170.653,231.452L179.298,237.993L170.598,244.461L170.653,231.452Z" style="fill:rgb(255,0,0);"/>
|
||||
<path d="M125.948,237.768C125.948,237.768 157.916,237.903 172.36,237.964" style="fill:none;stroke:rgb(255,0,0);stroke-width:2.89px;stroke-miterlimit:1.5;"/>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(1.73353,0.00309801,0.00309801,1.00001,639.025,236.856)">
|
||||
<g transform="matrix(0.57686,-0.0017871,-0.0017871,0.999992,-166.693,-1.6572)">
|
||||
<path d="M895.303,232.857L903.948,239.399L895.248,245.866L895.303,232.857Z" style="fill:rgb(255,0,0);"/>
|
||||
<path d="M804.948,238.98C804.948,238.98 874.5,239.274 897.01,239.369" style="fill:none;stroke:rgb(255,0,0);stroke-width:2.89px;stroke-miterlimit:1.5;"/>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(1.45403,0.00191757,0.00191757,1.00001,901.662,237.501)">
|
||||
<g transform="matrix(0.687744,-0.00131879,-0.00131879,0.999994,-379.363,-2.09148)">
|
||||
<path d="M1058.63,233.083L1067.27,239.624L1058.57,246.092L1058.63,233.083Z" style="fill:rgb(255,0,0);"/>
|
||||
<path d="M984.233,239.274C984.233,239.274 1040.38,239.511 1060.33,239.595" style="fill:none;stroke:rgb(255,0,0);stroke-width:2.89px;stroke-miterlimit:1.5;"/>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(0.00422338,0.959693,-0.999991,0.00405319,825.177,70.1581)">
|
||||
<path d="M297.222,235.883L354.331,236.124" style="fill:none;"/>
|
||||
<g transform="matrix(0.00422338,-0.999991,1.04198,0.00440072,169.424,475.845)">
|
||||
<path d="M248.693,165.557L240.499,176.482L232.306,165.557L248.693,165.557Z"/>
|
||||
<path d="M240.499,121.674L240.499,167.742" style="fill:none;stroke:black;stroke-width:3.64px;stroke-miterlimit:1.5;"/>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(0.959693,-0.00422338,0.00405319,0.999991,1250.8,239.181)">
|
||||
<path d="M297.222,235.883L354.331,236.124" style="fill:none;"/>
|
||||
<g transform="matrix(1.04198,0.00440072,-0.00422338,0.999991,-938.545,-8.46312)">
|
||||
<path d="M1230.83,230.931L1241.76,239.125L1230.83,247.318L1230.83,230.931Z"/>
|
||||
<path d="M1186.95,239.125L1233.02,239.125" style="fill:none;stroke:black;stroke-width:3.64px;stroke-miterlimit:1.5;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 14 KiB |
Binary file not shown.
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e8eaed"><path d="M480-120q-151 0-255.5-46.5T120-280v-400q0-66 105.5-113T480-840q149 0 254.5 47T840-680v400q0 67-104.5 113.5T480-120Zm0-479q89 0 179-25.5T760-679q-11-29-100.5-55T480-760q-91 0-178.5 25.5T200-679q14 30 101.5 55T480-599Zm0 199q42 0 81-4t74.5-11.5q35.5-7.5 67-18.5t57.5-25v-120q-26 14-57.5 25t-67 18.5Q600-528 561-524t-81 4q-42 0-82-4t-75.5-11.5Q287-543 256-554t-56-25v120q25 14 56 25t66.5 18.5Q358-408 398-404t82 4Zm0 200q46 0 93.5-7t87.5-18.5q40-11.5 67-26t32-29.5v-98q-26 14-57.5 25t-67 18.5Q600-328 561-324t-81 4q-42 0-82-4t-75.5-11.5Q287-343 256-354t-56-25v99q5 15 31.5 29t66.5 25.5q40 11.5 88 18.5t94 7Z"/></svg>
|
||||
|
After Width: | Height: | Size: 729 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e8eaed"><path d="m105-399-65-47 200-320 120 140 160-260 120 180 135-214 65 47-198 314-119-179-152 247-121-141-145 233Zm475 159q42 0 71-29t29-71q0-42-29-71t-71-29q-42 0-71 29t-29 71q0 42 29 71t71 29ZM784-80 676-188q-21 14-45.5 21t-50.5 7q-75 0-127.5-52.5T400-340q0-75 52.5-127.5T580-520q75 0 127.5 52.5T760-340q0 26-7 50.5T732-244l108 108-56 56Z"/></svg>
|
||||
|
After Width: | Height: | Size: 452 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e8eaed"><path d="M440-120v-480H120v-160q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H440Zm80-80h240v-160H520v160Zm0-240h240v-160H520v160ZM200-680h560v-80H200v80ZM120-80v-80h102q-48-23-77.5-68T115-330q0-79 55.5-134.5T305-520v80q-45 0-77.5 32T195-330q0 39 24 69t61 38v-97h80v240H120Z"/></svg>
|
||||
|
After Width: | Height: | Size: 421 B |
@@ -0,0 +1,137 @@
|
||||
basePath = 'C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor\';
|
||||
useGui = 0;
|
||||
pamlvls = [4, 6, 8];
|
||||
wlengths = [1310];
|
||||
db = DBHandler("pathToDB", [basePath, 'silas_labor.db']);
|
||||
|
||||
for w = 1:numel(wlengths)
|
||||
for p = 1:numel(pamlvls)
|
||||
% Load data from database
|
||||
joinedData = loadDataFromDB(db, pamlvls(p), wlengths(w), useGui);
|
||||
|
||||
% Plot filtered data
|
||||
figure(pamlvls(p));
|
||||
hold on;
|
||||
plotFilteredData(joinedData, wlengths(w));
|
||||
% Continue with the rest of your plot settings
|
||||
finalizePlot();
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
% Custom function to load data from database
|
||||
function joinedData = loadDataFromDB(db, pamlvl, wlength, useGui)
|
||||
if useGui
|
||||
filterParams = db.promptFilterParameters();
|
||||
selectedFields = db.promptSelectFields();
|
||||
else
|
||||
filterParams = db.tables;
|
||||
filterParams.Configurations = struct( ...
|
||||
'bitrate', [], 'db_mode', [], 'fiber_length', 1, ...
|
||||
'interference_attenuation', [], 'interference_path_length', [], ...
|
||||
'is_mpi', 0, 'pam_level', pamlvl, 'precomp_amp', [], ...
|
||||
'rop_attenuation', 0, 'symbolrate', [], 'v_awg', [], 'v_bias', [], ...
|
||||
'wavelength', wlength ...
|
||||
);
|
||||
|
||||
selectedFields = {'Runs.run_id', 'BERs.ber_id', 'Equalizer.eq_id', 'Equalizer.eq_type', 'BERs.ber', 'BERs.occurrence', ...
|
||||
'Configurations.db_mode', 'Configurations.pam_level', 'Configurations.bitrate', 'Configurations.symbolrate', ...
|
||||
'Configurations.fiber_length', 'Configurations.wavelength', 'Configurations.precomp_amp', ...
|
||||
'Measurements.power_rop', 'Measurements.power_laser', 'Measurements.power_pd_in'};
|
||||
end
|
||||
|
||||
% Get data table from DB
|
||||
[dataTable, ~] = db.queryDB(filterParams, selectedFields);
|
||||
|
||||
% Extract unique rows for each run_id
|
||||
uniqueConfigFields = {'run_id', 'pam_level', 'bitrate', 'symbolrate', 'fiber_length', 'wavelength', 'precomp_amp', 'db_mode'};
|
||||
[~, uniqueIdx] = unique(dataTable.run_id);
|
||||
configDetails = dataTable(uniqueIdx, uniqueConfigFields);
|
||||
|
||||
% Calculate the mean BER for each combination of 'run_id' and 'eq_type'
|
||||
groupedData = groupsummary(dataTable, {'run_id', 'eq_type'}, {'mean', 'min', @(x) meanExcludingOutliers(x)}, {'ber', 'power_rop', 'power_pd_in'});
|
||||
|
||||
% Join groupedData with configDetails on the run_id field
|
||||
joinedData = join(groupedData, configDetails, 'Keys', 'run_id');
|
||||
end
|
||||
|
||||
% Custom function to plot filtered data
|
||||
function plotFilteredData(joinedData, wlength)
|
||||
filterFields = {'eq_type'};
|
||||
cols = linspecer(8);
|
||||
lst = ["-", ":", "--"];
|
||||
|
||||
% Loop over each field you want to filter by
|
||||
for f = 1:numel(filterFields)
|
||||
currentField = filterFields{f};
|
||||
uniqueValues = unique(joinedData.(currentField));
|
||||
|
||||
for i = 1:numel(uniqueValues)
|
||||
currentValue = uniqueValues(i);
|
||||
|
||||
% Filter joinedData for the current value
|
||||
if isnumeric(currentValue)
|
||||
filteredData = joinedData(joinedData.(currentField) == currentValue, :);
|
||||
else
|
||||
filteredData = joinedData(strcmp(joinedData.(currentField), currentValue), :);
|
||||
end
|
||||
|
||||
% Group and average BERs of several run ids => repeated measurements in lab!
|
||||
groupVars = {'bitrate'};
|
||||
groupedDataWithMeans = groupsummary(filteredData, groupVars, {'mean', 'min'}, {'mean_ber', 'min_ber', 'fun1_ber', 'mean_power_rop', 'mean_power_pd_in'});
|
||||
[~, uniqueIdx] = unique(filteredData.bitrate);
|
||||
constantFields = filteredData(uniqueIdx, {'bitrate', 'GroupCount', 'pam_level', 'symbolrate', 'fiber_length', 'wavelength', 'precomp_amp', 'db_mode'});
|
||||
groupedRunIDs = varfun(@(x) {unique(x)}, filteredData, 'GroupingVariables', groupVars, 'InputVariables', 'run_id');
|
||||
groupedRunIDs.Properties.VariableNames(end) = {'GroupedRunIDs'};
|
||||
groupedDataWithMeans = join(groupedDataWithMeans, constantFields, 'Keys', 'bitrate');
|
||||
groupedDataWithMeans = join(groupedDataWithMeans, groupedRunIDs, 'Keys', 'bitrate');
|
||||
filteredData = groupedDataWithMeans;
|
||||
|
||||
% Plotting
|
||||
a = plot(filteredData.bitrate .* 1e-9, filteredData.mean_fun1_ber, ...
|
||||
'Color', cols(i, :), 'MarkerSize', 4, 'LineWidth', 1, 'LineStyle', lst(mod(wlength - 1, numel(lst)) + 1), ...
|
||||
'Marker', 'o', 'MarkerFaceColor', 'auto', 'MarkerEdgeColor', cols(i, :), ...
|
||||
'DisplayName', [char(currentValue), '; ', num2str(wlength), ' nm']);
|
||||
|
||||
a.DataTipTemplate.DataTipRows(1).Label = 'Bitrate';
|
||||
a.DataTipTemplate.DataTipRows(1).Format = ['%.1f', ' Gbit/s'];
|
||||
a.DataTipTemplate.DataTipRows(2).Label = 'BER';
|
||||
a.DataTipTemplate.DataTipRows(2).Format = '%.1e';
|
||||
a.DataTipTemplate.DataTipRows(3).Label = 'P_{out}';
|
||||
a.DataTipTemplate.DataTipRows(3).Value = filteredData.mean_mean_power_rop;
|
||||
a.DataTipTemplate.DataTipRows(3).Format = ['%.2f', ' dBm'];
|
||||
a.DataTipTemplate.DataTipRows(4).Label = 'Baudr';
|
||||
a.DataTipTemplate.DataTipRows(4).Value = filteredData.bitrate .* 1e-9;
|
||||
a.DataTipTemplate.DataTipRows(4).Format = ['%.1f', ' GBd'];
|
||||
a.DataTipTemplate.DataTipRows(5).Label = 'Run ID';
|
||||
a.DataTipTemplate.DataTipRows(5).Value = filteredData.GroupedRunIDs;
|
||||
a.DataTipTemplate.FontSize = 9;
|
||||
a.DataTipTemplate.FontName = 'arial';
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% Custom function to finalize the plot settings
|
||||
function finalizePlot()
|
||||
yline(2e-2, 'DisplayName', '20% O-FEC', 'LineStyle', '--', 'HandleVisibility', 'off');
|
||||
yline(3.8e-3, 'DisplayName', 'HD-FEC', 'LineStyle', '--', 'HandleVisibility', 'off');
|
||||
xlabel('Bit Rate in GBps');
|
||||
ylabel('Bit Error Rate (BER)');
|
||||
xlim([300, 480]);
|
||||
set(gca, 'yscale', 'log');
|
||||
set(gca, 'Box', 'on');
|
||||
grid on;
|
||||
grid minor;
|
||||
legend('Interpreter', 'none');
|
||||
end
|
||||
|
||||
% Custom function using rmoutliers to calculate mean after removing outliers
|
||||
function meanWithoutOutliers = meanExcludingOutliers(x)
|
||||
[xWithoutOutliers,outlierpos] = rmoutliers(x);
|
||||
if isempty(xWithoutOutliers)
|
||||
meanWithoutOutliers = NaN;
|
||||
else
|
||||
meanWithoutOutliers = mean(xWithoutOutliers);
|
||||
end
|
||||
|
||||
end
|
||||
89
projects/HighSpeedExperiment_2024/auswertung/analyze_mu_dc.m
Normal file
89
projects/HighSpeedExperiment_2024/auswertung/analyze_mu_dc.m
Normal file
@@ -0,0 +1,89 @@
|
||||
|
||||
|
||||
if 0
|
||||
uloops = struct;
|
||||
uloops.precomp = [0,1];
|
||||
uloops.db_precode = [0,1];
|
||||
uloops.bitrate = [300,330,360,390,420,450,480].*1e9; %[300,330,360,390,420,450,480]
|
||||
uloops.laser_wavelength = [1293,1302,1310,1318,1327.4];
|
||||
uloops.M = [4,6,8];
|
||||
uloops.link_length = [2]; % 1,2,3,5,6,8,10
|
||||
wh = DataStorage(uloops);
|
||||
wh.addStorage("ber");
|
||||
wh = submit_simulations(wh,"parallel",1,"simulation_mode",0);
|
||||
save('wh_2km',"wh");
|
||||
end
|
||||
|
||||
|
||||
|
||||
for wavelength = wh.parameter.laser_wavelength.values
|
||||
|
||||
cols = linspecer(6);%cbrewer2('Set2',10);
|
||||
figcnt = 0;
|
||||
figWidth = 21; % Full-width for IEEE double-column papers (~7 inches)
|
||||
figHeight = 6; % Adjust height as needed (~3.5 inches)
|
||||
figure('Units','centimeters','Position', [1 1 figWidth figHeight],'PaperUnits','centimeters','PaperPosition', [0 0 figWidth figHeight])
|
||||
tiledlayout(1,3, 'Padding', 'compact', 'TileSpacing', 'compact');
|
||||
for m = uloops.M
|
||||
|
||||
|
||||
|
||||
figcnt = figcnt+1;
|
||||
% subplot(1,3,figcnt)
|
||||
nexttile
|
||||
hold on
|
||||
title(sprintf('%d km | %d nm | PAM %d',uloops.link_length,wavelength,m));
|
||||
|
||||
precomp = 1;
|
||||
db_precode = 0;
|
||||
a = wh.getStoValue('ber',precomp, db_precode, uloops.bitrate , wavelength, m, uloops.link_length);
|
||||
ber_vnle = cellfun(@(x) x.vnle_pf_package{1,1}.ber_vnle, a);
|
||||
ber_vnle_cell = cellfun(@(s) cellfun(@(p) p.ber_vnle, s.vnle_pf_package, 'UniformOutput', true), a, 'UniformOutput', false);
|
||||
ber_vnle_best = cellfun(@(c) min(c), ber_vnle_cell);
|
||||
plot(uloops.bitrate.*1e-9,ber_vnle_best,'DisplayName',sprintf('Tx precomp + VNLE'),'Color',cols(3,:),'LineStyle','-','HandleVisibility','on');
|
||||
xticks(uloops.bitrate.*1e-9);
|
||||
xlim([min(uloops.bitrate.*1e-9) max(uloops.bitrate.*1e-9)]);
|
||||
|
||||
precomp = 0; %0
|
||||
db_precode = 1;
|
||||
a = wh.getStoValue('ber',precomp, db_precode, uloops.bitrate , wavelength, m, uloops.link_length);
|
||||
% ber_db = cellfun(@(x) x.dbtgt_package{1,1}.ber, a);
|
||||
ber_db_cell = cellfun(@(s) cellfun(@(p) p.ber, s.dbtgt_package, 'UniformOutput', true), a, 'UniformOutput', false);
|
||||
ber_db_best = cellfun(@(c) min(c), ber_db_cell);
|
||||
plot(uloops.bitrate.*1e-9,ber_db_best,'DisplayName',sprintf('DB tgt. + MLSE',uloops.link_length,uloops.M),'Color',cols(1,:),'LineStyle','-','HandleVisibility','on');
|
||||
xticks(uloops.bitrate.*1e-9);
|
||||
xlim([min(uloops.bitrate.*1e-9) max(uloops.bitrate.*1e-9)]);
|
||||
|
||||
precomp = 0; %0
|
||||
db_precode = 0; %1
|
||||
a = wh.getStoValue('ber',precomp, db_precode, uloops.bitrate , wavelength, m, uloops.link_length);
|
||||
% ber_mlse = cellfun(@(x) x.vnle_pf_package{1,1}.ber_mlse, a);
|
||||
ber_mlse_cell = cellfun(@(s) cellfun(@(p) p.ber_mlse, s.vnle_pf_package, 'UniformOutput', true), a, 'UniformOutput', false);
|
||||
ber_mlse_best = cellfun(@(c) min(c), ber_mlse_cell);
|
||||
plot(uloops.bitrate.*1e-9,ber_mlse_best,'DisplayName',sprintf('VNLE + 1 tap post-filter + MLSE',uloops.link_length,uloops.M),'Color',cols(4,:),'LineStyle','-','HandleVisibility','on');
|
||||
xticks(uloops.bitrate.*1e-9);
|
||||
xlim([min(uloops.bitrate.*1e-9) max(uloops.bitrate.*1e-9)]);
|
||||
|
||||
set(gca, 'YScale', 'log');
|
||||
ylim([8e-5 0.3]);
|
||||
yline([4.8e-3, 2e-2],'HandleVisibility','off','LineWidth',1,'LineStyle','--','Color',[0.1 0.1 0.1]);
|
||||
% legend
|
||||
beautifyBERplot()
|
||||
xlabel('Bit Rate in Gbps');
|
||||
ylabel('BER');
|
||||
|
||||
if m ==4
|
||||
text(310,6.8e-3,"4.8e-3","FontSize",10,"Interpreter","latex")
|
||||
text(310,3e-2,"2e-2","FontSize",10,"Interpreter","latex")
|
||||
end
|
||||
|
||||
% text(0.5,1,sprintf('%d km %d nm PAM %d',uloops.link_length,wavelength,m),...
|
||||
% 'Units', 'normalized',"FontSize",10,"Interpreter","latex","BackgroundColor",[1 1 1],"EdgeColor",[0 0 0],'HorizontalAlignment','center','VerticalAlignment','top')
|
||||
end
|
||||
|
||||
lgd = legend;
|
||||
% Place the legend underneath the tiled layout
|
||||
lgd.NumColumns = 3;
|
||||
lgd.Layout.Tile = 'south';
|
||||
|
||||
end
|
||||
170
projects/HighSpeedExperiment_2024/auswertung/ber_vs_bitrate.m
Normal file
170
projects/HighSpeedExperiment_2024/auswertung/ber_vs_bitrate.m
Normal file
@@ -0,0 +1,170 @@
|
||||
basePath = 'C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor\';
|
||||
useGui = 0;
|
||||
pamlvls = [4,6,8];
|
||||
wlengths = [1302];
|
||||
figoffset = 0;
|
||||
|
||||
figure(30)
|
||||
tiledlayout(1, 3, 'TileSpacing', 'compact', 'Padding', 'compact');
|
||||
|
||||
for p = 1:numel(pamlvls)
|
||||
nexttile;
|
||||
|
||||
for w = 1:numel(wlengths)
|
||||
sgtitle(['Lambda: ',num2str(wlengths),' nm'])
|
||||
|
||||
hold on
|
||||
pamlvl = pamlvls(p);
|
||||
wlength = wlengths(w);
|
||||
db = DBHandler("pathToDB",[basePath,'silas_labor.db']);
|
||||
if useGui
|
||||
filterParams = db.promptFilterParameters();
|
||||
selectedFields = db.promptSelectFields();
|
||||
else
|
||||
filterParams = db.tables;
|
||||
filterParams.Configurations = struct( ...
|
||||
'bitrate', [], ...
|
||||
'db_mode', [], ...
|
||||
'fiber_length', 10, ...
|
||||
'interference_attenuation', [], ...
|
||||
'interference_path_length', [], ...
|
||||
'is_mpi', 0, ...
|
||||
'pam_level', pamlvl, ...
|
||||
'precomp_amp', [], ...
|
||||
'rop_attenuation', 0, ...
|
||||
'symbolrate', [], ...
|
||||
'v_awg', [], ...
|
||||
'v_bias', [], ...
|
||||
'wavelength', wlength ...
|
||||
);
|
||||
|
||||
selectedFields = {'Runs.run_id','BERs.ber_id','Equalizer.eq_id','Equalizer.eq_type','BERs.ber','BERs.occurrence',...
|
||||
'Configurations.db_mode','Configurations.pam_level','Configurations.bitrate','Configurations.symbolrate','Configurations.fiber_length','Configurations.wavelength','Configurations.precomp_amp',...
|
||||
'Measurements.power_rop','Measurements.power_laser','Measurements.power_pd_in'};
|
||||
end
|
||||
|
||||
% Get data table from DB
|
||||
[dataTable,~] = db.queryDB(filterParams, selectedFields);
|
||||
|
||||
% Grouping variables: 'bitrate' and 'eq_type'
|
||||
groupVars = {'bitrate', 'eq_type'};
|
||||
|
||||
% Calculate mean BER for each combination of 'bitrate' and 'eq_type'
|
||||
groupedData = groupsummary(dataTable, groupVars, {'mean', 'min', @(x) meanExcludingOutliers(x)}, {'ber', 'power_rop','power_pd_in'});
|
||||
|
||||
% Collect the run_id values for each group
|
||||
groupedRunIDs = varfun(@(x) {unique(x)}, dataTable, 'GroupingVariables', groupVars, 'InputVariables', 'run_id');
|
||||
groupedRunIDs.Properties.VariableNames(end) = {'GroupedRunIDs'};
|
||||
|
||||
% Join the grouped data with the grouped run_id list
|
||||
avgdBerTable = join(groupedData, groupedRunIDs, 'Keys', groupVars);
|
||||
|
||||
% Define the fields that you want to use for filtering
|
||||
filterFields = {'eq_type'};
|
||||
|
||||
% Loop over each field you want to filter by
|
||||
for f = 1:numel(filterFields)
|
||||
currentField = filterFields{f};
|
||||
|
||||
% Determine unique values for the current field
|
||||
uniqueValues = unique(avgdBerTable.(currentField));
|
||||
|
||||
% Loop over each unique value for the current field
|
||||
for i = 1:numel(uniqueValues)
|
||||
currentValue = uniqueValues(i);
|
||||
|
||||
% Filter joinedData for the current value
|
||||
if isnumeric(currentValue)
|
||||
filteredData = avgdBerTable(avgdBerTable.(currentField) == currentValue, :);
|
||||
else
|
||||
filteredData = avgdBerTable(strcmp(avgdBerTable.(currentField), currentValue), :);
|
||||
end
|
||||
|
||||
cols = linspecer(8);
|
||||
|
||||
lst = ["-",":","--"];
|
||||
a=plot(filteredData.bitrate.*1e-9,filteredData.min_ber,...
|
||||
'Color',cols(i,:),'MarkerSize',4,'LineWidth',1,'LineStyle',lst(w),...
|
||||
'Marker','o','MarkerFaceColor','auto','MarkerEdgeColor',cols(i,:),...
|
||||
'DisplayName',[char(currentValue),'; ',num2str(wlength),' nm' ]);
|
||||
a.DataTipTemplate.DataTipRows(1).Label = 'Bitrate';
|
||||
a.DataTipTemplate.DataTipRows(1).Format = ['%.1f',' Gbit/s'];
|
||||
|
||||
a.DataTipTemplate.DataTipRows(2).Label = 'BER';
|
||||
a.DataTipTemplate.DataTipRows(2).Format ='%.1e';
|
||||
|
||||
a.DataTipTemplate.DataTipRows(3).Label = 'P_{out}';
|
||||
a.DataTipTemplate.DataTipRows(3).Value = filteredData.mean_power_rop;
|
||||
a.DataTipTemplate.DataTipRows(3).Format = ['%.2f',' dBm'];
|
||||
|
||||
a.DataTipTemplate.DataTipRows(4).Label = 'Run ID';
|
||||
a.DataTipTemplate.DataTipRows(4).Value = filteredData.GroupedRunIDs;
|
||||
a.DataTipTemplate.DataTipRows(4).Format = ['%d',' '];
|
||||
|
||||
|
||||
a.DataTipTemplate.FontSize = 9;
|
||||
a.DataTipTemplate.FontName = 'arial';
|
||||
%
|
||||
% a=scatter(filteredData.bitrate.*1e-9,filteredData.min_ber,5,'Marker','diamond',...
|
||||
% 'Color',cols(i,:),'LineWidth',1,...
|
||||
% 'MarkerFaceColor','auto','MarkerEdgeColor',cols(i,:),...
|
||||
% 'DisplayName',currentValue);
|
||||
%
|
||||
% a.DataTipTemplate.DataTipRows(1).Label = 'Bitrate';
|
||||
% a.DataTipTemplate.DataTipRows(1).Format = ['%.1f',' Gbit/s'];
|
||||
%
|
||||
% a.DataTipTemplate.DataTipRows(2).Label = 'BER';
|
||||
% a.DataTipTemplate.DataTipRows(2).Format ='%.1e';
|
||||
%
|
||||
% a.DataTipTemplate.DataTipRows(3).Label = 'P_{out}';
|
||||
% a.DataTipTemplate.DataTipRows(3).Value = filteredData.mean_power_rop;
|
||||
% a.DataTipTemplate.DataTipRows(3).Format = ['%.2f',' dBm'];
|
||||
%
|
||||
% a.DataTipTemplate.DataTipRows(4).Label = 'Run ID';
|
||||
% a.DataTipTemplate.DataTipRows(4).Value = filteredData.GroupedRunIDs;
|
||||
% a.DataTipTemplate.DataTipRows(4).Format = ['%d',' '];
|
||||
%
|
||||
%
|
||||
% a.DataTipTemplate.FontSize = 9;
|
||||
% a.DataTipTemplate.FontName = 'arial';
|
||||
|
||||
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
% Continue with the rest of your plot settings
|
||||
title(sprintf('%d km | %d nm | PAM %d',unique(filterParams.Configurations.fiber_length),wlength,pamlvl));
|
||||
yline(2e-2, 'DisplayName', '20% O-FEC', 'LineStyle', '--', 'HandleVisibility', 'off','LineWidth',1);
|
||||
yline(3.8e-3, 'DisplayName', 'HD-FEC', 'LineStyle', '--', 'HandleVisibility', 'off','LineWidth',1);
|
||||
xlabel('Bit Rate in Gbps');
|
||||
ylabel('Bit Error Rate');
|
||||
xlim([300, 480])
|
||||
ylim([8e-4,0.5])
|
||||
set(gca, 'yscale', 'log');
|
||||
set(gca, 'Box', 'on');
|
||||
grid on;
|
||||
grid minor;
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
legend('Interpreter', 'none');
|
||||
set(gcf, 'Units', 'pixels', 'Position', 1.0e+03 * [0.2483 0.7303 1.2093 0.3980]);
|
||||
|
||||
% Custom function using rmoutliers to calculate mean after removing outliers
|
||||
function meanWithoutOutliers = meanExcludingOutliers(x)
|
||||
% Remove outliers using rmoutliers with default method (based on median)
|
||||
xWithoutOutliers = rmoutliers(x);
|
||||
|
||||
% Calculate the mean of the non-outliers
|
||||
if isempty(xWithoutOutliers)
|
||||
% Handle the case where all values are outliers
|
||||
meanWithoutOutliers = NaN;
|
||||
else
|
||||
meanWithoutOutliers = mean(xWithoutOutliers);
|
||||
end
|
||||
end
|
||||
192
projects/HighSpeedExperiment_2024/auswertung/ber_vs_length.m
Normal file
192
projects/HighSpeedExperiment_2024/auswertung/ber_vs_length.m
Normal file
@@ -0,0 +1,192 @@
|
||||
basePath = 'C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor\';
|
||||
useGui = 0;
|
||||
pamlvls = [6];
|
||||
wlengths = [1293,1302,1310];%db.distinctValues.Configurations.wavelength
|
||||
figoffset = 20;
|
||||
|
||||
figure(21)
|
||||
tiledlayout(1, 3, 'TileSpacing', 'compact', 'Padding', 'compact');
|
||||
|
||||
|
||||
for w = 1:numel(wlengths)
|
||||
nexttile;
|
||||
for p = 1:numel(pamlvls)
|
||||
pamlvl = pamlvls(p);
|
||||
wlength = wlengths(w);
|
||||
db = DBHandler("pathToDB",[basePath,'silas_labor.db']);
|
||||
if useGui
|
||||
filterParams = db.promptFilterParameters();
|
||||
selectedFields = db.promptSelectFields();
|
||||
else
|
||||
filterParams = db.tables;
|
||||
filterParams.Configurations = struct( ...
|
||||
'bitrate', 420e9, ...
|
||||
'db_mode', [], ...
|
||||
'fiber_length', [], ...
|
||||
'interference_attenuation', [], ...
|
||||
'interference_path_length', [], ...
|
||||
'is_mpi', 0, ...
|
||||
'pam_level', pamlvl, ...
|
||||
'precomp_amp', [], ...
|
||||
'rop_attenuation', 0, ...
|
||||
'symbolrate', [], ...
|
||||
'v_awg', [], ...
|
||||
'v_bias', [], ...
|
||||
'wavelength', wlength ...
|
||||
);
|
||||
% filterParams.Equalizer.eq_type = equalizer_structure.vnle;
|
||||
|
||||
selectedFields = {'Runs.run_id','BERs.ber_id','Equalizer.eq_id','Equalizer.eq_type','BERs.ber','BERs.occurrence',...
|
||||
'Configurations.db_mode','Configurations.pam_level','Configurations.bitrate','Configurations.symbolrate','Configurations.fiber_length','Configurations.wavelength','Configurations.precomp_amp',...
|
||||
'Measurements.power_rop','Measurements.power_laser','Measurements.power_pd_in'};
|
||||
end
|
||||
sgtitle(['Rate: ',num2str(filterParams.Configurations.bitrate),' Gbit/s'])
|
||||
% Get data table from DB
|
||||
[dataTable,~] = db.queryDB(filterParams, selectedFields);
|
||||
|
||||
% Extract unique rows from dataTable for each run_id with relevant configuration details
|
||||
uniqueConfigFields = {'run_id', 'pam_level', 'bitrate','symbolrate', 'fiber_length', 'wavelength', 'precomp_amp', 'db_mode'};
|
||||
[~, uniqueIdx] = unique(dataTable.run_id); % Get unique run_id indices
|
||||
configDetails = dataTable(uniqueIdx, uniqueConfigFields); % Extract unique configurations for each run_id
|
||||
|
||||
% Calculate the mean BER for each combination of 'run_id' and 'eq_type'
|
||||
groupedData = groupsummary(dataTable, {'run_id', 'eq_type'}, {'mean','min'}, {'ber', 'power_rop','power_pd_in'});
|
||||
groupedData = groupsummary(dataTable, {'run_id', 'eq_type'}, {'mean', 'min', @(x) meanExcludingOutliers(x)}, {'ber', 'power_rop','power_pd_in'});
|
||||
|
||||
% Join groupedData with configDetails on the run_id field
|
||||
joinedData = join(groupedData, configDetails, 'Keys', 'run_id');
|
||||
|
||||
|
||||
% Define the fields that you want to use for filtering
|
||||
filterFields = {'eq_type'};
|
||||
|
||||
% Create a cell array to store filtered data tables for each filter field
|
||||
filteredDataByField = struct();
|
||||
|
||||
hold on
|
||||
% Loop over each field you want to filter by
|
||||
for f = 1:numel(filterFields)
|
||||
currentField = filterFields{f};
|
||||
|
||||
% Determine unique values for the current field
|
||||
uniqueValues = unique(joinedData.(currentField));
|
||||
|
||||
% Create a struct entry for the current field
|
||||
filteredDataByField.(currentField) = cell(numel(uniqueValues), 1);
|
||||
|
||||
% Loop over each unique value for the current field
|
||||
for i = 1:numel(uniqueValues)
|
||||
currentValue = uniqueValues(i);
|
||||
|
||||
% Filter joinedData for the current value
|
||||
if isnumeric(currentValue)
|
||||
filteredData = joinedData(joinedData.(currentField) == currentValue, :);
|
||||
else
|
||||
filteredData = joinedData(strcmp(joinedData.(currentField), currentValue), :);
|
||||
end
|
||||
|
||||
%%% workaround to average the BERs of several runs (ie in 1km case or trials)
|
||||
%%% Workaround to average the BERs of several runs (e.g., in 1 km case or trials)
|
||||
|
||||
% Grouping variable(s)
|
||||
groupVars = {'fiber_length'};
|
||||
|
||||
% Use groupsummary to calculate the mean and min of relevant fields
|
||||
groupedDataWithMeans = groupsummary(filteredData, groupVars, {'mean', 'min'}, {'mean_ber', 'min_ber', 'fun1_ber', 'mean_power_rop', 'mean_power_pd_in'});
|
||||
|
||||
% Extract representative values for constant fields
|
||||
[~, uniqueIdx] = unique(filteredData.(groupVars{1})); % Get the first occurrence of each bitrate value
|
||||
constantFields = filteredData(uniqueIdx, {'bitrate', 'GroupCount', 'pam_level', 'symbolrate', 'fiber_length', 'wavelength', 'precomp_amp', 'db_mode'});
|
||||
|
||||
% Keep track of which run_id values were grouped
|
||||
groupedRunIDs = varfun(@(x) {unique(x)}, filteredData, 'GroupingVariables', groupVars, 'InputVariables', 'run_id');
|
||||
groupedRunIDs.Properties.VariableNames(end) = {'GroupedRunIDs'};
|
||||
|
||||
% Join the grouped data with the constant fields
|
||||
groupedDataWithMeans = join(groupedDataWithMeans, constantFields, 'Keys', groupVars);
|
||||
|
||||
% Join the grouped data with the grouped run_id list
|
||||
groupedDataWithMeans = join(groupedDataWithMeans, groupedRunIDs, 'Keys', groupVars);
|
||||
|
||||
% Update filteredData to include the grouped information
|
||||
filteredData = groupedDataWithMeans;
|
||||
%%% end of workaround
|
||||
|
||||
|
||||
|
||||
cols = linspecer(8);
|
||||
% a=plot(filteredData.bitrate.*1e-9,filteredData.mean_mean_ber,...
|
||||
% 'Color',cols(i,:),'MarkerSize',4,'LineWidth',1,'LineStyle',':',...
|
||||
% 'Marker','o','MarkerFaceColor','auto','MarkerEdgeColor',cols(i,:),...
|
||||
% 'DisplayName',currentValue);
|
||||
|
||||
lst = ["-",":","--"];
|
||||
a=plot(filteredData.(groupVars{1}),filteredData.mean_fun1_ber,...
|
||||
'Color',cols(i,:),'MarkerSize',4,'LineWidth',1,'LineStyle',lst(1),...
|
||||
'Marker','o','MarkerFaceColor','auto','MarkerEdgeColor',cols(i,:),...
|
||||
'DisplayName',[char(currentValue),'; ',num2str(wlength),' nm' ]);
|
||||
%
|
||||
% scatter(filteredData.symbolrate.*1e-9,filteredData.min_min_ber,5,'Marker','_',...
|
||||
% 'Color',cols(i,:),'LineWidth',1,...
|
||||
% 'MarkerFaceColor',cols(i,:),'MarkerEdgeColor','black',...
|
||||
% 'DisplayName',currentValue);
|
||||
|
||||
a.DataTipTemplate.DataTipRows(1).Label = groupVars{1};
|
||||
a.DataTipTemplate.DataTipRows(1).Format = ['%.1f',''];
|
||||
|
||||
a.DataTipTemplate.DataTipRows(2).Label = 'BER';
|
||||
a.DataTipTemplate.DataTipRows(2).Format ='%.1e';
|
||||
|
||||
a.DataTipTemplate.DataTipRows(3).Label = 'P_{out}';
|
||||
a.DataTipTemplate.DataTipRows(3).Value = filteredData.mean_mean_power_rop;
|
||||
a.DataTipTemplate.DataTipRows(3).Format = ['%.2f',' dBm'];
|
||||
|
||||
a.DataTipTemplate.DataTipRows(4).Label = 'Baudr';
|
||||
a.DataTipTemplate.DataTipRows(4).Value = filteredData.bitrate .*1e-9;
|
||||
a.DataTipTemplate.DataTipRows(4).Format = ['%.1f',' GBd'];
|
||||
|
||||
a.DataTipTemplate.DataTipRows(5).Label = 'Run ID';
|
||||
a.DataTipTemplate.DataTipRows(5).Value = filteredData.GroupedRunIDs;
|
||||
a.DataTipTemplate.DataTipRows(5).Format = ['%f',' GBd'];
|
||||
|
||||
|
||||
a.DataTipTemplate.FontSize = 9;
|
||||
a.DataTipTemplate.FontName = 'arial';
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
% Continue with the rest of your plot settings
|
||||
title(sprintf('Lambda: %f',wlength));
|
||||
yline(2e-2, 'DisplayName', '20% O-FEC', 'LineStyle', '--', 'HandleVisibility', 'off');
|
||||
yline(3.8e-3, 'DisplayName', 'HD-FEC', 'LineStyle', '--', 'HandleVisibility', 'off');
|
||||
xlabel(groupVars{1},'Interpreter','none');
|
||||
ylabel('Bit Error Rate (BER)');
|
||||
%xlim([300, 480])
|
||||
ylim([8e-4,0.5])
|
||||
set(gca, 'yscale', 'log');
|
||||
set(gca, 'Box', 'on');
|
||||
grid on;
|
||||
grid minor;
|
||||
legend('Interpreter', 'none');
|
||||
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
% Custom function using rmoutliers to calculate mean after removing outliers
|
||||
function meanWithoutOutliers = meanExcludingOutliers(x)
|
||||
% Remove outliers using rmoutliers with default method (based on median)
|
||||
xWithoutOutliers = rmoutliers(x);
|
||||
|
||||
% Calculate the mean of the non-outliers
|
||||
if isempty(xWithoutOutliers)
|
||||
% Handle the case where all values are outliers
|
||||
meanWithoutOutliers = NaN;
|
||||
else
|
||||
meanWithoutOutliers = mean(xWithoutOutliers);
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,554 @@
|
||||
% Connect to SQLite database
|
||||
pathToDB = 'C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor\silas_labor.db'; % Update the path as needed
|
||||
db = DBHandler("pathToDB",pathToDB);
|
||||
|
||||
% main file path
|
||||
sioe_labor_path = 'C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor';
|
||||
|
||||
% Get list of all folders (including subfolders) within sioe_labor_path
|
||||
folderList = dir(fullfile(sioe_labor_path, '**', '*'));
|
||||
|
||||
% Filter to include only directories and exclude '.' and '..'
|
||||
folderNames = {folderList([folderList.isdir]).name};
|
||||
folderPaths = {folderList([folderList.isdir]).folder}; % Get the full paths
|
||||
folderPaths = folderPaths(~ismember(folderNames, {'.', '..'}));
|
||||
folderNames = folderNames(~ismember(folderNames, {'.', '..'}));
|
||||
|
||||
|
||||
% Combine folder names with paths
|
||||
fullFolderPaths = flip(fullfile(folderPaths, folderNames));
|
||||
|
||||
% process only MPI?
|
||||
only_mpi=0;
|
||||
if only_mpi
|
||||
fullFolderPaths = fullFolderPaths(contains(fullFolderPaths,"mpi"));
|
||||
end
|
||||
|
||||
% Shorten folder paths to display only the folder name after the last filesep
|
||||
displayFolderPaths = cellfun(@(x) x(find(x == filesep, 1, 'last') + 1 : end), fullFolderPaths, 'UniformOutput', false);
|
||||
|
||||
% Create checkbox settings for each folder path
|
||||
numFolders = numel(fullFolderPaths);
|
||||
checkboxSettings = cell(1, 2 * numFolders);
|
||||
for i = 1:numFolders
|
||||
checkboxSettings{2*i-1} = {displayFolderPaths{i}; sprintf('Folder_%d', i)};
|
||||
checkboxSettings{2*i} = true; % Set false for unchecked by default
|
||||
end
|
||||
|
||||
% Create settings dialog using settingsdlg
|
||||
[settings, button] = settingsdlg( ...
|
||||
'Description', 'Select Folders to Process:', ...
|
||||
'title', 'Folder Selection', ...
|
||||
checkboxSettings{:});
|
||||
|
||||
% Check if the user pressed OK
|
||||
if strcmp(button, 'OK')
|
||||
% Get all the field names from settings
|
||||
allFields = fieldnames(settings);
|
||||
|
||||
% Determine which folders were selected
|
||||
selectedFoldersIdx = cellfun(@(x) settings.(x), allFields);
|
||||
|
||||
% Get the list of selected folders
|
||||
selectedFolders = fullFolderPaths(selectedFoldersIdx==1);
|
||||
|
||||
% Display the selected folders
|
||||
fprintf('Selected Folders to Process:\n');
|
||||
disp(selectedFolders);
|
||||
else
|
||||
fprintf('No folders selected.\n');
|
||||
end
|
||||
|
||||
|
||||
relativeFolderPaths = strrep(selectedFolders, sioe_labor_path, '');
|
||||
|
||||
disp(['Start to process ',num2str(numel(relativeFolderPaths)), ' folder in the directory']);
|
||||
|
||||
|
||||
for f = 1:numel(selectedFolders)
|
||||
folder = selectedFolders{n};
|
||||
relfolder = relativeFolderPaths{f};
|
||||
|
||||
|
||||
% Get list of all files in the specified folder and subfolders
|
||||
fileList = dir(folder);
|
||||
|
||||
if isempty(fileList(~[fileList.isdir]))
|
||||
continue
|
||||
end
|
||||
|
||||
matches = regexp(folder, '\d+km', 'match');
|
||||
|
||||
% Check if a match was found
|
||||
if ~isempty(matches)
|
||||
|
||||
length_from_foldername_km = matches{1}; % Extract the first match
|
||||
length_from_foldername_km = strrep(length_from_foldername_km,'km','');
|
||||
disp(['The length is: ', length_from_foldername_km]);
|
||||
else
|
||||
disp('No length information found in the folder name.');
|
||||
end
|
||||
|
||||
% Loop through each file and rename if necessary
|
||||
for i = 1:length(fileList)
|
||||
oldName = fileList(i).name;
|
||||
|
||||
% Use regex to find and remove any prefix before the date string
|
||||
newName = regexprep(oldName, '^[^\d]*(\d{8}_\d{6}.*)', '$1');
|
||||
|
||||
% Insert an underscore before "PAM" if missing
|
||||
newName = regexprep(newName, '(\d{8}_\d{6})(PAM)', '$1_PAM');
|
||||
|
||||
% Rename the file only if a change was made
|
||||
if ~strcmp(oldName, newName)
|
||||
movefile(fullfile(fileList(i).folder, oldName), fullfile(fileList(i).folder, newName));
|
||||
fprintf('Renamed: %s -> %s\n', oldName, newName);
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
% Get new list of all files in the specified folder and subfolders, we
|
||||
% renamed files so we need to get the new filenames here to work on :-)
|
||||
fileList = dir(folder);
|
||||
|
||||
% Initialize lists to store DataStorage objects based on size
|
||||
big_wh_list = {}; % For large DataStorage objects
|
||||
big_wh_filename = {}; % Corresponding filenames for large objects
|
||||
small_wh_list = {}; % For small DataStorage objects
|
||||
small_wh_filename = {}; % Corresponding filenames for small objects
|
||||
|
||||
% Loop through each file and categorize based on the presence of 'wh' in the filename
|
||||
for i = 1:length(fileList)
|
||||
fileName = fileList(i).name;
|
||||
if contains(fileName, 'wh')
|
||||
% Load DataStorage object from file
|
||||
wh = load(fullfile(fileList(i).folder, fileName));
|
||||
wh = wh.obj;
|
||||
|
||||
% Classify as big or small based on dimensions
|
||||
if isa(wh, 'DataStorage')
|
||||
if prod(wh.dim) > 2
|
||||
big_wh_list{end+1} = wh;
|
||||
big_wh_filename{end+1} = fileName;
|
||||
else
|
||||
small_wh_list{end+1} = wh;
|
||||
small_wh_filename{end+1} = fileName;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% Aggregate unique parameters across all large DataStorage objects
|
||||
params_merge = struct;
|
||||
for c = 1:numel(big_wh_list)
|
||||
fnames = fieldnames(big_wh_list{c}.parameter);
|
||||
for fn = 1:numel(fnames)
|
||||
% Initialize field if not already present
|
||||
if ~isfield(params_merge, fnames{fn})
|
||||
params_merge.(fnames{fn}) = [];
|
||||
end
|
||||
|
||||
% Merge unique parameter values into params_merge
|
||||
a = big_wh_list{c}.parameter.(fnames{fn}).values;
|
||||
b = params_merge.(fnames{fn});
|
||||
vals_to_add = setdiff(a, b); % New values in a that aren't in b
|
||||
b = sort([b, vals_to_add]); % Combine and sort values
|
||||
params_merge.(fnames{fn}) = b;
|
||||
end
|
||||
end
|
||||
|
||||
% Process each large DataStorage object
|
||||
for w = 1:numel(big_wh_list)
|
||||
wh = big_wh_list{w};
|
||||
% Extract date and time for filename generation
|
||||
datebody = regexp(big_wh_filename{w}, '^\d{8}_\d{6}', 'match', 'once');
|
||||
|
||||
% Get the total number of linear indices
|
||||
totalIndices = wh.getLastLinIndice;
|
||||
|
||||
% Initialize the waitbar
|
||||
h = waitbar(0, 'Processing DataStorage...');
|
||||
|
||||
% Loop over each linear index in DataStorage
|
||||
for i = 1:wh.getLastLinIndice
|
||||
% Update the waitbar with the current progress
|
||||
waitbar(i / totalIndices, h, sprintf('Folder: %s...\n %d of %d', string(strrep(strrep(relfolder, '\', '/'),'_',' ')), i, totalIndices));
|
||||
|
||||
% Initialize record struct for each entry and flag for non-empty data
|
||||
measurementStruct = struct();
|
||||
recordIsFilled = false;
|
||||
|
||||
% Loop over each storage within DataStorage and gather data
|
||||
storage_names = fieldnames(wh.sto);
|
||||
for s = 1:length(storage_names)
|
||||
% Retrieve physical values, parameter names, and stored value
|
||||
[configStruct, stored_value] = wh.getPhysAndValueByLinIndex(storage_names{s}, i);
|
||||
measurementStruct.(storage_names{s}) = stored_value;
|
||||
if ~isempty(stored_value)
|
||||
recordIsFilled = true; % Mark as filled if value is present
|
||||
end
|
||||
end
|
||||
|
||||
[configStruct.precomp_amp_max,configStruct.v_bias_for_pam] = getBias(configStruct.duobinary,configStruct.M);
|
||||
|
||||
isMPI = isfield(measurementStruct,'i_power');
|
||||
|
||||
% Process record if it contains *any* data
|
||||
if recordIsFilled
|
||||
|
||||
if ~isMPI
|
||||
|
||||
% Generate filenames with conditionally formatted parameters
|
||||
% Format the L parameter value (show decimal only if non-zero)
|
||||
if configStruct.lambda == floor(configStruct.lambda)
|
||||
L_str = sprintf('%.0f',configStruct.lambda); % No decimal part
|
||||
else
|
||||
L_str = sprintf('%.1f', configStruct.lambda); % Include one decimal place
|
||||
end
|
||||
|
||||
% Synthesize filename base with placeholders for storage types
|
||||
fbody_tx = sprintf('%s_PAM_%d_L_%s_R_%d_DB_%d_ROP_%d', datebody, ...
|
||||
configStruct.M, L_str, configStruct.bitrate, configStruct.duobinary, 0);
|
||||
fbody_tx = strrep(fbody_tx, '.', '_'); % Replace decimal point with underscore
|
||||
|
||||
if configStruct.rop_atten == round(configStruct.rop_atten)
|
||||
fbody_rx = sprintf('%s_PAM_%d_L_%s_R_%d_DB_%d_ROP_%d', datebody, ...
|
||||
configStruct.M, L_str, configStruct.bitrate, configStruct.duobinary, configStruct.rop_atten);
|
||||
else
|
||||
fbody_rx = sprintf('%s_PAM_%d_L_%s_R_%d_DB_%d_ROP_%.1f', datebody, ...
|
||||
configStruct.M, L_str, configStruct.bitrate, configStruct.duobinary, configStruct.rop_atten);
|
||||
end
|
||||
fbody_rx = strrep(fbody_rx, '.', '_');
|
||||
|
||||
elseif isMPI
|
||||
|
||||
fbody_tx = sprintf('%s_PAM_%d_R_%d_DB_%d_I_atten_%d', datebody, ...
|
||||
configStruct.M, configStruct.bitrate, configStruct.duobinary, 0);
|
||||
fbody_tx = strrep(fbody_tx, '.', '_'); % Replace decimal point with underscore
|
||||
|
||||
if configStruct.interference_atten == round(configStruct.interference_atten)
|
||||
fbody_rx = sprintf('%s_PAM_%d_R_%d_DB_%d_I_atten_%d', datebody, ...
|
||||
configStruct.M, configStruct.bitrate, configStruct.duobinary, configStruct.interference_atten);
|
||||
else
|
||||
fbody_rx = sprintf('%s_PAM_%d_R_%d_DB_%d_I_atten_%.1f', datebody, ...
|
||||
configStruct.M, configStruct.bitrate, configStruct.duobinary, configStruct.interference_atten);
|
||||
end
|
||||
fbody_rx = strrep(fbody_rx, '.', '_'); % Replace decimal point with underscore
|
||||
|
||||
end
|
||||
|
||||
% Check existence of different file types (bits, symbols, raw signal, rx signal)
|
||||
% BIT SEQUENCE
|
||||
fn_bits = [filesep, fbody_tx, '_bits.mat'];
|
||||
fp_bits = fullfile([folder, fn_bits]);
|
||||
if exist(fp_bits, "file") == 2
|
||||
fn_bits_rel = [relfolder, fn_bits];
|
||||
else
|
||||
warning(['Bits not found at: ', fn_bits]);
|
||||
end
|
||||
|
||||
% SYMBOL SEQUENCE
|
||||
fn_symbols = [filesep, fbody_tx, '_symbols.mat'];
|
||||
fp_symbols = fullfile([folder, fn_symbols]);
|
||||
if exist(fp_symbols, "file") == 2
|
||||
fn_symbols_rel = [relfolder, fn_symbols];
|
||||
else
|
||||
warning(['Symbols not found at: ', fn_symbols]);
|
||||
end
|
||||
|
||||
% RAW RX SIGNAL
|
||||
fn_rxraw = [filesep, fbody_rx, '_raw_signal.mat'];
|
||||
fp_rxraw = fullfile([folder, fn_rxraw]);
|
||||
missing_raw_flag = 1; % Initialize as missing
|
||||
|
||||
if exist(fp_rxraw, "file") == 2
|
||||
fn_rxraw_rel = [relfolder, fn_rxraw];
|
||||
missing_raw_flag = 0;
|
||||
end
|
||||
|
||||
% SYNCHRONIZED RX SIGNAL
|
||||
fn_rxtsynch = [filesep, fbody_rx, '_rx_signal.mat'];
|
||||
fp_rxtsynch = fullfile([folder, fn_rxtsynch]);
|
||||
fn_rxtsynch_rel = [];
|
||||
if exist(fp_rxtsynch, "file") == 2
|
||||
fn_rxtsynch_rel = [relfolder, fn_rxtsynch];
|
||||
|
||||
matObj = matfile([folder, fn_rxtsynch]);
|
||||
|
||||
% If RX signal actually contains raw signal, handle as necessary
|
||||
if isprop(matObj, 'Scpe_sig_raw')
|
||||
sig_rx = load([folder, fn_rxtsynch]);
|
||||
if missing_raw_flag
|
||||
% Save as raw signal if original raw signal is missing
|
||||
Scpe_sig_raw = sig_rx.Scpe_sig_raw;
|
||||
save([folder, fn_rxraw], "Scpe_sig_raw");
|
||||
delete([folder, fn_rxtsynch]);
|
||||
else
|
||||
% Check if raw and rx signal files are identical, then delete duplicate
|
||||
sig_raw = load([folder, fn_rxraw]);
|
||||
if isequal(sig_raw, sig_rx)
|
||||
delete([folder, fn_rxtsynch]);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
elseif exist(fp_rxtsynch, "file") == 0
|
||||
|
||||
disp(['RX Signal not found at: ', fn_rxtsynch,' generate and save new one using symbols and raw signal']);
|
||||
|
||||
Scpe_sig_raw = load(fp_rxraw);
|
||||
Scpe_sig_raw = Scpe_sig_raw.Scpe_sig_raw;
|
||||
|
||||
Symbols = load(fp_symbols);
|
||||
Symbols = Symbols.Symbols;
|
||||
%%%%%% Sample to 2x fsym %%%%%%
|
||||
Scpe_sig_resampled = Scpe_sig_raw.resample("fs_in",Scpe_sig_raw.fs,"fs_out",2*Symbols.fs);
|
||||
%%%%%% Sync Rx signal with reference (S is a cell array with all occurences) %%%%%%
|
||||
[Scpe_sig_syncd,S,isFlipped] = Scpe_sig_resampled.tsynch("reference",Symbols,"fs_ref",Symbols.fs);
|
||||
%%%%% Plot and Save Routines: SAVE RECEIVED SIGNALS %%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
save(fp_rxtsynch,"S");
|
||||
|
||||
if exist(fp_rxtsynch, "file") == 0
|
||||
warndlg('Something still wromg... No rx file here but we just generated it from raw signal');
|
||||
end
|
||||
|
||||
fn_rxtsynch_rel = [relfolder, fn_rxtsynch];
|
||||
|
||||
elseif missing_raw_flag
|
||||
warndlg('No RAW or RX signal found! This is bad!');
|
||||
% look at measurementStruct and configStruct
|
||||
end
|
||||
else
|
||||
disp('Record not filled?')
|
||||
% look at measurementStruct and configStruct
|
||||
end
|
||||
|
||||
% Call the duplicate check function
|
||||
if ~isempty(fn_rxtsynch_rel)
|
||||
exists = db.checkIfRunExists('Runs', 'rx_sync_path', fn_rxtsynch_rel);
|
||||
end
|
||||
|
||||
if ~exists
|
||||
|
||||
% Table 1: Append to Runs
|
||||
newRun = db.tables.Runs; % Get the existing table structure (an empty table)
|
||||
newRun = struct(...
|
||||
'run_id', NaN, ... % Auto-increment, leave empty
|
||||
'date_of_run', datetime(datebody, 'InputFormat', 'yyyyMMdd_HHmmss'), ...
|
||||
'tx_bits_path', fn_bits_rel, ...
|
||||
'tx_symbols_path', fn_symbols_rel, ...
|
||||
'rx_sync_path', fn_rxtsynch_rel, ...
|
||||
'rx_raw_path', fn_rxraw_rel, ...
|
||||
'filename', fbody_rx ...
|
||||
);
|
||||
|
||||
% Append the new row to the Runs table and get the generated run ID
|
||||
run_id = db.appendToTable('Runs', newRun);
|
||||
|
||||
if isMPI
|
||||
|
||||
assert(configStruct.interference_atten==measurementStruct.voa.value(4),'MPI attuation differs between voa state and desired config from simulation loop.');
|
||||
interference_attenuation = configStruct.interference_atten;
|
||||
interference_path_length = 2;
|
||||
power_mpi_interference = measurementStruct.voa.power_state(4);
|
||||
power_mpi_signal = measurementStruct.voa.power_state(3);
|
||||
|
||||
rop_attenuation = 0;
|
||||
wavelength = 1310;
|
||||
fiber_length = 1;
|
||||
|
||||
else
|
||||
|
||||
interference_attenuation = NaN;
|
||||
interference_path_length = NaN;
|
||||
power_mpi_interference = NaN;
|
||||
power_mpi_signal = NaN;
|
||||
|
||||
rop_attenuation = configStruct.rop_atten;
|
||||
wavelength = configStruct.lambda;
|
||||
fiber_length = str2double(length_from_foldername_km);
|
||||
|
||||
end
|
||||
% Table 2: Append to Configurations
|
||||
newConfig = db.tables.Configurations; % Get the existing table structure (an empty table)
|
||||
newConfig = struct(...
|
||||
'configuration_id', NaN, ... % Auto-increment, leave empty
|
||||
'run_id', run_id, ... % Foreign key from Runs
|
||||
'unique_elab_id', "20241028-dea635ef776cd18270922ba0e52c65831ff7699f", ... % Set unique_elab_id as needed
|
||||
'bitrate', configStruct.bitrate, ...
|
||||
'symbolrate', floor(configStruct.bitrate * 1e-9 / log2(configStruct.M)) * 1e9, ... % Calculate symbolrate if available
|
||||
'pam_level', configStruct.M, ...
|
||||
'db_mode', configStruct.duobinary, ... % Assuming db_mode corresponds to duobinary mode
|
||||
'v_bias', configStruct.v_bias_for_pam, ...
|
||||
'v_awg', 2.7, ...
|
||||
'precomp_amp', configStruct.precomp_amp_max, ...
|
||||
'rop_attenuation', rop_attenuation, ...
|
||||
'wavelength', wavelength, ...
|
||||
'fiber_length', fiber_length, ...
|
||||
'is_mpi', isMPI, ... % Set false for no MPI, change as needed
|
||||
'interference_path_length', interference_path_length, ... % Set NaN if not applicable
|
||||
'interference_attenuation', interference_attenuation ... % Set NaN if not applicable
|
||||
);
|
||||
|
||||
% Append the new row to the Configurations table
|
||||
db.appendToTable('Configurations', newConfig);
|
||||
|
||||
% Table 3: Append to Measurements
|
||||
newMeas = db.tables.Measurements; % Get the existing table structure (an empty table)
|
||||
newMeas = struct(...
|
||||
'measurement_id', NaN, ... % Auto-increment, leave empty
|
||||
'run_id', run_id, ... % Foreign key from Runs
|
||||
'power_laser', measurementStruct.exfo.cur_power, ...
|
||||
'power_rop', measurementStruct.rop, ...
|
||||
'power_pd_in', measurementStruct.pd_in, ...
|
||||
'power_mpi_interference', power_mpi_interference, ...
|
||||
'power_mpi_signal', power_mpi_signal, ...
|
||||
'voa_class', measurementStruct.voa, ...
|
||||
'pdfa_class', measurementStruct.pdfa, ...
|
||||
'laser_class', measurementStruct.exfo ...
|
||||
);
|
||||
|
||||
% Append the new row to the Measurements table
|
||||
db.appendToTable('Measurements', newMeas);
|
||||
|
||||
% % Table 4: Append to Bers
|
||||
% [ber, structure, settings] = getBers(configStruct,measurementStruct);
|
||||
% for t = 1:numel(ber)
|
||||
%
|
||||
% if iscell(ber(t))
|
||||
% ber_ = ber(t);
|
||||
% ber_ = ber_{1};
|
||||
% else
|
||||
% ber_ = ber(t);
|
||||
% end
|
||||
%
|
||||
% if ber_~=-1
|
||||
%
|
||||
% newBer = struct(...
|
||||
% 'ber_id', NaN,...
|
||||
% 'run_id', run_id,...
|
||||
% 'processing_structure', structure(t),...
|
||||
% 'processing_settings', settings(t),...
|
||||
% 'ber', jsonencode(ber_)...
|
||||
% );
|
||||
%
|
||||
% db.appendToTable('BERs', newBer);
|
||||
%
|
||||
% end
|
||||
%
|
||||
% end
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function [ber, structure, settings] = getBers(configStruct,measurementStruct)
|
||||
|
||||
if configStruct.duobinary == 0
|
||||
|
||||
structure(1) = "vnle";
|
||||
settings(1) = EQ("Ne",[50,7,7],"Nb",[0,0,0],"training_length",4096*2,"training_loops",5,"dd_loops",5,"K",2,"DCmu",0.0,"DDmu",[0.0004 0.0004 0.0004 0.0004 ],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1);
|
||||
ber(1) = measurementStruct.ber_vnle;
|
||||
|
||||
structure(2) = "vnle -> remove DC from error ""Noi{s}.signal = Noi{s}.signal - mean(Noi{s}.signal);"" -> burg(error) -> pf -> mlse";
|
||||
settings(2) = EQ("Ne",[50,7,7],"Nb",[0,0,0],"training_length",4096*2,"training_loops",5,"dd_loops",5,"K",2,"DCmu",0.0,"DDmu",[0.0004 0.0004 0.0004 0.0004 ],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1);
|
||||
ber(2) = measurementStruct.ber_vnle_mlse;
|
||||
|
||||
elseif configStruct.duobinary == 1
|
||||
|
||||
structure(1) = "tx: duobinary precode; rx: db target -> mlse -> modulo";
|
||||
settings(1) = EQ("Ne",[50,7,7],"Nb",[0,0,0],"training_length",4096*2,"training_loops",5,"dd_loops",5,"K",2,"DCmu",0.0,"DDmu",[0.0004 0.0004 0.0004 0.0004 ],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1);
|
||||
ber(1) = measurementStruct.ber_db;
|
||||
|
||||
elseif configStruct.duobinary == 2
|
||||
|
||||
structure(1) = "tx: duobinary precode -> encode; rx: db target -> mlse as decoder -> modulo";
|
||||
settings(1) = EQ("Ne",[50,7,7],"Nb",[0,0,0],"training_length",4096*2,"training_loops",5,"dd_loops",5,"K",2,"DCmu",0.0,"DDmu",[0.0004 0.0004 0.0004 0.0004 ],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1);
|
||||
ber(1) = measurementStruct.ber_db;
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
function [precomp_amp_max,v_bias_for_pam] = getBias(db,M)
|
||||
|
||||
if db == 1
|
||||
ffe_only = 0;
|
||||
postfilter_approach = 0;
|
||||
db_channel_approach = 1;
|
||||
db_coding_approach = 0;
|
||||
db_precode = db_coding_approach || db_channel_approach;
|
||||
if M == 4
|
||||
pulsef=1;
|
||||
precomp_amp_max = -50;
|
||||
v_bias_for_pam = 2.3;
|
||||
pulsef = 1;
|
||||
elseif M == 6
|
||||
pulsef=0;
|
||||
precomp_amp_max = -50;
|
||||
v_bias_for_pam = 2.3;
|
||||
pulsef = 1;
|
||||
elseif M == 8
|
||||
pulsef=0;
|
||||
precomp_amp_max = -50;
|
||||
v_bias_for_pam=2.6;
|
||||
pulsef = 0;
|
||||
end
|
||||
|
||||
elseif db == 2
|
||||
|
||||
ffe_only = 0;
|
||||
postfilter_approach = 0;
|
||||
db_channel_approach = 0;
|
||||
db_coding_approach = 1;
|
||||
db_precode = db_coding_approach || db_channel_approach;
|
||||
if M == 4
|
||||
pulsef=1;
|
||||
precomp_amp_max = -38;
|
||||
v_bias_for_pam = 2.8;
|
||||
pulsef = 1;
|
||||
elseif M == 6
|
||||
pulsef=0;
|
||||
precomp_amp_max = -38;
|
||||
v_bias_for_pam = 2.8;
|
||||
pulsef = 1;
|
||||
elseif M == 8
|
||||
pulsef=0;
|
||||
precomp_amp_max = -38;
|
||||
v_bias_for_pam = 2.8;
|
||||
pulsef = 1;
|
||||
end
|
||||
|
||||
elseif db == 0
|
||||
|
||||
ffe_only = 0;
|
||||
postfilter_approach = 1;
|
||||
db_channel_approach = 0;
|
||||
db_coding_approach = 0;
|
||||
db_precode = db_coding_approach || db_channel_approach;
|
||||
if M == 4
|
||||
pulsef=1;
|
||||
precomp_amp_max = -37;
|
||||
v_bias_for_pam = 2.3;
|
||||
pulsef = 1;
|
||||
elseif M == 6
|
||||
pulsef=0;
|
||||
precomp_amp_max = -34;
|
||||
v_bias_for_pam = 2.3;
|
||||
pulsef = 1;
|
||||
elseif M == 8
|
||||
pulsef=0;
|
||||
precomp_amp_max = -34;
|
||||
v_bias_for_pam=2.6;
|
||||
pulsef = 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
28
projects/HighSpeedExperiment_2024/auswertung/checkDB.m
Normal file
28
projects/HighSpeedExperiment_2024/auswertung/checkDB.m
Normal file
@@ -0,0 +1,28 @@
|
||||
function checkDB(db_path)
|
||||
|
||||
db = DBHandler("pathToDB",db_path);
|
||||
|
||||
num_runs = db.fetch('SELECT COUNT(*) AS total_runs FROM Runs');
|
||||
|
||||
num_configs = db.fetch('SELECT COUNT(*) AS total_configurations FROM Configurations');
|
||||
|
||||
num_meas = db.fetch('SELECT COUNT(*) AS total_measurements FROM Measurements');
|
||||
|
||||
assert((num_runs{1,1}==num_configs{1,1})&&(num_configs{1,1}==num_meas{1,1}),'Different num of entries per table')
|
||||
|
||||
% should not be possible, but check if anyconfig or meas is without
|
||||
% parent Run entry
|
||||
unmatchedConfigs = db.fetch('SELECT COUNT(*) AS unmatched_configs FROM Configurations WHERE run_id NOT IN (SELECT run_id FROM Runs)');
|
||||
unmatchedMeasurements = db.fetch('SELECT COUNT(*) AS unmatched_measurements FROM Measurements WHERE run_id NOT IN (SELECT run_id FROM Runs)');
|
||||
|
||||
if unmatchedConfigs{1,1}~=0 || unmatchedMeasurements{1,1}~=0
|
||||
fprintf('Unmatched Configurations: %d\n', unmatchedConfigs{1,1});
|
||||
fprintf('Unmatched Measurements: %d\n', unmatchedMeasurements{1,1});
|
||||
end
|
||||
|
||||
%Check for any duplicate paths
|
||||
db.fetch("SELECT rx_raw_path, COUNT(*) AS occurrences FROM Runs GROUP BY rx_raw_path HAVING COUNT(*) > 1");
|
||||
db.fetch("SELECT rx_sync_path, COUNT(*) AS occurrences FROM Runs GROUP BY rx_sync_path HAVING COUNT(*) > 1");
|
||||
db.fetch("SELECT filename, COUNT(*) AS occurrences FROM Runs GROUP BY filename HAVING COUNT(*) > 1");
|
||||
|
||||
end
|
||||
42
projects/HighSpeedExperiment_2024/auswertung/checkDBpaths.m
Normal file
42
projects/HighSpeedExperiment_2024/auswertung/checkDBpaths.m
Normal file
@@ -0,0 +1,42 @@
|
||||
% Load the Runs table from the database
|
||||
db = DBHandler("pathToDB", 'C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor\silas_labor.db');
|
||||
runsTable = db.queryDB(db.tables, {'Runs.run_id', 'Runs.tx_bits_path', 'Runs.tx_symbols_path', 'Runs.rx_sync_path', 'Runs.rx_raw_path', 'Runs.filename'});
|
||||
|
||||
% Initialize an array to store the result of existence check
|
||||
fileExistenceResults = false(height(runsTable), 4); % 4 columns for the paths: tx_bits, tx_symbols, rx_sync, rx_raw
|
||||
|
||||
% Main file path
|
||||
sioe_labor_path = 'C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor';
|
||||
|
||||
% Loop through all rows in the table and check paths
|
||||
for i = 1:height(runsTable)
|
||||
fileExistenceResults(i, 1) = exist([sioe_labor_path, runsTable.tx_bits_path{i}], 'file') == 2;
|
||||
fileExistenceResults(i, 2) = exist([sioe_labor_path, runsTable.tx_symbols_path{i}], 'file') == 2;
|
||||
fileExistenceResults(i, 3) = exist([sioe_labor_path, runsTable.rx_sync_path{i}], 'file') == 2;
|
||||
fileExistenceResults(i, 4) = exist([sioe_labor_path, runsTable.rx_raw_path{i}], 'file') == 2;
|
||||
end
|
||||
|
||||
% Identify corrupted run_ids (where any path does not exist)
|
||||
corruptedRunIds = runsTable.run_id(~all(fileExistenceResults, 2));
|
||||
|
||||
% Delete entries in all tables related to corrupted run_ids
|
||||
for i = 1:numel(corruptedRunIds)
|
||||
run_id = corruptedRunIds(i);
|
||||
|
||||
% Delete from BERs table
|
||||
db.executeSQL(sprintf('DELETE FROM BERs WHERE run_id = %d;', run_id));
|
||||
|
||||
% Delete from Equalizer table (if applicable)
|
||||
db.executeSQL(sprintf('DELETE FROM Equalizer WHERE eq_id IN (SELECT eq_id FROM BERs WHERE run_id = %d);', run_id));
|
||||
|
||||
% Delete from Measurements table
|
||||
db.executeSQL(sprintf('DELETE FROM Measurements WHERE run_id = %d;', run_id));
|
||||
|
||||
% Delete from Configurations table
|
||||
db.executeSQL(sprintf('DELETE FROM Configurations WHERE run_id = %d;', run_id));
|
||||
|
||||
% Delete from Runs table
|
||||
db.executeSQL(sprintf('DELETE FROM Runs WHERE run_id = %d;', run_id));
|
||||
end
|
||||
%
|
||||
% disp('Entries for corrupted run_ids have been removed from the database.');
|
||||
@@ -0,0 +1,52 @@
|
||||
function createConfigMenu(DBHandler)
|
||||
% Create the main figure window
|
||||
fig = uifigure('Name', 'Configuration Query', 'Position', [100, 100, 400, 300]);
|
||||
|
||||
% Retrieve tables and table names using the DBHandler class
|
||||
dbTables = DBHandler.getTables();
|
||||
tableNames = DBHandler.getTableNames();
|
||||
|
||||
% Assume that the DBHandler class provides methods to get the unique
|
||||
% configuration options (e.g., PAM levels, bitrates, etc.)
|
||||
uniqueBitrates = unique([dbTables.bitrate]);
|
||||
uniquePAMLevels = unique([dbTables.pam_level]);
|
||||
uniqueWavelengths = unique([dbTables.wavelength]);
|
||||
uniqueDBModes = unique([dbTables.db_mode]);
|
||||
|
||||
% Create dropdown menus for each configuration
|
||||
lblBitrate = uilabel(fig, 'Text', 'Bitrate:', 'Position', [50, 240, 100, 20]);
|
||||
dropdownBitrate = uidropdown(fig, 'Items', string(uniqueBitrates), 'Position', [150, 240, 200, 20]);
|
||||
|
||||
lblPAM = uilabel(fig, 'Text', 'PAM Level:', 'Position', [50, 200, 100, 20]);
|
||||
dropdownPAM = uidropdown(fig, 'Items', string(uniquePAMLevels), 'Position', [150, 200, 200, 20]);
|
||||
|
||||
lblWavelength = uilabel(fig, 'Text', 'Wavelength:', 'Position', [50, 160, 100, 20]);
|
||||
dropdownWavelength = uidropdown(fig, 'Items', string(uniqueWavelengths), 'Position', [150, 160, 200, 20]);
|
||||
|
||||
lblDBMode = uilabel(fig, 'Text', 'DB Mode:', 'Position', [50, 120, 100, 20]);
|
||||
dropdownDBMode = uidropdown(fig, 'Items', string(uniqueDBModes), 'Position', [150, 120, 200, 20]);
|
||||
|
||||
% Create a button to query the configuration
|
||||
btnQuery = uibutton(fig, 'Text', 'Query Configuration', 'Position', [150, 80, 200, 30], ...
|
||||
'ButtonPushedFcn', @(btn, event) queryConfiguration(DBHandler, ...
|
||||
dropdownBitrate.Value, ...
|
||||
dropdownPAM.Value, ...
|
||||
dropdownWavelength.Value, ...
|
||||
dropdownDBMode.Value));
|
||||
|
||||
% Function to handle querying the configuration
|
||||
function queryConfiguration(DBHandler, bitrate, pamLevel, wavelength, dbMode)
|
||||
% Convert dropdown values to numeric if necessary
|
||||
bitrate = str2double(bitrate);
|
||||
pamLevel = str2double(pamLevel);
|
||||
wavelength = str2double(wavelength);
|
||||
dbMode = str2double(dbMode);
|
||||
|
||||
% Query the DBHandler class with the specified configuration
|
||||
results = DBHandler.query(bitrate, pamLevel, wavelength, dbMode);
|
||||
|
||||
% Display the results in the command window (or update the GUI)
|
||||
disp('Query Results:');
|
||||
disp(results);
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,32 @@
|
||||
function [berTable, foundBerFlag] = getBerForRunId(db, run_id)
|
||||
% getBerForRunId Queries the BER data for the specified run_id.
|
||||
% Inputs:
|
||||
% db - The database handler object.
|
||||
% run_id - The run ID for which to get the BER data.
|
||||
% Outputs:
|
||||
% berData - A table containing BER results for the given run ID.
|
||||
|
||||
% Set up filter parameters to query the BER data for the specific run_id
|
||||
filterParams = db.tables;
|
||||
filterParams.Runs.run_id = run_id; % Filter by specific run_id
|
||||
|
||||
% Define the fields to be retrieved from the database
|
||||
selectedFields = {'Runs.run_id', 'BERs.ber_id', 'Equalizer.eq_id', 'Equalizer.eq_type', ...
|
||||
'BERs.ber', 'BERs.occurrence', 'Configurations.db_mode', ...
|
||||
'Configurations.pam_level', 'Configurations.bitrate', 'Configurations.symbolrate', ...
|
||||
'Configurations.fiber_length', 'Configurations.wavelength', ...
|
||||
'Configurations.precomp_amp', 'Measurements.power_rop', 'Measurements.power_laser', ...
|
||||
'Measurements.power_pd_in'};
|
||||
|
||||
% Query the database for the specified run_id
|
||||
[berTable, ~] = db.queryDB(filterParams, selectedFields);
|
||||
|
||||
if ~isnumeric(berTable.ber)
|
||||
foundBerFlag = ~isnan(str2num(berTable.ber));
|
||||
else
|
||||
foundBerFlag = 1;
|
||||
end
|
||||
|
||||
% Display information about the found BER entries
|
||||
% fprintf('Found %d BER entries for run_id %d.\n', size(berTable, 1), run_id);
|
||||
end
|
||||
@@ -0,0 +1,89 @@
|
||||
|
||||
precomp_path = "C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor\precomp";
|
||||
precomp_fn = "lab_high_speed";
|
||||
precomp_mode = 2; %0=do nothing ; 1= measure; 2=precomp active
|
||||
db_precode = 0;
|
||||
db_coding_approach = 0;
|
||||
|
||||
fsym = 224e9;
|
||||
fdac = 256e9;
|
||||
random_key = 0;
|
||||
M = 4;
|
||||
|
||||
if (db_precode==1)&&(db_coding_approach==0)
|
||||
|
||||
if M == 4
|
||||
pulsef=1;
|
||||
precomp_amp_max = -50;
|
||||
elseif M == 6
|
||||
pulsef=0;
|
||||
precomp_amp_max = -50;
|
||||
elseif M == 8
|
||||
pulsef=0;
|
||||
precomp_amp_max = -50;
|
||||
end
|
||||
|
||||
elseif (db_precode==1)&&(db_coding_approach==1)
|
||||
|
||||
if M == 4
|
||||
pulsef=1;
|
||||
precomp_amp_max = -38;
|
||||
pulsef = 1;
|
||||
elseif M == 6
|
||||
pulsef=0;
|
||||
precomp_amp_max = -38;
|
||||
pulsef = 1;
|
||||
elseif M == 8
|
||||
pulsef=0;
|
||||
precomp_amp_max = -38;
|
||||
pulsef = 1;
|
||||
end
|
||||
|
||||
elseif (db_precode==0)&&(db_coding_approach==0)
|
||||
|
||||
if M == 4
|
||||
pulsef=1;
|
||||
precomp_amp_max = -37;
|
||||
pulsef = 1;
|
||||
elseif M == 6
|
||||
pulsef=0;
|
||||
precomp_amp_max = -34;
|
||||
pulsef = 1;
|
||||
elseif M == 8
|
||||
pulsef=0;
|
||||
precomp_amp_max = -34;
|
||||
pulsef = 0;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
rcalpha = 0.05;
|
||||
Pform = Pulseformer("fsym",fsym,"fdac",4*fsym,"pulse","rrc","pulselength",16,"rrcalpha",rcalpha);
|
||||
|
||||
|
||||
Pamsource = PAMsource(...
|
||||
"fsym",fsym,"M",M,"order",19,"useprbs",1,...
|
||||
"fs_out",fdac,...
|
||||
"applyclipping",0,"clipfactor",1.2,...
|
||||
"applypulseform",pulsef,"pulseformer",Pform,...
|
||||
"randkey",random_key,...
|
||||
"db_precode",db_precode,"db_encode",db_coding_approach,...
|
||||
"mrds_code",0,"mrds_blocklength",512);
|
||||
|
||||
[Digi_sig,Symbols,Bits] = Pamsource.process();
|
||||
|
||||
Digi_sig = Digi_sig.normalize("mode","rms");
|
||||
|
||||
Digi_sig.spectrum("displayname","No Precomp","fignum",2223,"normalizeToNyquist",0,"normalizeTo0dB",0);
|
||||
|
||||
precomp_est = ChannelFreqResp("Nacq",2048,"Navg",100,"Ncp",63,'f_ref',Digi_sig.fs);
|
||||
|
||||
Digi_sig = precomp_est.precomp(Digi_sig,'maxampdb',precomp_amp_max,'loadPath',precomp_path,'fileName',precomp_fn);
|
||||
|
||||
Digi_sig = Digi_sig.normalize("mode","rms");
|
||||
|
||||
Digi_sig = Digi_sig.resample("fs_out",fdac);
|
||||
Digi_sig= Digi_sig.normalize("mode","rms");
|
||||
Digi_sig.spectrum("displayname","Strong Precomp","fignum",2223,"normalizeToNyquist",0,"normalizeTo0dB",0);
|
||||
|
||||
|
||||
165
projects/HighSpeedExperiment_2024/auswertung/runDSP.m
Normal file
165
projects/HighSpeedExperiment_2024/auswertung/runDSP.m
Normal file
@@ -0,0 +1,165 @@
|
||||
tic
|
||||
basePath = 'C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor\';
|
||||
useGui = 0;
|
||||
db = DBHandler("pathToDB",[basePath,'silas_labor.db']);
|
||||
|
||||
toc
|
||||
|
||||
if useGui
|
||||
filterParams = db.promptFilterParameters();
|
||||
selectedFields = db.promptSelectFields();
|
||||
else
|
||||
filterParams = db.tables;
|
||||
filterParams.Configurations = struct( ...
|
||||
'bitrate', 300e9, ...
|
||||
'db_mode', 0, ...
|
||||
'fiber_length', 1, ...
|
||||
'interference_attenuation', [], ...
|
||||
'interference_path_length', [], ...
|
||||
'is_mpi', 0, ...
|
||||
'pam_level', 4, ...
|
||||
'precomp_amp', [], ...
|
||||
'rop_attenuation', [], ...
|
||||
'symbolrate', [], ...
|
||||
'v_awg', [], ...
|
||||
'v_bias', [], ...
|
||||
'wavelength', 1310 ...
|
||||
);
|
||||
% filterParams.Runs.run_id = 3303;
|
||||
%filterParams.Equalizer.eq_id = equalizer_structure.vnle;
|
||||
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.fiber_length','Configurations.wavelength','Configurations.precomp_amp','BERs.ber'};
|
||||
end
|
||||
|
||||
toc
|
||||
|
||||
[dataTable,sql_query] = db.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))));
|
||||
|
||||
toc
|
||||
|
||||
fprintf('Processing: %d%%', 0);
|
||||
%2) Process Measurement Config
|
||||
for i = 1:size(dataTable,1)
|
||||
|
||||
fprintf('\b\b\b\b%4d', i); % Backspace 3 characters, then overwrite
|
||||
|
||||
[~, foundBerFlag] = getBerForRunId(db, dataTable.run_id(i));
|
||||
if foundBerFlag
|
||||
continue
|
||||
end
|
||||
|
||||
fprintf('\n%s T: %f CURRENT ID: %d == %d KM == %s PAM %d == %d Gbit/s == %d nm %s \n \n', repmat('=', 1, 10), toc/60, dataTable.run_id(i), dataTable.fiber_length(i) ,db_mode(dataTable.db_mode(i)), dataTable.pam_level(i) ,dataTable.bitrate(i).*1e-9,dataTable.wavelength(i), repmat('=', 1, 10)); % Print a blank line, then a thick line of 80 '=' characters, then another blank line
|
||||
|
||||
% FROM NOW ON, ONE Run_id IS CHOSEN AND WILL BE DSP'd
|
||||
|
||||
tx_bits = load([basePath, char(dataTable.tx_bits_path(i))]);
|
||||
tx_bits = tx_bits.Bits;
|
||||
tx_symbols = load([basePath, char(dataTable.tx_symbols_path(i))]);
|
||||
tx_symbols = tx_symbols.Symbols;
|
||||
rx_sync = load([basePath, char(dataTable.rx_sync_path(i))]);
|
||||
rx_sync = rx_sync.S;
|
||||
%rx_raw = load([basePath, char(result.rx_raw_path(i))]);
|
||||
|
||||
ffe_order=[50,0,0];
|
||||
vnle_order=[50,7,7];
|
||||
dfe_order = [0 0 0];
|
||||
|
||||
len_tr = 4096*2;
|
||||
mu_ffe = [0.0004 0.0004 0.0004];
|
||||
mu_dfe = 0.0004;
|
||||
mu_dc = 0.05;
|
||||
|
||||
dfe_ = sum(dfe_order)>0;
|
||||
|
||||
%Loop through sliced oscilloscope measurement
|
||||
parfor o = 1:numel(rx_sync)
|
||||
rx_sig = rx_sync{o};
|
||||
|
||||
M = dataTable.pam_level(i);
|
||||
|
||||
switch dataTable.db_mode(i)
|
||||
|
||||
case db_mode.no_db
|
||||
|
||||
%FFE
|
||||
eq_ffe(o) = EQ("Ne",ffe_order,"Nb",dfe_order,"training_length",len_tr,"training_loops",5,"dd_loops",5,"K",2,"DCmu",0.05,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1);
|
||||
[eq_sig,eq_noise,ber_ffe(o),totalErrors] = vnle( eq_ffe(o),M,rx_sig,tx_symbols, tx_bits);
|
||||
|
||||
%VNLE
|
||||
eq_vnle(o) = EQ("Ne",vnle_order,"Nb",dfe_order,"training_length",len_tr,"training_loops",5,"dd_loops",5,"K",2,"DCmu",0.05,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1);
|
||||
[eq_sig,eq_noise,ber_vnle(o),totalErrors] = vnle(eq_vnle(o),M,rx_sig,tx_symbols, tx_bits);
|
||||
|
||||
%VNLE + PF + MLSE
|
||||
eq_mlse(o) = EQ("Ne",vnle_order,"Nb",dfe_order,"training_length",len_tr,"training_loops",5,"dd_loops",5,"K",2,"DCmu",0.05,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1);
|
||||
pf_(o) = Postfilter("ncoeff",2);
|
||||
mlse_(o) = MLSE("DIR",[0,0],"duobinary_output",0,"M",[],"trellis_states",[]);
|
||||
[eq_sig,eq_noise,ber_mlse(o),totalErrors] = vnle_postfilter_mlse(eq_mlse(o) , pf_(o), mlse_(o),M, rx_sig,tx_symbols, tx_bits);
|
||||
|
||||
case db_mode.db_precoded
|
||||
|
||||
%EQ targets DB => less precompensation; pre-coded
|
||||
M = dataTable.pam_level(i);
|
||||
mlse_db_pre(o) = MLSE("DIR",[1,1],"duobinary_output",1,"M",M,"trellis_states",PAMmapper(M,0).levels);
|
||||
eq_db_pre(o) = EQ("Ne",vnle_order,"Nb",dfe_order,"training_length",len_tr,"training_loops",5,"dd_loops",5,"K",2,"DCmu",0.05,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1);
|
||||
[eq_sig,eq_noise,ber_db_pre(o),totalErrors] = duobinary_target(eq_db_pre(o), mlse_db_pre(o),M, rx_sig, tx_symbols, tx_bits);
|
||||
%->append BER to DB
|
||||
|
||||
case db_mode.db_encoded
|
||||
|
||||
%db signaling => db encoded
|
||||
M = dataTable.pam_level(i);
|
||||
mlse_db_enc(o) = MLSE("DIR",[1,1],"duobinary_output",1,"M",M,"trellis_states",PAMmapper(M,0).levels);
|
||||
eq_db_enc(o) = EQ("Ne",vnle_order,"Nb",dfe_order,"training_length",len_tr,"training_loops",5,"dd_loops",5,"K",2,"DCmu",0.05,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1);
|
||||
[eq_sig,eq_noise,ber_db_enc(o),totalErrors] = duobinary_signaling(eq_db_enc(o), mlse_db_enc(o),M, rx_sig, tx_symbols, tx_bits);
|
||||
%->append BER to DB
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
for o = 1:numel(rx_sync)
|
||||
switch dataTable.db_mode(i)
|
||||
|
||||
case db_mode.no_db
|
||||
|
||||
%FFE
|
||||
eq_type = equalizer_structure.ffe;
|
||||
db.addBEREntry(ber_ffe(o), o, dataTable.run_id(i), eq_ffe(o), dfe_, [], [], eq_type, ffe_order, dfe_order, len_tr, mu_ffe, mu_dfe, mu_dc, "FFE");
|
||||
showCurrentMeasurement('EQ', string(eq_type), 'BER',ber_ffe(o), 'Mode', string(db_mode(dataTable.db_mode(i))), 'Len', dataTable.fiber_length(i) ,'PAM' , dataTable.pam_level(i) , 'GBit/s' ,dataTable.bitrate(i).*1e-9, 'Lambda' ,dataTable.wavelength(i) );
|
||||
|
||||
%VNLE
|
||||
eq_type = equalizer_structure.vnle;
|
||||
db.addBEREntry(ber_vnle(o), o, dataTable.run_id(i), eq_vnle(o), dfe_, [], [], eq_type, vnle_order, dfe_order, len_tr, mu_ffe, mu_dfe, mu_dc, "VNLE");
|
||||
showCurrentMeasurement('EQ', string(eq_type), 'BER',ber_vnle(o), 'Mode', string(db_mode(dataTable.db_mode(i))), 'Len', dataTable.fiber_length(i) ,'PAM' , dataTable.pam_level(i) , 'GBit/s' ,dataTable.bitrate(i).*1e-9, 'Lambda' ,dataTable.wavelength(i) );
|
||||
|
||||
%MLSE
|
||||
eq_type = equalizer_structure.vnle_pf_mlse;
|
||||
db.addBEREntry(ber_mlse(o), o, dataTable.run_id(i), eq_mlse(o), dfe_, mlse_(o), pf_(o), eq_type, vnle_order, dfe_order, len_tr, mu_ffe, mu_dfe, mu_dc, "VNLE;PF;MLSE");
|
||||
showCurrentMeasurement('EQ', string(eq_type), 'BER',ber_mlse(o), 'Mode', string(db_mode(dataTable.db_mode(i))), 'Len', dataTable.fiber_length(i) ,'PAM' , dataTable.pam_level(i) , 'GBit/s' ,dataTable.bitrate(i).*1e-9, 'Lambda' ,dataTable.wavelength(i) );
|
||||
|
||||
case db_mode.db_precoded
|
||||
|
||||
%db_precoded
|
||||
eq_type = equalizer_structure.db_precoded;
|
||||
db.addBEREntry(ber_db_pre(o), o, dataTable.run_id(i), eq_db_pre(o), dfe_, mlse_db_pre(o), [], eq_type, vnle_order, dfe_order, len_tr, mu_ffe, mu_dfe, mu_dc, "DB Precode;DB Target;MLSE DB Decode;Modulo");
|
||||
showCurrentMeasurement('EQ', string(eq_type), 'BER',ber_db_pre(o), 'Mode', string(db_mode(dataTable.db_mode(i))), 'Len', dataTable.fiber_length(i) ,'PAM' , dataTable.pam_level(i) , 'GBit/s' ,dataTable.bitrate(i).*1e-9, 'Lambda' ,dataTable.wavelength(i) );
|
||||
|
||||
case db_mode.db_encoded
|
||||
|
||||
%db_encoded
|
||||
eq_type = equalizer_structure.db_encoded;
|
||||
db.addBEREntry(ber_db_enc(o), o, dataTable.run_id(i), eq_db_enc(o), dfe_, mlse_db_enc(o), [], eq_type, vnle_order, dfe_order, len_tr, mu_ffe, mu_dfe, mu_dc, "DB Precode;DB Encode;DB Target;MLSE DB Decode;Modulo");
|
||||
showCurrentMeasurement('EQ', string(eq_type), 'BER',ber_db_enc(o), 'Mode', string(db_mode(dataTable.db_mode(i))), 'Len', dataTable.fiber_length(i) ,'PAM' , dataTable.pam_level(i) , 'GBit/s' ,dataTable.bitrate(i).*1e-9, 'Lambda' ,dataTable.wavelength(i) );
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
fprintf('\n%s SIMULATION COMPLETE AFTER %f MINUTES %s \n \n', repmat('=', 1, 35), toc/60 ,repmat('=', 1, 35)); % Print a blank line, then a thick line of 80 '=' characters, then another blank line
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
wh = load('C:\Users\sioe\Documents\High_Speed_Measurement_2024\10km_bitrate_complete\20241030_170224_wh.mat');
|
||||
wh = load('C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor\highspeed_oct_2024\10km_bitrate_complete\20241030_170224_wh.mat');
|
||||
wh = wh.obj;
|
||||
|
||||
M_vals = wh.parameter.M.values;
|
||||
@@ -10,12 +10,17 @@ duobinary_vals = wh.parameter.duobinary.values;
|
||||
rop_atten_vals = wh.parameter.rop_atten.values;
|
||||
|
||||
|
||||
figure(177)
|
||||
|
||||
figure(18)
|
||||
tiledlayout(3, 3, 'TileSpacing', 'compact', 'Padding', 'compact');
|
||||
|
||||
%CHANGE PAM FORMAT HERE (use 4,6,8)
|
||||
for M_choose = [8]
|
||||
sgtitle(['PAM',num2str(M_choose)])
|
||||
for l = 1:numel(lambda_vals)
|
||||
ber_vnle = [];
|
||||
ber_vnle_mlse= [];
|
||||
ber_db= [];
|
||||
ber_db_enc= [];
|
||||
for b = 1:numel(bitrate_vals)
|
||||
|
||||
cel = wh.getStoValue('ber_vnle',M_choose(1),lambda_vals(l),bitrate_vals(b),duobinary_vals(1),rop_atten_vals(1));
|
||||
@@ -36,8 +41,8 @@ for M_choose = [8]
|
||||
end
|
||||
|
||||
cols = linspecer(4);
|
||||
subplot(3,3,l)
|
||||
|
||||
%subplot(3,3,l)
|
||||
nexttile;
|
||||
if M_choose == 4
|
||||
lst = '-';
|
||||
mkr = 'o';
|
||||
@@ -56,24 +61,24 @@ for M_choose = [8]
|
||||
fsym_vals = floor( bitrate_vals*1e-9./log2(M_choose) );
|
||||
hold on
|
||||
|
||||
plot(bitrate_vals*1e-9,ber_db,'Color',cols(1,:),'Marker',mkr,'MarkerFaceColor','auto','DisplayName','DB pre','LineStyle',lst,'HandleVisibility',hv);
|
||||
plot(bitrate_vals*1e-9,ber_db_enc,'Color',cols(2,:)','Marker',mkr,'MarkerFaceColor','auto','DisplayName','DB enc','LineStyle',lst,'HandleVisibility',hv);
|
||||
plot(bitrate_vals*1e-9,ber_vnle,'Color',cols(3,:),'Marker',mkr,'MarkerFaceColor','auto','DisplayName','VNLE','LineStyle',lst,'HandleVisibility',hv);
|
||||
plot(bitrate_vals*1e-9,ber_vnle_mlse,'Color',cols(4,:),'Marker',mkr,'MarkerFaceColor','auto','DisplayName','VNLE+PF+MLSE','LineStyle',lst,'HandleVisibility',hv);
|
||||
plot(bitrate_vals*1e-9,ber_db,'Color',cols(1,:),'Marker',mkr,'MarkerFaceColor','auto','DisplayName','DB pre','LineStyle',lst,'HandleVisibility',hv,'LineWidth',1);
|
||||
plot(bitrate_vals*1e-9,ber_db_enc,'Color',cols(2,:)','Marker',mkr,'MarkerFaceColor','auto','DisplayName','DB enc','LineStyle',lst,'HandleVisibility',hv,'LineWidth',1);
|
||||
plot(bitrate_vals*1e-9,ber_vnle,'Color',cols(3,:),'Marker',mkr,'MarkerFaceColor','auto','DisplayName','VNLE','LineStyle',lst,'HandleVisibility',hv,'LineWidth',1);
|
||||
plot(bitrate_vals*1e-9,ber_vnle_mlse,'Color',cols(4,:),'Marker',mkr,'MarkerFaceColor','auto','DisplayName','VNLE+PF+MLSE','LineStyle',lst,'HandleVisibility',hv,'LineWidth',1);
|
||||
|
||||
% Continue with the rest of your plot settings
|
||||
|
||||
yline(3.8e-3, 'DisplayName', 'HD-FEC', 'LineStyle', '--', 'HandleVisibility', 'off');
|
||||
yline(2e-2, 'DisplayName', '20%', 'LineStyle', '--','LineWidth',1, 'HandleVisibility', 'off');
|
||||
xlabel('Bitrate');
|
||||
ylabel('Bit Error Rate (BER)');
|
||||
%xlabel('Bitrate');
|
||||
ylabel('BER');
|
||||
title([num2str(lambda_vals(l)),' nm']);
|
||||
set(gca, 'yscale', 'log');
|
||||
set(gca, 'Box', 'on');
|
||||
grid on;
|
||||
grid minor;
|
||||
legend('Interpreter', 'none','Location','southwest');
|
||||
ylim([1e-4,1e-1]);
|
||||
% legend('Interpreter', 'none','Location','southwest','Visible','off','HandleVisibility','off');
|
||||
ylim([8e-4,1e-1]);
|
||||
xlim([bitrate_vals(1)*1e-9,bitrate_vals(end)*1e-9])
|
||||
|
||||
end
|
||||
|
||||
87
projects/HighSpeedExperiment_2024/single_auswertung_10km.m
Normal file
87
projects/HighSpeedExperiment_2024/single_auswertung_10km.m
Normal file
@@ -0,0 +1,87 @@
|
||||
|
||||
wh = load('C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor\highspeed_oct_2024\10km_bitrate_complete\20241030_170224_wh.mat');
|
||||
wh = wh.obj;
|
||||
|
||||
M_vals = wh.parameter.M.values;
|
||||
M_choose = M_vals(1);
|
||||
lambda_vals = wh.parameter.lambda.values;
|
||||
bitrate_vals = wh.parameter.bitrate.values;
|
||||
duobinary_vals = wh.parameter.duobinary.values;
|
||||
rop_atten_vals = wh.parameter.rop_atten.values;
|
||||
|
||||
|
||||
figure(11)
|
||||
|
||||
l = 6;
|
||||
for m = 1:numel(M_vals)
|
||||
sgtitle(['Lambda: ',num2str(lambda_vals(l)),' nm'])
|
||||
%for l = 1:numel(lambda_vals)
|
||||
ber_vnle = [];
|
||||
ber_vnle_mlse= [];
|
||||
ber_db= [];
|
||||
ber_db_enc= [];
|
||||
for b = 1:numel(bitrate_vals)
|
||||
|
||||
M_choose = M_vals(m);
|
||||
|
||||
|
||||
cel = wh.getStoValue('ber_vnle',M_choose(1),lambda_vals(l),bitrate_vals(b),duobinary_vals(1),rop_atten_vals(1));
|
||||
ber_vnle(b)=min(cel{1});
|
||||
|
||||
cel = wh.getStoValue('ber_vnle_mlse',M_choose(1),lambda_vals(l),bitrate_vals(b),duobinary_vals(1),rop_atten_vals(1));
|
||||
ber_vnle_mlse(b)=min(cel{1});
|
||||
|
||||
cel = wh.getStoValue('ber_db',M_choose(1),lambda_vals(l),bitrate_vals(b),duobinary_vals(2),rop_atten_vals(1));
|
||||
ber_db(b)=min(cel{1});
|
||||
|
||||
cel = wh.getStoValue('ber_db',M_choose(1),lambda_vals(l),bitrate_vals(b),duobinary_vals(3),rop_atten_vals(1));
|
||||
ber_db_enc(b)=min(cel{1});
|
||||
|
||||
dcs_ = wh.getStoValue('dcs',M_choose(1),lambda_vals(l),bitrate_vals(b),duobinary_vals(2),rop_atten_vals(1));
|
||||
|
||||
|
||||
end
|
||||
|
||||
cols = linspecer(4);
|
||||
subplot(1,3,m)
|
||||
|
||||
if M_choose == 4
|
||||
lst = '-';
|
||||
mkr = 'o';
|
||||
hv = 'on';
|
||||
elseif M_choose == 6
|
||||
lst = '-';
|
||||
mkr = 'x';
|
||||
hv = 'on';
|
||||
elseif M_choose == 8
|
||||
lst = '-';
|
||||
mkr = 'diamond';
|
||||
hv = 'on';
|
||||
end
|
||||
|
||||
|
||||
fsym_vals = floor( bitrate_vals*1e-9./log2(M_choose) );
|
||||
hold on
|
||||
|
||||
plot(bitrate_vals*1e-9,ber_db,'Color',cols(1,:),'Marker',mkr,'MarkerFaceColor','auto','DisplayName','DB pre','LineStyle',lst,'HandleVisibility',hv,'LineWidth',1);
|
||||
plot(bitrate_vals*1e-9,ber_db_enc,'Color',cols(2,:)','Marker',mkr,'MarkerFaceColor','auto','DisplayName','DB enc','LineStyle',lst,'HandleVisibility',hv,'LineWidth',1);
|
||||
plot(bitrate_vals*1e-9,ber_vnle,'Color',cols(3,:),'Marker',mkr,'MarkerFaceColor','auto','DisplayName','VNLE','LineStyle',lst,'HandleVisibility',hv,'LineWidth',1);
|
||||
plot(bitrate_vals*1e-9,ber_vnle_mlse,'Color',cols(4,:),'Marker',mkr,'MarkerFaceColor','auto','DisplayName','VNLE+PF+MLSE','LineStyle',lst,'HandleVisibility',hv,'LineWidth',1);
|
||||
|
||||
% Continue with the rest of your plot settings
|
||||
|
||||
yline(3.8e-3, 'DisplayName', 'HD-FEC', 'LineStyle', '--', 'HandleVisibility', 'off');
|
||||
yline(2e-2, 'DisplayName', '20%', 'LineStyle', '--','LineWidth',1, 'HandleVisibility', 'off');
|
||||
xlabel('Bitrate');
|
||||
ylabel('Bit Error Rate (BER)');
|
||||
title(['PAM ',num2str(M_choose),' ']);
|
||||
set(gca, 'yscale', 'log');
|
||||
set(gca, 'Box', 'on');
|
||||
grid on;
|
||||
grid minor;
|
||||
legend('Interpreter', 'none','Location','southwest');
|
||||
ylim([1e-4,1e-1]);
|
||||
xlim([bitrate_vals(1)*1e-9,bitrate_vals(end)*1e-9])
|
||||
|
||||
%end
|
||||
end
|
||||
@@ -1,70 +0,0 @@
|
||||
|
||||
clear
|
||||
%% Set Simulation Variables
|
||||
|
||||
O = 18; %order of prbs
|
||||
N = 2^(O-1); %length of prbs
|
||||
[~,seed] = prbs(O,1); %initialize first seed of prbs
|
||||
|
||||
% Modulation
|
||||
M = 4; %PAM-M
|
||||
bitpattern = zeros(N,log2(M));
|
||||
|
||||
% Symbol Rate
|
||||
fsym = 112e9;
|
||||
|
||||
% DAC Rate
|
||||
fdac = 120e9;
|
||||
|
||||
% Simulation oversampling rate "k";
|
||||
kover = 16;
|
||||
|
||||
% ADC Rate
|
||||
fadc = 256e9;
|
||||
|
||||
% Simulation frequency in "analog domain"
|
||||
fsimu = kover * fdac ;
|
||||
|
||||
|
||||
|
||||
%% CONSTRUCT ALL CLASSES
|
||||
|
||||
digimod = PAMmapper(M,0);
|
||||
|
||||
pulsef = Pulseformer("pulseform","rrc","fdac",fdac,"fsym",fsym,"pulselength",32,"rrcalpha",0.05);
|
||||
|
||||
awg = AWG('preset','M8199B','fdac',fdac,'kover',kover,'lpf_active',1,'f_cutoff',56e9,'lpf_type',filtertypes.gaussian,'bit_resolution',5.5);
|
||||
|
||||
lp_laser = Filter('filtdegree',1,"f_cutoff",30e9,"fsamp",fdac,"filterType",filtertypes.bessel_inp);
|
||||
|
||||
|
||||
|
||||
%% PROCESS
|
||||
|
||||
% PRBS Generation
|
||||
for i = 1:log2(M)
|
||||
[bitpattern(:,i),seed] = prbs(O,N,seed);
|
||||
end
|
||||
|
||||
% Build Inf. signal class
|
||||
bits = Informationsignal(bitpattern);
|
||||
|
||||
% Digi Mod
|
||||
mod_out = digimod.map(bits);
|
||||
% merken für EQ training
|
||||
reference = mod_out;
|
||||
|
||||
% shape shape
|
||||
mod_out = pulsef.process(mod_out);
|
||||
test = applyPulseShaping(reference.signal,fsym,fdac);
|
||||
|
||||
% AWG -> ELECTRICAL DOMAIN
|
||||
X = lp_laser.process(mod_out);
|
||||
%X.spectrum(fsimu,"displayname",'AWG out','figurename','after AWG');
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
projects/IMDD_base_system/imdd_example_live.mlx
Normal file
BIN
projects/IMDD_base_system/imdd_example_live.mlx
Normal file
Binary file not shown.
367
projects/IMDD_base_system/imdd_it.m
Normal file
367
projects/IMDD_base_system/imdd_it.m
Normal file
@@ -0,0 +1,367 @@
|
||||
|
||||
% basePath = 'C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor\';
|
||||
% db = DBHandler("pathToDB",[basePath,'silas_labor.db']);
|
||||
if 1
|
||||
uloops = struct;
|
||||
uloops.precomp = [0,1];
|
||||
uloops.db_precode = [0,1];
|
||||
uloops.bitrate = [300,330,360,390,420,450,480].*1e9; %[300,330,360,390,420,450,480]
|
||||
% uloops.bitrate = 390e9;
|
||||
% uloops.laser_wavelength = [1293,1297.5,1302,1306.5,1310,1313.4,1318,1322.7,1327.4];
|
||||
uloops.laser_wavelength = [1293];
|
||||
uloops.M = [4,6,8];
|
||||
uloops.link_length = [2]; % 1,2,3,5,6,8,10
|
||||
wh = DataStorage(uloops);
|
||||
wh.addStorage("ber");
|
||||
|
||||
wh = submit_simulations(wh,"parallel",0,"simulation_mode",1);
|
||||
end
|
||||
|
||||
wh_ana = wh;
|
||||
|
||||
ber_mlse = {};
|
||||
ber_vnle = {};
|
||||
inf_rate_vnle ={};
|
||||
|
||||
ber_dbtgt ={};
|
||||
|
||||
ber_dbenc ={};
|
||||
alpha = {};
|
||||
ber_dfe = {};
|
||||
ngmi = [];
|
||||
|
||||
wavelength=1293;
|
||||
for m = [4,6,8]
|
||||
%1302
|
||||
%VNLE
|
||||
precomp = 1;
|
||||
precode = 0;
|
||||
a = wh_ana.getStoValue('ber',precomp, precode, uloops.bitrate , wavelength, m, uloops.link_length);
|
||||
ber_vnle = cellfun(@(x) x.vnle_pf_package{1,1}.ber_vnle, a);
|
||||
|
||||
%MLSE
|
||||
precomp = 0;
|
||||
precode = 1;
|
||||
a = wh_ana.getStoValue('ber',precomp, precode, uloops.bitrate , wavelength, m, uloops.link_length);
|
||||
ber_mlse = cellfun(@(x) x.vnle_pf_package{1,1}.ber_mlse, a);
|
||||
|
||||
%DB
|
||||
precomp = 0;
|
||||
precode = 1;
|
||||
a = wh_ana.getStoValue('ber',precomp, precode, uloops.bitrate , wavelength, m, uloops.link_length);
|
||||
ber_dbtgt = cellfun(@(x) x.dbtgt_package{1,1}.ber, a);
|
||||
|
||||
figure(m+20)
|
||||
hold on
|
||||
title(sprintf('%d km | %d nm | PAM %d',uloops.link_length,wavelength,m));
|
||||
|
||||
plot(uloops.bitrate,ber_vnle,'DisplayName',sprintf('VNLE'),'Color',cols(3,:),'LineStyle','-','HandleVisibility','on');
|
||||
|
||||
plot(uloops.bitrate,ber_dbtgt,'DisplayName',sprintf('DB tgt. + MLSE',uloops.link_length,uloops.M),'Color',cols(1,:),'LineStyle','-','HandleVisibility','on');
|
||||
|
||||
plot(uloops.bitrate,ber_mlse,'DisplayName',sprintf('VNLE + 1 tap post-filter + MLSE',uloops.link_length,uloops.M),'Color',cols(4,:),'LineStyle','-','HandleVisibility','on');
|
||||
|
||||
set(gca, 'YScale', 'log');
|
||||
ylim([5e-5 0.3]);
|
||||
% xlim([min(uloops.bitrate.*1e-9), max(uloops.bitrate.*1e-9) ]);
|
||||
yline([3.8e-3, 2e-2],'HandleVisibility','off');
|
||||
legend
|
||||
beautifyBERplot()
|
||||
xlabel('Bit Rate in Gbps');
|
||||
ylabel('BER');
|
||||
end
|
||||
|
||||
|
||||
cols = linspecer(7);%cbrewer2('Set2',10);
|
||||
|
||||
|
||||
for w = uloops.laser_wavelength
|
||||
|
||||
figure(w)
|
||||
figcnt = 0;
|
||||
|
||||
for precode = uloops.db_precode
|
||||
|
||||
for precomp = uloops.precomp
|
||||
|
||||
for m = uloops.M
|
||||
|
||||
a = wh_ana.getStoValue('ber',precomp, precode, uloops.bitrate , w, m, uloops.link_length);
|
||||
ber_dbtgt = cellfun(@(x) x.dbtgt_package{1,1}.ber, a);
|
||||
|
||||
ber_vnle = cellfun(@(x) x.vnle_pf_package{1,1}.ber_vnle, a);
|
||||
|
||||
ber_mlse = cellfun(@(x) x.vnle_pf_package{1,1}.ber_mlse, a);
|
||||
|
||||
figcnt = figcnt+1;
|
||||
subplot(4,3,figcnt);
|
||||
hold on
|
||||
title(sprintf('precomp = %d | precode = %d | %d km | %d nm | PAM %d',precomp,precode,uloops.link_length,w,m));
|
||||
|
||||
plot(uloops.bitrate,ber_dbtgt,'DisplayName',sprintf('DB tgt. + MLSE',uloops.link_length,uloops.M),'Color',cols(1,:),'LineStyle','-','HandleVisibility','on');
|
||||
|
||||
plot(uloops.bitrate,ber_vnle,'DisplayName',sprintf('VNLE'),'Color',cols(3,:),'LineStyle','-','HandleVisibility','on');
|
||||
|
||||
plot(uloops.bitrate,ber_mlse,'DisplayName',sprintf('VNLE + 1 tap post-filter + MLSE',uloops.link_length,uloops.M),'Color',cols(4,:),'LineStyle','-','HandleVisibility','on');
|
||||
|
||||
% plot(uloops.bitrate,cellfun(@min, ber_dfe),'DisplayName',sprintf('VNLE + DFE',uloops.link_length,uloops.M),'Color',cols(2,:),'LineStyle','--');
|
||||
|
||||
% plot(uloops.bitrate,cellfun(@min, ber_dbenc),'DisplayName',sprintf('DB Encoded',uloops.link_length,uloops.M),'Color',cols(5,:),'LineStyle','-');
|
||||
|
||||
set(gca, 'YScale', 'log');
|
||||
ylim([5e-5 0.5]);
|
||||
% xlim([min(uloops.bitrate.*1e-9), max(uloops.bitrate.*1e-9) ]);
|
||||
yline([3.8e-3, 2e-2],'HandleVisibility','off');
|
||||
legend
|
||||
beautifyBERplot()
|
||||
xlabel('Bit Rate in Gbps');
|
||||
ylabel('Channel Wavelength (nm)');
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
tp = TransmissionPerformance;
|
||||
netRatesVNLE = tp.calculateNetRate(uloops.bitrate, 'NGMI', cellfun(@min, inf_rate_vnle)./log2(uloops.M), 'BER', cellfun(@min, ber_vnle));
|
||||
|
||||
pam8= [2.9515 2.9284 2.9203 2.9311 2.8473 2.7740 2.6253];
|
||||
pam6 = [2.5280 2.5452 2.5579 2.5549 2.5272 2.4243 2.2617];
|
||||
pam4 = [ 1.9982 1.9972 1.9690 1.7909 1.2493 0.8014 0.6385];
|
||||
|
||||
figure(6)
|
||||
hold on
|
||||
title(sprintf('Performance at 1310 for all lengths'));
|
||||
% plot(uloops.bitrate.*1e-9,cellfun(@min, inf_rate_vnle),'DisplayName',sprintf('NGMI VNLE; %d km',uloops.link_length),'Color',cols(3,:),'LineStyle',':');
|
||||
plot(uloops.bitrate.*1e-9,pam4/2,'DisplayName',sprintf('GMI VNLE; PAM 4'),'Color',cols(1,:),'LineStyle',':');
|
||||
plot(uloops.bitrate.*1e-9,pam6/log2(6),'DisplayName',sprintf('GMI VNLE; PAM 6'),'Color',cols(2,:),'LineStyle',':');
|
||||
plot(uloops.bitrate.*1e-9,pam8/3,'DisplayName',sprintf('GMI VNLE; PAM 8'),'Color',cols(3,:),'LineStyle',':');
|
||||
xlabel('Gross Bitrate in Gbps');
|
||||
ylabel('NGMI')
|
||||
beautifyBERplot()
|
||||
ylim([0,1]);
|
||||
|
||||
figure()
|
||||
title(sprintf('%d km | 1310 nm | PAM %d | VNLE',uloops.link_length,uloops.M));
|
||||
hold on
|
||||
line([min(uloops.bitrate.*1e-9) max(uloops.bitrate.*1e-9)],[min(uloops.bitrate.*1e-9) max(uloops.bitrate.*1e-9)],'Color',[.7,.7,.7],'Marker','none','Handlevisibility','off');
|
||||
plot(uloops.bitrate.*1e-9,cellfun(@min, inf_rate_vnle).*uloops.bitrate./log2(uloops.M).*1e-9,'DisplayName',sprintf('AIR'),'Color',cols(1,:),'LineStyle',':');
|
||||
plot(uloops.bitrate.*1e-9,netRatesVNLE.SDHD.NetRate.*1e-9,'DisplayName',sprintf('SD+HD'),'Color',cols(2,:),'LineStyle',':');
|
||||
plot(uloops.bitrate.*1e-9,netRatesVNLE.HD.NetRate.*1e-9,'DisplayName',sprintf('HD'),'Color',cols(3,:),'LineStyle',':');
|
||||
plot(uloops.bitrate.*1e-9,netRatesVNLE.KP4_hamming.NetRate.*1e-9,'DisplayName',sprintf('KP4+Hamming'),'Color',cols(4,:),'LineStyle',':');
|
||||
beautifyBERplot()
|
||||
xlim([min(uloops.bitrate.*1e-9) max(uloops.bitrate.*1e-9)])
|
||||
xlabel('Gross Bitrate in Gbps');
|
||||
ylabel('Net Bitrate in Gbps');
|
||||
legend
|
||||
|
||||
|
||||
% plot(uloops.bitrate.*1e-9,ber_vnle,'DisplayName',sprintf('NGMI MLSE; %d km',len),'Color',cols(1,:),'LineStyle','-');
|
||||
% plot(uloops.bitrate.*1e-9,ber_dfe,'DisplayName',sprintf('NGMI MLSE; %d km',len),'Color',cols(1,:),'LineStyle','-');
|
||||
% plot(uloops.bitrate.*1e-9,ber_mlse,'DisplayName',sprintf('NGMI MLSE; %d km',len),'Color',cols(1,:),'LineStyle','-');
|
||||
% plot(uloops.bitrate.*1e-9,ber_db,'DisplayName',sprintf('NGMI VNLE; %d km',len),'Color',cols(2,:),'LineStyle','-');
|
||||
%
|
||||
% set(gca, 'YScale', 'log');
|
||||
% ylim([1e-5, 0.1]);
|
||||
% yline([3.8e-3;1e-2],'LineWidth',1,'HandleVisibility','off');
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
% for alpha = uloops.alpha
|
||||
% for precode = uloops.db_precode
|
||||
% for precomp = uloops.precomp
|
||||
%
|
||||
%
|
||||
% cols = linspecer(6);%cbrewer2('Set2',10);
|
||||
% cnt = 1;
|
||||
% a = wh.getStoValue('ber',alpha,uloops.vnle_order2,uloops.vnle_order3,precomp, precode, uloops.bitrate,uloops.M);
|
||||
%
|
||||
%
|
||||
% for i = 1:numel(a)
|
||||
% ber_db(i) = mean((a{i}.ber_db));
|
||||
% ber_vnle(i) = mean((a{i}.ber_vnle));
|
||||
% ber_vnle_dfe(i) = mean((a{i}.ber_vnle_dfe));
|
||||
% ber_mlse(i) = mean((a{i}.ber_mlse));
|
||||
% pf_taps(i) = a{i}.pf_taps{1}(2);
|
||||
% vnle_taps(i,:) = a{i}.eq_vnle{1}.e;
|
||||
%
|
||||
% figure(222)
|
||||
%
|
||||
%
|
||||
% subplot(7,3,3*(i-1)+1)
|
||||
% ylim([-0.5 1]);
|
||||
% title(sprintf('%d GBps',uloops.bitrate(i).*1e-9));
|
||||
% hold on
|
||||
% stem(a{i}.eq_vnle{1}.e)
|
||||
%
|
||||
% subplot(7,3,3*(i-1)+2)
|
||||
% ylim([-0.5 1]);
|
||||
% title(sprintf('%d GBps',uloops.bitrate(i).*1e-9));
|
||||
% hold on
|
||||
% stem(a{i}.eq_vnle{1}.e2)
|
||||
%
|
||||
% subplot(7,3,3*(i-1)+3)
|
||||
% ylim([-0.5 1]);
|
||||
% title(sprintf('%d GBps',uloops.bitrate(i).*1e-9));
|
||||
% hold on
|
||||
% stem(a{i}.eq_vnle{1}.e3)
|
||||
%
|
||||
% showEQNoisePSD(a{i}.noise_vnle{1},"fignum",220,"displayname",sprintf('%d 2nd order taps; %d GBps',vnle_order2,uloops.bitrate(i).*1e-9),"postfilter_taps",a{i}.pf_taps{1});
|
||||
%
|
||||
% eq_sig = a{i}.signal_vnle{1};
|
||||
%
|
||||
%
|
||||
% end
|
||||
%
|
||||
% figure()
|
||||
% hold on
|
||||
%
|
||||
% if precomp
|
||||
% lsty = '-';
|
||||
% else
|
||||
% lsty = '-';
|
||||
% end
|
||||
%
|
||||
% if precode
|
||||
% coloffset = 1;
|
||||
% else
|
||||
% coloffset=1;
|
||||
% end
|
||||
%
|
||||
% % plot(uloops.bitrate,ber_mlse,'DisplayName',sprintf('Precomp: %d; Precode %d',precomp,precode),'Color',cols(cnt,:));
|
||||
% title(sprintf('Precomp: %d; Precode %d',precomp,precode));
|
||||
% plot(uloops.bitrate.*1e-9,ber_vnle,'DisplayName','VNLE','Color',cols(4,:),'LineStyle',lsty);
|
||||
% plot(uloops.bitrate.*1e-9,ber_vnle_dfe,'DisplayName','VNLE+DFE','Color',cols(2,:),'LineStyle',lsty);
|
||||
% plot(uloops.bitrate.*1e-9,ber_mlse,'DisplayName','VNLE+PF+MLSE','Color',cols(3,:),'LineStyle',lsty);
|
||||
% plot(uloops.bitrate.*1e-9,ber_db,'DisplayName','DB tgt.','Color',cols(1,:),'LineStyle',lsty);
|
||||
%
|
||||
% cnt = cnt+1;
|
||||
% yline([3.8e-3;1e-2],'LineWidth',1,'HandleVisibility','off');
|
||||
% beautifyBERplot()
|
||||
% end
|
||||
% end
|
||||
% end
|
||||
%
|
||||
%
|
||||
%
|
||||
% for vnle_order3 = uloops.vnle_order3([1,3,5,7,9,10])
|
||||
% cnt = 0;
|
||||
% for vnle_order2 = 3%= uloops.vnle_order2
|
||||
% for precode = uloops.db_precode
|
||||
% for precomp = uloops.precomp
|
||||
%
|
||||
%
|
||||
% cols = linspecer(10);%cbrewer2('Set2',10);
|
||||
% cnt = cnt+1;
|
||||
% a = wh.getStoValue('ber',vnle_order2,vnle_order3,precomp, precode, uloops.bitrate,uloops.M);
|
||||
%
|
||||
%
|
||||
% ber_db(cnt) = mean((a{1}.ber_db));
|
||||
% ber_vnle(cnt) = mean((a{1}.ber_vnle));
|
||||
% ber_vnle_dfe(cnt) = mean((a{1}.ber_vnle_dfe));
|
||||
% ber_mlse(cnt) = mean((a{1}.ber_mlse));
|
||||
% pf_taps(cnt) = a{1}.pf_taps{1}(2);
|
||||
%
|
||||
% showEQNoisePSD(a{1}.noise_vnle{1},"fignum",220,"displayname",sprintf('%d 3rd order taps; %d GBps',vnle_order3,uloops.bitrate(i).*1e-9));
|
||||
%
|
||||
% eq_sig = a{1}.signal_vnle{1};
|
||||
%
|
||||
%
|
||||
% end
|
||||
% end
|
||||
% end
|
||||
%
|
||||
% figure(180)
|
||||
% hold on
|
||||
% scatter(uloops.vnle_order2,ber_mlse,'MarkerEdgeColor',cols(vnle_order3,:),'LineWidth',1,'DisplayName',sprintf('%d 3rd order taps',vnle_order3));
|
||||
% ylim([1e-3 0.5]);
|
||||
%
|
||||
% end
|
||||
% title(sprintf('%d GBps',uloops.bitrate(i).*1e-9));
|
||||
% ylabel('BER');
|
||||
% xlabel('VNLE 2nd order taps');
|
||||
% yline([3.8e-3;1e-2],'LineWidth',1,'HandleVisibility','off');
|
||||
% beautifyBERplot()
|
||||
|
||||
% r = 1;
|
||||
% for rate = uloops.bitrate
|
||||
%
|
||||
% i = 1;
|
||||
% for alpha = uloops.alpha
|
||||
% cols = linspecer(7);%cbrewer2('Set2',10);
|
||||
% cnt = 1;
|
||||
% a = wh.getStoValue('ber',alpha,uloops.vnle_order2,uloops.vnle_order3,precomp, precode, rate,uloops.M);
|
||||
% ber_mlse(i) = mean((a{1}.ber_mlse));
|
||||
% pf_taps(i) = a{1}.pf_taps{1}(2);
|
||||
% i = i+1;
|
||||
% end
|
||||
%
|
||||
% figure(150)
|
||||
% hold on
|
||||
% scatter(pf_taps(1),ber_mlse(1),200,'DisplayName','Burg','MarkerEdgeColor',cols(r,:),'Marker','x','LineWidth',2,'HandleVisibility','off');
|
||||
% plot(uloops.alpha(2:end),ber_mlse(2:end),'DisplayName',sprintf('%d GBps',rate.*1e-9),'Color',cols(r,:),'LineStyle','-');
|
||||
% r=r+1;
|
||||
%
|
||||
% end
|
||||
%
|
||||
%
|
||||
% % title(sprintf('%d GBps',uloops.bitrate.*1e-9));
|
||||
% ylabel('BER');
|
||||
% xlabel('Alpha');
|
||||
% yline([3.8e-3;1e-2],'LineWidth',1,'HandleVisibility','off');
|
||||
% beautifyBERplot()
|
||||
%
|
||||
%
|
||||
%
|
||||
% figure(2024)
|
||||
% hold on
|
||||
% for j = 1:numel(uloops.vnle_order3)
|
||||
% all2nd = wh.getStoValue('ber',uloops.vnle_order3(j), uloops.vnle_order2, uloops.bitrate,uloops.M);
|
||||
% for i = 1:numel(a)
|
||||
% ber_mlse(i) = all2nd{i}.ber_mlse;
|
||||
% ber_vnle(i) = all2nd{i}.ber_vnle;
|
||||
% pf_taps(:,i) = all2nd{i}.pf_taps;
|
||||
%
|
||||
% end
|
||||
% plot(uloops.vnle_order2,ber_mlse,'DisplayName',sprintf('%d 3rd order',uloops.vnle_order3(j)));
|
||||
% end
|
||||
%
|
||||
% yline(3.8e-3,'LineWidth',2,'DisplayName','3.8e-3');
|
||||
% yline(2e-2,'LineWidth',2,'LineStyle','--','DisplayName','2e-2');
|
||||
% beautifyBERplot()
|
||||
% legend
|
||||
%
|
||||
% figure(2025)
|
||||
% clf; % Clear figure so we start fresh
|
||||
%
|
||||
% numJ = numel(uloops.vnle_order3);
|
||||
% numI = numel(uloops.vnle_order2);
|
||||
% ber_mlse_mat = zeros(numJ, numI);
|
||||
%
|
||||
% % Gather data into a 2D matrix
|
||||
% for j = 1:numJ
|
||||
% all2nd = wh.getStoValue('ber', uloops.vnle_order3(j), uloops.vnle_order2, uloops.bitrate, uloops.M);
|
||||
% for i = 1:numI
|
||||
% ber_mlse_mat(j,i) = all2nd{i}.ber_mlse;
|
||||
% end
|
||||
% end
|
||||
%
|
||||
% % Create a 2D plot
|
||||
% % 'imagesc' displays the matrix as an image with a colorbar.
|
||||
% imagesc(uloops.vnle_order2, uloops.vnle_order3, ber_mlse_mat);
|
||||
% set(gca,'YDir','normal'); % Ensure that lower vnle_order3 is at the bottom
|
||||
% colorbar; % Add a colorbar to show BER scale
|
||||
%
|
||||
% xlabel('VNLE Order 2');
|
||||
% ylabel('VNLE Order 3');
|
||||
% title('BER MLSE as a function of VNLE Orders');
|
||||
%
|
||||
% % If you want to highlight certain BER levels, you can add contour lines:
|
||||
% hold on;
|
||||
% [C,h] = contour(uloops.vnle_order2, uloops.vnle_order3, ber_mlse_mat, [3.8e-3, 2e-2], 'LineWidth',2,'LineColor','k');
|
||||
% clabel(C,h,'Color','k','FontWeight','bold');
|
||||
%
|
||||
% beautifyBERplot();
|
||||
% legend('BER contour lines');
|
||||
346
projects/IMDD_base_system/imdd_model.m
Normal file
346
projects/IMDD_base_system/imdd_model.m
Normal file
@@ -0,0 +1,346 @@
|
||||
function [output] = imdd_model(simulation_mode,varargin)
|
||||
|
||||
%%% 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;
|
||||
|
||||
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 = -8;
|
||||
rx_bw_nyquist = 0.8;
|
||||
|
||||
vnle_order1 = 50;
|
||||
vnle_order2 = 7;
|
||||
vnle_order3 = 7;
|
||||
|
||||
vnle_order=[vnle_order1,vnle_order2,vnle_order3];
|
||||
dfe_order = [0 0 0];
|
||||
|
||||
|
||||
alpha = 0;
|
||||
|
||||
len_tr = 4096*2;
|
||||
|
||||
mu_ffe1 = 0.0001;
|
||||
mu_ffe2 = 0.0008;
|
||||
mu_ffe3 = 0.001;
|
||||
mu_dc = 0.005;
|
||||
|
||||
mu_ffe = [mu_ffe1 mu_ffe3 mu_ffe3];
|
||||
mu_dfe = 0.0004;
|
||||
|
||||
|
||||
dfe_ = sum(dfe_order)>0;
|
||||
|
||||
doub_mode = db_mode.db_precoded;
|
||||
|
||||
%%% 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;
|
||||
|
||||
%%% run the simulation or measurement or ...
|
||||
if simulation_mode
|
||||
|
||||
Pform = Pulseformer("fsym",fsym,"fdac",4*fsym,"pulse","rrc","pulselength",16,"rrcalpha",rcalpha);
|
||||
|
||||
[Digi_sig,Symbols,Tx_bits] = PAMsource(...
|
||||
"fsym",fsym,"M",M,"order",17,"useprbs",1,...
|
||||
"fs_out",fdac,...
|
||||
"applyclipping",0,"clipfactor",1.5,...
|
||||
"applypulseform",apply_pulsef,"pulseformer",Pform,...
|
||||
"randkey",random_key,...
|
||||
"db_precode",db_precode,"db_encode",db_encode,...
|
||||
"mrds_code",0,"mrds_blocklength",512).process();
|
||||
|
||||
% Digi_sig.spectrum("displayname",'Digi Spectrum','fignum',10,'normalizeTo0dB',1);
|
||||
|
||||
%%%%% AWG
|
||||
% El_sig = M8199A("kover",kover).process(Digi_sig);
|
||||
El_sig = AWG("fdac",fdac,"f_cutoff",fsym,"lpf_active",0,"kover",kover,"bit_resolution",12,"upsampling_method","samplehold","precomp_sinc_rolloff",1).process(Digi_sig);
|
||||
% El_sig.spectrum("displayname",'Digi Spectrum','fignum',100,'normalizeTo0dB',0);
|
||||
% El_sig = El_sig.setPower(0,"dBm");
|
||||
|
||||
%%%%% Low-pass el. components %%%%%%
|
||||
tx_bwl = tx_bw_nyquist.*f_nyquist;
|
||||
% tx_bwl = 80e9;
|
||||
El_sig = Filter('filtdegree',4,"f_cutoff",tx_bwl,"fs",fdac*kover,"filterType",filtertypes.butterworth,"active",true).process(El_sig);
|
||||
% El_sig.spectrum("displayname",'Digi Spectrum','fignum',100,'normalizeTo0dB',1);
|
||||
|
||||
%%%%% Electrical Driver Amplifier %%%%%%
|
||||
El_sig = Amplifier("amp_mode","ideal_no_noise","gain_mode","gain","amplification_db",3).process(El_sig);
|
||||
El_sig = El_sig.normalize("mode","oneone");
|
||||
|
||||
%%%%% MODULATE E/O CONVERSION %%%%%%
|
||||
[Opt_sig] = EML("mode",eml_mode.im_cosinus,"power",3,"fsimu",El_sig.fs,"lambda",laser_wavelength,"bias",vbias,"u_pi",u_pi,"linewidth",laser_linewidth,"randomkey",random_key+1).process(El_sig);
|
||||
|
||||
Opt_sig = Fiber("fsimu",Opt_sig.fs,"fiber_length",link_length/1000,"alpha",0.3,"D",0,"lambda0",1310,"gamma",0,"Dslope",0.07).process(Opt_sig);
|
||||
|
||||
%%%%%% ROP %%%%%%
|
||||
Rx_sig = Amplifier("amp_mode","ideal_no_noise","gain_mode","output_power","amplification_db",rop).process(Opt_sig);
|
||||
|
||||
%%%%%% PD Square Law %%%%%%
|
||||
Rx_sig = Photodiode("fsimu",fdac*kover,"dark_current",2e-08,"responsivity",1,"temperature",20,"nep",1.8e-11).process(Rx_sig);
|
||||
|
||||
%%%%%% Low-pass RX (PD, El. Connectors and Scope %%%%%%
|
||||
rx_bwl = rx_bw_nyquist.*f_nyquist;
|
||||
% rx_bwl = 80e9;
|
||||
Rx_sig = Filter('filtdegree',4,"f_cutoff",rx_bwl,"fs",fdac*kover,"filterType",filtertypes.butterworth,"active",true).process(Rx_sig);
|
||||
|
||||
% %%%%%% Low-pass Scope %%%%%%
|
||||
Lp_scpe = Filter('filtdegree',4,"f_cutoff",110e9,"fs",fadc,"filterType",filtertypes.butterworth,"active",true);
|
||||
|
||||
% Rx_sig.spectrum("displayname",'Analog Rx Spectrum','fignum',100,'normalizeTo0dB',1);
|
||||
|
||||
%%%%%% Scope %%%%%%
|
||||
Scpe_sig = Scope("fsimu",fdac*kover,"fadc",fadc,...
|
||||
"delay",0,"fixed_delay",0,"filtertype",filtertypes.butterworth,...
|
||||
"samplingdelay",0,"rand_samplingdelay",0,"freq_offset",0,"samp_jitter",0,...
|
||||
"adcresolution",8,"quantbuffer",0.1,'block_dc',1,'lpf_active',1,'H_lpf',Lp_scpe).process(Rx_sig);
|
||||
|
||||
Scpe_cell{1} = Scpe_sig;
|
||||
|
||||
else
|
||||
profile on
|
||||
basePath = 'C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor\';
|
||||
database = DBHandler("pathToDB",[basePath,'silas_labor.db']);
|
||||
profile off
|
||||
basePath = 'C:\Users\Silas\Documents\MATLAB\Datensätze\sioe_labor\';
|
||||
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', 0, ...
|
||||
'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'};
|
||||
|
||||
[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))));
|
||||
|
||||
Tx_bits = load([basePath, char(dataTable.tx_bits_path(end))]);
|
||||
Tx_bits = Tx_bits.Bits;
|
||||
|
||||
Symbols = load([basePath, char(dataTable.tx_symbols_path(end))]);
|
||||
Symbols = Symbols.Symbols;
|
||||
|
||||
Scpe_load = load([basePath, char(dataTable.rx_sync_path(end))]);
|
||||
Scpe_cell = Scpe_load.S;
|
||||
|
||||
|
||||
% Raw_signal = load([basePath, char(dataTable.rx_raw_path(1))]);
|
||||
% Raw_signal = Raw_signal.Scpe_sig_raw;
|
||||
%
|
||||
% Raw_signal = Filter('filtdegree',4,"f_cutoff",Symbols.fs.*0.55,"fs",Raw_signal.fs,"filterType",filtertypes.gaussian,"active",true).process(Raw_signal);
|
||||
%
|
||||
% Scpe_cell{1}.eye(fsym,M,"displayname",'eye','fignum',227);
|
||||
%
|
||||
% Raw_signal.spectrum("normalizeTo0dB",0,"fignum",336,"fft_length",2^12);
|
||||
% Raw_signal.move_it_spectrum("fignum",334);
|
||||
|
||||
fsym = Symbols.fs;
|
||||
|
||||
end
|
||||
|
||||
if db_precode
|
||||
Symbols_precoded = Symbols;
|
||||
end
|
||||
|
||||
output = struct();
|
||||
vnle_pf_package = {};
|
||||
vnle_dfe_package = {};
|
||||
dbtgt_package = {};
|
||||
|
||||
|
||||
proc_occ = min(8,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);
|
||||
|
||||
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 + 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",1,"ideal_dfe",0);
|
||||
|
||||
[result] = vnle(eq_vnle_dfe,M,Scpe_sig,Symbols,Tx_bits,"precode_mode",doub_mode,"showAnalysis",0);
|
||||
vnle_dfe_package{occ} = result;
|
||||
|
||||
|
||||
end
|
||||
%%%%% VNLE + PF + MLSE %%%%
|
||||
if 1
|
||||
|
||||
% 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",1,"useBurg",1);
|
||||
mlse_ = MLSE_viterbi("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels);
|
||||
|
||||
[result] = vnle_postfilter_mlse(eq_vnle_,pf_,mlse_,M,Scpe_sig,Symbols,Tx_bits,"precode_mode",doub_mode,'showAnalysis',1);
|
||||
vnle_pf_package{occ} = result;
|
||||
|
||||
end
|
||||
|
||||
|
||||
%%%%% Duobinary Targeting %%%%
|
||||
if 1
|
||||
|
||||
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);
|
||||
|
||||
[result] = duobinary_target(eq_db, mlse_db, M, Scpe_sig, Symbols, Tx_bits, "precode_mode", doub_mode,'showAnalysis',1);
|
||||
dbtgt_package{occ} = result;
|
||||
|
||||
|
||||
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{occ} = result;
|
||||
end
|
||||
|
||||
|
||||
% autoArrangeFigures;
|
||||
disp('- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ')
|
||||
fprintf('\n')
|
||||
|
||||
|
||||
end
|
||||
|
||||
output.vnle_dfe_package = vnle_dfe_package;
|
||||
output.vnle_pf_package = vnle_pf_package;
|
||||
output.dbtgt_package = dbtgt_package;
|
||||
|
||||
if ~isempty(curFolder)
|
||||
cd(curFolder);
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,227 +0,0 @@
|
||||
function output = imddmodel(sir,dcmode)
|
||||
|
||||
for realiz = 1:3
|
||||
|
||||
rng(realiz);
|
||||
|
||||
%% Set Simulation Variables
|
||||
delay = 0;10+(10*realiz); %mpi delay in meter
|
||||
|
||||
fiblen = 0; %main link in km
|
||||
|
||||
laser_linewidth =0e6;
|
||||
|
||||
O = 18; %order of prbs
|
||||
N = 2^(O-1); %length of prbs
|
||||
[~,seed] = prbs(O,1); %initialize first seed of prbs
|
||||
|
||||
% Modulation
|
||||
M = 4; %PAM-M
|
||||
bitpattern = zeros(N,log2(M));
|
||||
|
||||
% Symbol Rate
|
||||
fsym = 112e9;
|
||||
|
||||
% DAC Rate
|
||||
fdac = 120e9;
|
||||
|
||||
% Simulation oversampling rate "k";
|
||||
kover = 16;
|
||||
|
||||
% ADC Rate
|
||||
fadc = 256e9;
|
||||
|
||||
% Simulation frequency in "analog domain"
|
||||
fsimu = kover * fdac ;
|
||||
|
||||
|
||||
|
||||
%% B) CONSTRUCT ALL CLASSES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
digimod = PAMmapper(M,0);
|
||||
|
||||
pulseform = Pulseformer("pulseform","rrc","fdac",fdac,"fsym",fsym,"pulselength",32,"rrcalpha",0.027);
|
||||
|
||||
awg = AWG('fdac',fdac,'kover',kover,'lpf_active',1,'f_cutoff',56e9,'lpf_type',filtertypes.gaussian,'bit_resolution',5.5);
|
||||
|
||||
lp_laser = Filter('filtdegree',1,"f_cutoff",50e9,"fsamp",fdac*kover,"filterType",filtertypes.bessel_inp);
|
||||
|
||||
u_pi = 3.5;
|
||||
vbias = (0.5*u_pi)-u_pi;
|
||||
extmodlaser = EML("mode",eml_mode.im_cosinus,"power",5,"fsimu",fsimu,"lambda",1550,"bias",vbias,"u_pi",u_pi,"linewidth",laser_linewidth);
|
||||
|
||||
fib = Fiber("fsimu",fdac*kover,"fiber_length",fiblen,"alpha",0.2,"D",16,"lambda0",thz2nm(193.1),"gamma",0);
|
||||
|
||||
reflectionpoint = Amplifier("amp_mode","ideal_no_noise","gain_mode","gain","amplification_db",sir);
|
||||
reflectionprop = Fiber("fsimu",fdac*kover,"fiber_length",delay/1000,"alpha",0.2,"D",16,"lambda0",1550,"gamma",0);
|
||||
|
||||
opticatten = Amplifier("amp_mode","ideal_no_noise","gain_mode","output_power","amplification_db",-8);
|
||||
|
||||
phdiode = Photodiode("fsimu",fdac*kover,"dark_current",2e-08,"responsivity",1,"temperature",20);
|
||||
|
||||
lp_diode = Filter('filtdegree',1,"f_cutoff",50e9,"fsamp",fdac*kover,"filterType",filtertypes.bessel_inp);
|
||||
|
||||
scp = Scope("fsimu",fdac*kover,"fadc",fadc,...
|
||||
"delay",0,"fixed_delay",0,"lpf_bw",113e9,"filtertype",filtertypes.butterworth,...
|
||||
"samplingdelay",0,"rand_samplingdelay",0,"freq_offset",0,"samp_jitter",0,...
|
||||
"adcresolution",6,"quantbuffer",0.1,'block_dc',1);
|
||||
|
||||
eq = EQ("K",2,"plottrain",0,"plotfinal",0,...
|
||||
"training_length",4096,"training_loops",2,...
|
||||
"Ne",[50,5,3],"Nb",[3,2,2],...
|
||||
"DCmu",0.05,"DDmu",[0.0004 0.0005 0.0006 0.0007 ],"DFEmu",0.005,"FFEmu",0.005,...
|
||||
"dd_loops",2,"epsilon",[10 100 1000 ],"M",2,...
|
||||
"thres",[0.005 0.004 0.0005 ],"l1act",0,"delay",0,"rho",0.0005,"ideal_dfe",0,"DB_aim",0);
|
||||
|
||||
eq2 = EQ_silas("Ne",[20,0,0],"Nb",[3,0,0],"trainlength",4096,"mu_dc_dd",0.005,"mu_dc_train",0.05,...
|
||||
"mu_ffe_train",0.005,"mu_combined_dd",[0.0004 0.0006 0.0003 0.005],"ddloops",3,"dcmode",dcmode);
|
||||
|
||||
|
||||
%% C) PROCESS TX %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% 1) PRBS Generation
|
||||
for i = 1:log2(M)
|
||||
[bitpattern(:,i),seed] = prbs(O,N,seed);
|
||||
end
|
||||
|
||||
% 2 ) Build Inf. signal class
|
||||
bits = Informationsignal(bitpattern);
|
||||
|
||||
% 3) Digi modulation -> PAM-M signal
|
||||
digimod_out = digimod.map(bits);
|
||||
|
||||
% 4) Pulse shaping -> racos
|
||||
X = pulseform.process(digimod_out);
|
||||
|
||||
% 5) AWG (lowpass, quantization, sample and hold)
|
||||
X = awg.process(X);
|
||||
|
||||
% 6) Lowpass behavior of laser and hf-cable? why twice?
|
||||
X = lp_laser.process(X);
|
||||
X = lp_laser.process(X);
|
||||
|
||||
% 7) Normalize signal
|
||||
X = X.normalize("mode","oneone");
|
||||
X.signal = X.signal .* 1.3800;
|
||||
|
||||
|
||||
|
||||
%% D) PROCESS OPTICAL CHANNEL %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% 1) Laser; Modulation -> OPTICAL DOMAIN
|
||||
[X,extmodlaser] = extmodlaser.process(X);
|
||||
|
||||
% 2) Main fiber propagation
|
||||
X = fib.process(X);
|
||||
|
||||
if delay ~= 0
|
||||
|
||||
% 3) Reflection
|
||||
% Reflection is just an attenuation
|
||||
R = reflectionpoint.process(X);
|
||||
|
||||
% Propagate back and forth (actual fiber propagation)
|
||||
R = reflectionprop.process(R);
|
||||
|
||||
% Delay the reflected signal
|
||||
[R,n] = R.delay("delay_meter",delay);
|
||||
|
||||
% Add together
|
||||
X.signal = X.signal(n:end);
|
||||
R.signal = R.signal(n:end);
|
||||
|
||||
%disp(['SIR ',num2str(10*log10(X.power/R.power))]);
|
||||
|
||||
X = X+R;
|
||||
|
||||
% 4) Equalize
|
||||
% cut reference signal to correct length (nessecary due to MPI delay)
|
||||
digimod_out.signal = digimod_out.signal(round(n * fsym/fsimu) : end,:);
|
||||
bitpattern = bitpattern(round(n * fsym/fsimu):end,:);
|
||||
end
|
||||
|
||||
% 4) Attenuation
|
||||
X = opticatten.process(X);
|
||||
% X = edfaamp.process(X);
|
||||
|
||||
% 5) Photo Diode -> ELECTRICAL DOMAIN
|
||||
X = phdiode.process(X);
|
||||
X = lp_diode.process(X);
|
||||
|
||||
|
||||
%% E) PROCESS RX %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% 1) Oscilloscope (Sampling to f_adc; Quantization; Bandwidth Limitation)
|
||||
X = scp.process(X);
|
||||
|
||||
% 2) Resample to 2x symbol rate
|
||||
X = X.resample("fs_out",2*fsym,"fs_in",fadc);
|
||||
|
||||
% 3) Normalize
|
||||
Eq_in = X.normalize("mode","rms");
|
||||
|
||||
|
||||
|
||||
% MPI reduction DC removal BEFORE EQ
|
||||
wl = 3000; % symbols
|
||||
Eq_in.signal = Eq_in.signal - 1/wl .* movsum( Eq_in.signal,[wl/2,wl/2]);
|
||||
|
||||
% Equalize Signal
|
||||
[Eq_out] = eq2.process(Eq_in,digimod_out);
|
||||
|
||||
|
||||
|
||||
|
||||
%% A1: MPI reduction DC removal
|
||||
wl = 1000; % symbols
|
||||
yk_dcsm = Eq_out;
|
||||
yk_dcsm.signal = Eq_out.signal - 1/wl .* movsum( Eq_out.signal,[wl/2,wl/2]);
|
||||
|
||||
%% A2: MPI reduction Level wise error removal
|
||||
yk_lvsm = Eq_out;
|
||||
yk_lvlp = Eq_out;
|
||||
pre_decision_level_uni = digimod.decide_pamlevel(Eq_out);
|
||||
pre_decision_level_bi = ( pre_decision_level_uni*2-3 ) .* 1/sqrt(5);
|
||||
|
||||
e = Eq_out.signal - pre_decision_level_bi;
|
||||
|
||||
lp_mpi = Filter('filtdegree',1,"f_cutoff",2e6,"fsamp",fsym,"filterType",filtertypes.bessel_inp);
|
||||
|
||||
filtered = lp_mpi.process(e);
|
||||
|
||||
wl = 30; % symbols
|
||||
smoothed = ( 1/wl .* movsum(e,[wl/2,wl/2]) );
|
||||
|
||||
% remove interference
|
||||
for level = 0:3
|
||||
yk_lvsm.signal(pre_decision_level_uni==level) = yk_lvsm.signal(pre_decision_level_uni==level) - smoothed(pre_decision_level_uni==level);
|
||||
yk_lvlp.signal(pre_decision_level_uni==level) = yk_lvlp.signal(pre_decision_level_uni==level) - filtered(pre_decision_level_uni==level);
|
||||
end
|
||||
|
||||
%% PROCESS RX %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% 1) Digi Demod
|
||||
d_bm = digimod.demap(Eq_out);
|
||||
d_dcsm = digimod.demap(yk_dcsm);
|
||||
d_lvsm = digimod.demap(yk_lvsm);
|
||||
d_lvlp = digimod.demap(yk_lvlp);
|
||||
|
||||
% 2) BER
|
||||
|
||||
dbit = length(d_bm.signal)-length(bitpattern);
|
||||
|
||||
[~,errors_bm,ber_bm(realiz),loc] = calc_ber(d_bm.signal(1:end-dbit,:) ,bitpattern(1:end,:),"skip",0,"returnErrorLocation",1);
|
||||
[~,errors_dcsm,ber_dcsm(realiz)] = calc_ber(d_dcsm.signal(1:end-dbit,:) ,bitpattern(1:end,:),"skip",0,"returnErrorLocation",0);
|
||||
[~,errors_lvsm,ber_lvsm(realiz)] = calc_ber(d_lvsm.signal(1:end-dbit,:) ,bitpattern(1:end,:),"skip",0,"returnErrorLocation",0);
|
||||
[~,errors_lvlp,ber_lvlp(realiz)] = calc_ber(d_lvlp.signal(1:end-dbit,:) ,bitpattern(1:end,:),"skip",0,"returnErrorLocation",0);
|
||||
|
||||
|
||||
end
|
||||
|
||||
output.ber_bm = mean(ber_bm);
|
||||
output.ber_dcsm = mean(ber_dcsm);
|
||||
output.ber_lvsm = mean(ber_lvsm);
|
||||
output.ber_lvlp = mean(ber_lvlp);
|
||||
|
||||
|
||||
end
|
||||
46
projects/IMDD_base_system/parameters.m
Normal file
46
projects/IMDD_base_system/parameters.m
Normal file
@@ -0,0 +1,46 @@
|
||||
% TX
|
||||
M = 4;
|
||||
fsym = 180e9;
|
||||
f_nyquist = fsym/2;
|
||||
apply_pulsef = 0;
|
||||
fdac = 2*fsym;%256e9;
|
||||
fadc = 2*fsym;%256e9;
|
||||
fdac = 256e9;
|
||||
fadc = 256e9;
|
||||
random_key = 1;
|
||||
db_precode = 0;
|
||||
emulate_precode = 0;
|
||||
discard_precode = 0;
|
||||
db_encode = 0;
|
||||
% duob_mode = db_mode.db_emulate;
|
||||
emulate_db = 1;
|
||||
rcalpha = 0.05;
|
||||
kover = 16;
|
||||
vbias_rel = 0.5;
|
||||
u_pi = 2.9;
|
||||
vbias = -vbias_rel*u_pi;
|
||||
laser_wavelength = 1310;
|
||||
laser_linewidth = 0;
|
||||
tx_bw_nyquist = 1.5;
|
||||
|
||||
% Channel
|
||||
link_length = 1;
|
||||
|
||||
% RX
|
||||
rop = -8;
|
||||
rx_bw_nyquist = 0.7;
|
||||
|
||||
% EQ
|
||||
eq_mode = equalizer_structure.vnle_pf_mlse;
|
||||
ffe_order=[50,0,0];
|
||||
vnle_order=[50,7,7];
|
||||
dfe_order = [2 0 0];
|
||||
|
||||
len_tr = 4096*2;
|
||||
mu_ffe = [0.0004 0.0004 0.0004];
|
||||
mu_dfe = 0.0004;
|
||||
mu_dc = 0.00;
|
||||
|
||||
dfe_ = sum(dfe_order)>0;
|
||||
|
||||
|
||||
@@ -1,208 +0,0 @@
|
||||
|
||||
clear
|
||||
|
||||
sir_loop = [-25:2:-13];
|
||||
sir_loop = 0;
|
||||
lw_loop = [1,2,3];
|
||||
|
||||
data = cell(length(sir_loop),length(lw_loop));
|
||||
|
||||
iterations=size(data);
|
||||
|
||||
parfor ix = 1:numel(data)
|
||||
|
||||
[u1,u2] = ind2sub(iterations,ix);
|
||||
|
||||
output = imddmodel(sir_loop(u1),lw_loop(u2));
|
||||
|
||||
data{ix} = output;
|
||||
|
||||
end
|
||||
|
||||
for sir = 1:size(data,1)
|
||||
for lw = 1:size(data,2)
|
||||
ber_bm(sir,lw) = data{sir,lw}.ber_bm;
|
||||
ber_dcsm(sir,lw) = data{sir,lw}.ber_dcsm;
|
||||
ber_lvsm(sir,lw) = data{sir,lw}.ber_lvsm;
|
||||
ber_lvlp(sir,lw) = data{sir,lw}.ber_lvlp;
|
||||
end
|
||||
end
|
||||
|
||||
col = [ 0.6510 0.8078 0.8902
|
||||
0.6980 0.8745 0.5412
|
||||
0.9922 0.7490 0.4353];
|
||||
figure(22)
|
||||
for l = 1:numel(lw_loop)
|
||||
hold on
|
||||
plot(sir_loop,ber_bm(:,l),'DisplayName',['DC mode:', num2str(lw_loop(l)),', Linewidth= 50 MHz'],'Marker','o','MarkerFaceColor',col(l,:),'Color',col(l,:),'LineWidth',2,'LineStyle','--');
|
||||
end
|
||||
set(gca,'yscale','log');
|
||||
yline(3.8e-3,'LineWidth',2,'LineStyle','--','HandleVisibility','off');
|
||||
set(gca,'xdir','reverse');
|
||||
|
||||
|
||||
|
||||
%% Plot
|
||||
col = linspecer(8);
|
||||
figure(1)
|
||||
hold on
|
||||
m = ["x","o","pentagram","hexagram","*","+"];
|
||||
cnt = 1;
|
||||
for d = 1%:size(data,2)
|
||||
for dc = 1:size(data,1)
|
||||
for lw = 1:size(data,3)
|
||||
ber_bm(dc,d,lw) = (data{dc,d,lw}.ber_bm);
|
||||
ber_dcsm(dc,d,lw) = data{dc,d,lw}.ber_dcsm;
|
||||
ber_lvsm(dc,d,lw) = data{dc,d,lw}.ber_lvsm;
|
||||
ber_lvlp(dc,d,lw) = (data{dc,d,lw}.ber_lvlp);
|
||||
end
|
||||
end
|
||||
i = 1;
|
||||
comm_dn = [];% ['EQ DC Tap: ',num2str(dc_tap_loop(d)),' m'];
|
||||
title("Dependency on Laser Linewidth; B2B; Delay : 2*50m")
|
||||
plot(lw_loop*1e-6,mean(squeeze(ber_bm(1:end,d,:)),1),"LineWidth",1.2,"Marker",m(1),"MarkerSize",5,'Color',col(cnt,:),'DisplayName',[' ',comm_dn]);
|
||||
plot(lw_loop*1e-6,mean(squeeze(ber_dcsm(1:end,d,:)),1),"LineWidth",1,"Marker",m(1+4),"MarkerSize",5,'LineStyle','--','Color',col(cnt,:),'DisplayName',['DC smoothing ',comm_dn],'HandleVisibility','on');
|
||||
plot(lw_loop*1e-6,mean(squeeze(ber_lvsm(1:end,d,:)),1),"LineWidth",1.2,"Marker",m(1+1),"MarkerSize",5,'LineStyle',':','Color',col(cnt,:),'DisplayName',['Lvl Smoothing ',comm_dn],'HandleVisibility','on');
|
||||
plot(lw_loop*1e-6,mean(squeeze(ber_lvlp(1:end,d,:)),1),"LineWidth",1,"Marker",m(1+3),"MarkerSize",5,'LineStyle','-.','Color',col(cnt,:),'DisplayName',['Lvl Lowpass ',comm_dn],'HandleVisibility','on');
|
||||
set(gca,'yscale','log');
|
||||
set(gca,'xscale','log');
|
||||
%xticklabels([10 100 1000 10000]);
|
||||
grid minor
|
||||
yline(3.8e-3,'LineWidth',2,'LineStyle','--','HandleVisibility','off');
|
||||
ylim([1e-3 4e-2]);
|
||||
ylabel("BER");
|
||||
xlabel("Linewidth in MHz")
|
||||
legend
|
||||
cnt = cnt+1;
|
||||
end
|
||||
|
||||
|
||||
figure(1)
|
||||
contour(lw_loop,sir_loop,thres_a0,16:0.4:21,'LineWidth',2,'FaceAlpha',0.3,'ShowText','on',"LabelFormat","%0.1f dB");
|
||||
clim([16 21]);
|
||||
ylabel("Bandwidth in Multiples of Linewidth");
|
||||
xlabel("Linewidth in MHz");
|
||||
% set(gca,'yscale','log');
|
||||
grid minor
|
||||
title("MPI removal - Optimization of Lowpass Filter Bandwidth")
|
||||
|
||||
figure(2)
|
||||
contour(lw_loop,sir_loop([1:10,12:end]),thres_a0([1:10,12:end],:),16:0.3:21,'LineWidth',2,'FaceAlpha',0.3,'ShowText','on',"LabelFormat","%0.1f dB");
|
||||
clim([16 21]);
|
||||
ylabel("Window Length");
|
||||
xlabel("Linewidth in MHz");
|
||||
set(gca,'yscale','log');
|
||||
grid minor
|
||||
title("MPI removal - Optimization of Averaging Window Length")
|
||||
|
||||
|
||||
|
||||
%% Plot Winlen Contour
|
||||
hdfec = 3.8e-3.*ones(size(sir_loop));
|
||||
|
||||
for dc = 1:size(data,2)
|
||||
for lw = 1:size(data,3)
|
||||
for s = 1:size(data,1)
|
||||
ber_lvlp(s,dc,lw) = data{s,dc,lw}.ber_dcsm;
|
||||
% ber_dcsm(wl,lw,s) = data{wl,s,lw}.ber_dcsm;
|
||||
end
|
||||
|
||||
a_bm = InterX([sir_loop;squeeze(ber_lvlp(:,dc,lw))'],[sir_loop;hdfec]);
|
||||
% a_dcsm = InterX([sirloop;squeeze(ber_dcsm(wl,lw,:))'],[sirloop;hdfec]);
|
||||
try
|
||||
thres_a0(dc,lw) = -a_bm(1);
|
||||
%thres_a1(wl,lw) = -a_dcsm(1);
|
||||
catch
|
||||
thres_a0(dc,lw) = NaN;
|
||||
%thres_a1(wl,lw) = NaN;
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
figure(1)
|
||||
contour(lw_loop,bw_loop,thres_a0,14:0.2:21,'LineWidth',1.5,'FaceAlpha',0.3,'ShowText','on',"LabelFormat","%0.1f dB");
|
||||
a = flip(cbrewer2('seq','Spectral',32));
|
||||
a = [a(1:12,:); a(22:end,:)];
|
||||
colormap(a);
|
||||
clim([16 21]);
|
||||
ylabel("Window Length");
|
||||
xlabel("Linewidth in MHz");
|
||||
yticks(bw_loop);
|
||||
yticklabels(bw_loop);
|
||||
set(gca,'yscale','log');
|
||||
set(gca,'xscale','log');
|
||||
grid minor
|
||||
|
||||
|
||||
|
||||
|
||||
%% Plot DC Tap Contour
|
||||
hdfec = 3.8e-3.*ones(size(bw_loop));
|
||||
thres_a0 = zeros(size(ber,1),size(ber,3));
|
||||
thres_a1 = zeros(size(ber,1),size(ber,3));
|
||||
for dc = 1:size(ber,1)
|
||||
for lw = 1:size(ber,3)
|
||||
a_lvsm = InterX([bw_loop;ber(dc,:,lw)],[bw_loop;hdfec]);
|
||||
thres_a0(dc,lw) = -a_lvsm(1);
|
||||
|
||||
a1 = InterX([bw_loop;ber_a1(dc,:,lw)],[bw_loop;hdfec]);
|
||||
thres_a1(dc,lw) = -a1(1);
|
||||
end
|
||||
end
|
||||
|
||||
figure(1)
|
||||
subplot(2,1,1)
|
||||
contour(lw_loop,sir_loop,thres_a0,16:0.5:21,'LineWidth',3,'FaceAlpha',0.3,'ShowText','on',"LabelFormat","%0.1f dB");
|
||||
clim([16 21]);
|
||||
ylabel("DC Tap");
|
||||
xlabel("Linewidth in MHz");
|
||||
set(gca,'yscale','log');
|
||||
grid minor
|
||||
subplot(2,1,2)
|
||||
contour(lw_loop,sir_loop,thres_a1,16:0.5:21,'LineWidth',3,'FaceAlpha',0.3,'ShowText','on',"LabelFormat","%0.1f dB");
|
||||
clim([16 21]);
|
||||
ylabel("DC Tap");
|
||||
xlabel("Linewidth in MHz");
|
||||
set(gca,'yscale','log');
|
||||
grid minor
|
||||
|
||||
%% Plot Curves of required SIR to see the minimum a bit better
|
||||
col = flip(cbrewer2('seq','Spectral',16));
|
||||
col = col([1:4, 10:end],:);
|
||||
figure(2)
|
||||
hold on
|
||||
for lw = [size(ber,3):-2:2 2 1]
|
||||
plot(sir_loop,thres_a0(:,lw),'DisplayName',[' Linewidth: ',num2str(lw_loop(lw)*1e-6), ' MHz'],'Color',col(lw,:),'Marker','o','MarkerFaceColor',col(lw,:),'LineWidth',2);
|
||||
set(gca,'xscale','log');
|
||||
end
|
||||
xlabel("DC Tap Value");
|
||||
ylabel("Required SIR to rech FEC in dB");
|
||||
|
||||
%%
|
||||
col = linspecer(7);
|
||||
figure(3)
|
||||
cnt=1;
|
||||
for lw = [1,2,11]
|
||||
|
||||
for i = 1:length(sir_loop)-1
|
||||
|
||||
subplot(1,3,cnt)
|
||||
hold on
|
||||
plot(-1.*bw_loop,ber(i,:,lw),"LineWidth",2,"Marker","o","MarkerSize",5,'Color',col(i,:),'DisplayName',['DC tap ',num2str(sir_loop(i))]);
|
||||
plot(-1.*bw_loop,ber_a1(i,:,lw),"LineWidth",2,"Marker","x","MarkerSize",5,'LineStyle','--','Color',col(i,:),'DisplayName',['A1. DC tap ',num2str(sir_loop(i))]);
|
||||
yline(3.8e-3,'LineWidth',2,'LineStyle','--','HandleVisibility','off');
|
||||
set(gca,'yscale','log');
|
||||
grid minor
|
||||
|
||||
xlim([15,30]);
|
||||
ylim([1e-4,1e-2]);
|
||||
xlabel("SIR in dB");
|
||||
ylabel("BER");
|
||||
title(['BER for different SIR;',' Linewidth: ',num2str(lw_loop(lw)*1e-6), ' MHz'])
|
||||
text(25,4.2e-3,"FEC $3.8 e^{-3}$");
|
||||
end
|
||||
cnt = cnt+1;
|
||||
end
|
||||
legend
|
||||
|
||||
24
projects/IMDD_base_system/rx_simulation.m
Normal file
24
projects/IMDD_base_system/rx_simulation.m
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
|
||||
%%%%%% ROP %%%%%%
|
||||
Rx_sig = Amplifier("amp_mode","ideal_no_noise","gain_mode","output_power","amplification_db",rop).process(Opt_sig);
|
||||
|
||||
|
||||
%%%%%% PD Square Law %%%%%%
|
||||
Rx_sig = Photodiode("fsimu",fdac*kover,"dark_current",2e-08,"responsivity",1,"temperature",20,"nep",1.8e-11).process(Rx_sig);
|
||||
|
||||
|
||||
%%%%%% Low-pass RX (PD, El. Connectors and Scope %%%%%%
|
||||
Rx_sig = Filter('filtdegree',4,"f_cutoff",rx_bw_nyquist.*f_nyquist,"fs",fdac*kover,"filterType",filtertypes.butterworth,"active",true).process(Rx_sig);
|
||||
|
||||
% %%%%%% Low-pass Scope %%%%%%
|
||||
Lp_scpe = Filter('filtdegree',4,"f_cutoff",110e9,"fs",fadc,"filterType",filtertypes.butterworth,"active",true);
|
||||
|
||||
% Rx_sig.spectrum("displayname",'Analog Rx Spectrum','fignum',100,'normalizeTo0dB',1);
|
||||
|
||||
%%%%%% Scope %%%%%%
|
||||
Scpe_sig = Scope("fsimu",fdac*kover,"fadc",fadc,...
|
||||
"delay",0,"fixed_delay",0,"filtertype",filtertypes.butterworth,...
|
||||
"samplingdelay",0,"rand_samplingdelay",0,"freq_offset",0,"samp_jitter",0,...
|
||||
"adcresolution",8,"quantbuffer",0.1,'block_dc',1,'lpf_active',1,'H_lpf',Lp_scpe).process(Rx_sig);
|
||||
|
||||
@@ -1,399 +0,0 @@
|
||||
|
||||
|
||||
lw = [0.1e6 1e6 10e6];
|
||||
|
||||
for lp = 1
|
||||
|
||||
rng(9);
|
||||
|
||||
%% A) Set Simulation Variables
|
||||
|
||||
sir = -18;
|
||||
delay = 50; %mpi delay in meter
|
||||
|
||||
fiblen = 0; %main link in km
|
||||
|
||||
laser_linewidth =5e6;
|
||||
|
||||
O = 19; %order of prbs
|
||||
N = 2^(O-1); %length of prbs
|
||||
[~,seed] = prbs(O,1); %initialize first seed of prbs
|
||||
|
||||
% Modulation
|
||||
M = 4; %PAM-M
|
||||
bitpattern = zeros(N,log2(M));
|
||||
|
||||
% Symbol Rate
|
||||
fsym = 112e9;
|
||||
|
||||
% DAC Rate
|
||||
fdac = 120e9;
|
||||
|
||||
% Simulation oversampling rate "k";
|
||||
kover = 16;
|
||||
|
||||
% ADC Rate
|
||||
fadc = 256e9;
|
||||
|
||||
% Simulation frequency in "analog domain"
|
||||
fsimu = kover * fdac ;
|
||||
|
||||
|
||||
|
||||
%% B) CONSTRUCT ALL CLASSES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
digimod = PAMmapper(M,0);
|
||||
|
||||
pulseform = Pulseformer("pulseform","rrc","fdac",fdac,"fsym",fsym,"pulselength",32,"rrcalpha",0.027);
|
||||
|
||||
awg = AWG('fdac',fdac,'kover',kover,'lpf_active',1,'f_cutoff',56e9,'lpf_type',filtertypes.gaussian,'bit_resolution',5.5);
|
||||
|
||||
lp_laser = Filter('filtdegree',1,"f_cutoff",50e9,"fsamp",fdac*kover,"filterType",filtertypes.bessel_inp);
|
||||
|
||||
u_pi = 3.5;
|
||||
vbias = (0.5*u_pi)-u_pi;
|
||||
extmodlaser = EML("mode",eml_mode.im_cosinus,"power",5,"fsimu",fsimu,"lambda",1310,"bias",vbias,"u_pi",u_pi,"linewidth",laser_linewidth);
|
||||
|
||||
fib = Fiber("fsimu",fdac*kover,"fiber_length",fiblen,"alpha",0.2,"D",16,"lambda0",thz2nm(193.1),"gamma",0);
|
||||
|
||||
reflectionpoint = Amplifier("amp_mode","ideal_no_noise","gain_mode","gain","amplification_db",sir);
|
||||
reflectionprop = Fiber("fsimu",fdac*kover,"fiber_length",delay/1000,"alpha",0.2,"D",16,"lambda0",1550,"gamma",0);
|
||||
|
||||
opticatten = Amplifier("amp_mode","ideal_no_noise","gain_mode","output_power","amplification_db",-8);
|
||||
|
||||
phdiode = Photodiode("fsimu",fdac*kover,"dark_current",2e-08,"responsivity",1,"temperature",20);
|
||||
|
||||
lp_diode = Filter('filtdegree',1,"f_cutoff",50e9,"fsamp",fdac*kover,"filterType",filtertypes.bessel_inp);
|
||||
|
||||
scp = Scope("fsimu",fdac*kover,"fadc",fadc,...
|
||||
"delay",0,"fixed_delay",0,"lpf_bw",113e9,"filtertype",filtertypes.butterworth,...
|
||||
"samplingdelay",0,"rand_samplingdelay",0,"freq_offset",0,"samp_jitter",0,...
|
||||
"adcresolution",6,"quantbuffer",0.1,'block_dc',1);
|
||||
|
||||
eq = EQ("K",2,"plottrain",0,"plotfinal",0,...
|
||||
"training_length",4096,"training_loops",2,...
|
||||
"Ne",[50,5,3],"Nb",[3,0,0],...
|
||||
"DCmu",0.05,"DDmu",[0.0004 0.0005 0.0006 0.0007 ],"DFEmu",0.005,"FFEmu",0.00,...
|
||||
"dd_loops",2,"epsilon",[10 100 1000 ],"M",2,...
|
||||
"thres",[0.005 0.004 0.0005 ],"l1act",0,"delay",0,"rho",0.0005,"ideal_dfe",0,"DB_aim",0);
|
||||
|
||||
eq = EQ_silas("Ne",[50,5,3],"Nb",[2,0,0],"trainlength",4096,...
|
||||
"sps",2,...
|
||||
"mu_dc_dd",0.05,...
|
||||
"mu_dc_train",0.05,...
|
||||
"mu_ffe_train",0,...
|
||||
"mu_dfe_train",0.005,...
|
||||
"mu_ffe_dd",[0.0004 0.0004 0.0004],...
|
||||
"mu_dfe_dd",0.005,...
|
||||
"ddloops",3,...
|
||||
"trainloops",4,...
|
||||
"dcmode",1);
|
||||
|
||||
|
||||
%% C) PROCESS TX %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% 1) PRBS Generation
|
||||
for i = 1:log2(M)
|
||||
[bitpattern(:,i),seed] = prbs(O,N,seed);
|
||||
end
|
||||
|
||||
% 2 ) Build Inf. signal class
|
||||
bits = Informationsignal(bitpattern);
|
||||
|
||||
% 3) Digi modulation -> PAM-M signal
|
||||
digimod_out = digimod.map(bits);
|
||||
|
||||
% 4) Pulse shaping -> racos
|
||||
X = pulseform.process(digimod_out);
|
||||
|
||||
% 5) AWG (lowpass, quantization, sample and hold)
|
||||
X = awg.process(X);
|
||||
|
||||
% 6) Lowpass behavior of laser and hf-cable? why twice?
|
||||
X = lp_laser.process(X);
|
||||
% X = lp_laser.process(X);
|
||||
|
||||
% 7) Normalize signal
|
||||
X = X.normalize("mode","oneone");
|
||||
X.signal = X.signal .* 1.3800;
|
||||
|
||||
|
||||
%% D) PROCESS OPTICAL CHANNEL %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% 1) Laser; Modulation -> OPTICAL DOMAIN
|
||||
[X,extmodlaser] = extmodlaser.process(X);
|
||||
|
||||
% 2) Main fiber propagation
|
||||
X = fib.process(X);
|
||||
|
||||
if delay ~= 0
|
||||
% 3) Reflection
|
||||
% Reflection is just an attenuation
|
||||
R = reflectionpoint.process(X);
|
||||
|
||||
% Propagate back and forth (actual fiber propagation)
|
||||
R = reflectionprop.process(R);
|
||||
|
||||
% Delay the reflected signal
|
||||
[R,n] = R.delay("delay_meter",delay);
|
||||
|
||||
% Add together
|
||||
col = cbrewer2('qual','Paired',8);
|
||||
|
||||
xax = (1:X.length);% / fsimu * (physconst("LightSpeed")/1.4677);
|
||||
xax_sec = (1:X.length) / fsimu .* 1e6;%* (physconst("LightSpeed")/1.4677);
|
||||
xax_sec = xax_sec(n:end).';
|
||||
thresh = pi/4;
|
||||
phaseX = phase(X.signal(n:end));
|
||||
phaseR = phase(R.signal(n:end));
|
||||
phasediff = wrapToPi(phaseX-phaseR);
|
||||
[pos_high] = find(abs(phasediff)>thresh);
|
||||
[pos_low] = find(abs(phasediff)<=thresh);
|
||||
|
||||
|
||||
figure(6);hold on;histogram(phaseX-phaseR,500,'EdgeAlpha',0)
|
||||
|
||||
figure()
|
||||
subplot(3,1,1)
|
||||
scatter(xax_sec.',wrapToPi(phaseX),4,'.','MarkerEdgeColor',col(2,:),'DisplayName','Desired Signal')
|
||||
hold on
|
||||
scatter(xax_sec,wrapToPi(phaseR),4,'.','MarkerEdgeColor',col(1,:),'DisplayName','Reflected Signal')
|
||||
hold on
|
||||
lg = legend;
|
||||
lg.Location = "southwest";
|
||||
xlim([xax_sec(1) xax_sec(end)]);
|
||||
xlabel('time in $\mu$s')
|
||||
ylim([-pi pi]);
|
||||
yticks([-pi 0 pi])
|
||||
yticklabels({'$-\pi$',0, '$\pi$'})
|
||||
ylabel('$\phi$')
|
||||
|
||||
subplot(3,1,2)
|
||||
scatter(xax_sec(pos_low),phasediff(pos_low),4,'.','MarkerEdgeColor',col(5,:),'DisplayName','Phase Difference')
|
||||
hold on
|
||||
scatter(xax_sec(pos_high),phasediff(pos_high),4,'.','MarkerEdgeColor',col(2,:),'HandleVisibility','off')
|
||||
% yline(thresh,'LineWidth',2,'LineStyle','-','HandleVisibility','off')
|
||||
% yline(-thresh,'LineWidth',2,'LineStyle','-','HandleVisibility','off')
|
||||
lg = legend;
|
||||
lg.Location = "southwest";
|
||||
xlabel('time in $\mu$s')
|
||||
xlim([xax_sec(1) xax_sec(end)]);
|
||||
ylim([-pi pi]);
|
||||
yticks([-pi 0 pi])
|
||||
yticklabels({'$-\pi$',0, '$\pi$'})
|
||||
ylabel('$\Delta \phi$')
|
||||
|
||||
|
||||
X.signal = X.signal(n:end);
|
||||
R.signal = R.signal(n:end);
|
||||
X1 = X;
|
||||
X = X+R;
|
||||
|
||||
subplot(3,1,3)
|
||||
scatter(xax_sec(pos_low),abs(X.signal(pos_low).^2)*1000,4,'.','MarkerEdgeColor',col(5,:),'DisplayName','Constructive Interference');
|
||||
hold on
|
||||
scatter(xax_sec(pos_high),abs(X.signal(pos_high).^2)*1000,4,'.','MarkerEdgeColor',col(2,:),'DisplayName','Destructive Interference');
|
||||
%scatter(xax_sec(pos_high),abs(X1.signal(pos_high).^2)*1000,4,'.','MarkerEdgeColor',col(1,:),'MarkerFaceAlpha',0.3,'DisplayName','Destructive Interference');
|
||||
xlim([xax_sec(1) xax_sec(end)]);
|
||||
xlabel('time in $\mu$s')
|
||||
lg = legend;
|
||||
lg.Location = "southwest";
|
||||
ylabel('Optical power in mW');
|
||||
|
||||
|
||||
|
||||
|
||||
disp(['SIR ',num2str(10*log10(X.power/R.power))]);
|
||||
|
||||
% cut reference signal to correct length (nessecary due to MPI delay)
|
||||
digimod_out.signal = digimod_out.signal(round(n * fsym/fsimu) : end,:);
|
||||
|
||||
bitpattern = bitpattern(round(n * fsym/fsimu):end,:);
|
||||
|
||||
end
|
||||
|
||||
|
||||
% plot(angle(R.signal))
|
||||
|
||||
% 4) Attenuation
|
||||
X = opticatten.process(X);
|
||||
|
||||
|
||||
% 5) Photo Diode -> ELECTRICAL DOMAIN
|
||||
X = phdiode.process(X);
|
||||
X = lp_diode.process(X);
|
||||
|
||||
|
||||
%% E) PROCESS RX %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% 1) Oscilloscope (Sampling to f_adc; Quantization; Bandwidth Limitation)
|
||||
X = scp.process(X);
|
||||
|
||||
% 2) Resample to 2x symbol rate
|
||||
X = X.resample("fs_out",2*fsym,"fs_in",fadc);
|
||||
|
||||
% 3) Normalize
|
||||
Eq_in = X.normalize("mode","rms");
|
||||
|
||||
% 4) Equalize
|
||||
|
||||
% MPI reduction DC removal BEFORE EQ
|
||||
wl = 3000; % symbols
|
||||
Eq_in.signal = Eq_in.signal - 1/wl .* movsum( Eq_in.signal,[wl/2,wl/2]);
|
||||
|
||||
% Equalize Signal
|
||||
[Eq_out] = eq.process(Eq_in,digimod_out);
|
||||
|
||||
|
||||
|
||||
%% A1: MPI reduction DC removal
|
||||
wl = 1000; % symbols
|
||||
yk_dcsm = Eq_out;
|
||||
yk_dcsm.signal = Eq_out.signal - 1/wl .* movsum( Eq_out.signal,[wl/2,wl/2]);
|
||||
|
||||
%% A2: MPI reduction Level wise error removal
|
||||
yk_lvsm = Eq_out;
|
||||
yk_lvlp = Eq_out;
|
||||
pre_decision_level_uni = digimod.decide_pamlevel(Eq_out);
|
||||
pre_decision_level_bi = ( pre_decision_level_uni*2-3 ) .* 1/sqrt(5);
|
||||
|
||||
e = Eq_out.signal - pre_decision_level_bi;
|
||||
|
||||
lp_mpi = Filter('filtdegree',1,"f_cutoff",2e6,"fsamp",fsym,"filterType",filtertypes.bessel_inp);
|
||||
|
||||
filtered = lp_mpi.process(e);
|
||||
|
||||
wl = 30; % symbols
|
||||
smoothed = ( 1/wl .* movsum(e,[wl/2,wl/2]) );
|
||||
|
||||
% remove interference
|
||||
for level = 0:3
|
||||
yk_lvsm.signal(pre_decision_level_uni==level) = yk_lvsm.signal(pre_decision_level_uni==level) - smoothed(pre_decision_level_uni==level);
|
||||
yk_lvlp.signal(pre_decision_level_uni==level) = yk_lvlp.signal(pre_decision_level_uni==level) - filtered(pre_decision_level_uni==level);
|
||||
end
|
||||
|
||||
% Calc EVM
|
||||
|
||||
evm_bm = calc_evm(Eq_out.signal, pre_decision_level_bi);
|
||||
evm_dcsm = calc_evm(yk_dcsm.signal, pre_decision_level_bi);
|
||||
evm_lsm = calc_evm(yk_lvsm.signal, pre_decision_level_bi);
|
||||
evm_llp = calc_evm(yk_lvlp.signal, pre_decision_level_bi);
|
||||
|
||||
% figure(1);bar([evm_bm' evm_dcsm' evm_llp' evm_lsm']);ylim([0.01 0.1]);set(gca,'yscale','log');
|
||||
|
||||
%% PROCESS RX %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% 1) Digi Demod
|
||||
d_bm = digimod.demap(Eq_out);
|
||||
d_dcsm = digimod.demap(yk_dcsm);
|
||||
d_lvsm = digimod.demap(yk_lvsm);
|
||||
d_lvlp = digimod.demap(yk_lvlp);
|
||||
|
||||
% 2) BER
|
||||
dbit = length(d_bm.signal)-length(bitpattern);
|
||||
|
||||
[~,errors_bm,ber_bm,loc] = calc_ber(d_bm.signal(1:end-dbit,:) ,bitpattern(1:end,:),"skip",0,"returnErrorLocation",1);
|
||||
[~,errors_dcsm,ber_dcsm] = calc_ber(d_dcsm.signal(1:end-dbit,:) ,bitpattern(1:end,:),"skip",0,"returnErrorLocation",0);
|
||||
[~,errors_lvsm,ber_lvsm] = calc_ber(d_lvsm.signal(1:end-dbit,:) ,bitpattern(1:end,:),"skip",0,"returnErrorLocation",0);
|
||||
[~,errors_lvlp,ber_lvlp] = calc_ber(d_lvlp.signal(1:end-dbit,:) ,bitpattern(1:end,:),"skip",0,"returnErrorLocation",0);
|
||||
|
||||
% Display BER
|
||||
disp(['BER benchmark: ', sprintf('%2E',ber_bm), ' ERRORS: ' ,num2str(sum(errors_bm))]);
|
||||
disp(['BER dc smooth (A1): ', sprintf('%2E',ber_dcsm), ' ERRORS: ' ,num2str(sum(errors_dcsm))]);
|
||||
disp(['BER lv smooth (A2): ', sprintf('%2E',ber_lvsm), ' ERRORS: ' ,num2str(sum(errors_lvsm))]);
|
||||
disp(['BER lv lowpas: ', sprintf('%2E',ber_lvlp), ' ERRORS: ' ,num2str(sum(errors_lvlp))]);
|
||||
|
||||
|
||||
%% Generate some Plots
|
||||
|
||||
if 1
|
||||
|
||||
% SCATTER
|
||||
col = cbrewer2('Paired',8);
|
||||
|
||||
xax = 1:Eq_out.length;
|
||||
|
||||
figure(3)
|
||||
sgtitle('')
|
||||
|
||||
subplot(1,3,1)
|
||||
hold on
|
||||
eq_decision = digimod.decide_pamlevel(Eq_out);
|
||||
true_symbols = digimod.decide_pamlevel(digimod_out);
|
||||
|
||||
xindices = 1:Eq_in.length;
|
||||
errorpos = find(loc~=0)*2;
|
||||
errorpos(errorpos>length(Eq_in.signal)) = length(Eq_in.signal);
|
||||
correct = find(loc==0)*2;
|
||||
correct(correct>length(Eq_in.signal)) = length(Eq_in.signal);
|
||||
scatter(xindices(correct),Eq_in.signal(correct),4,'.','MarkerEdgeColor',col(4,:),'DisplayName','After EQ');
|
||||
hold on
|
||||
scatter(xindices(errorpos),Eq_in.signal(errorpos),6,'x','MarkerEdgeColor',col(6,:),'DisplayName','Wrong Decision');
|
||||
hold off
|
||||
|
||||
xlim([1, xindices(end)]);
|
||||
ylim([-3 3]);
|
||||
xlabel('Sampling Index')
|
||||
ylabel('Amplitude')
|
||||
a = legend;
|
||||
a.Location = "best";
|
||||
|
||||
subplot(1,3,2)
|
||||
xindices = 1:Eq_out.length;
|
||||
xax_sec = (1:Eq_out.length) / fsym .* 1e6;
|
||||
scatter(xax_sec(loc==0),Eq_out.signal(loc==0),4,'.','MarkerEdgeColor',col(4,:),'DisplayName','After EQ');
|
||||
hold on
|
||||
scatter(xindices(loc~=0),Eq_out.signal(loc~=0),8,'x','MarkerEdgeColor',col(6,:),'DisplayName','Wrong Decision');
|
||||
hold off
|
||||
xlim([1, xax(end)]);
|
||||
ylim([-2 2]);
|
||||
xlabel('Sampling Index')
|
||||
ylabel('Amplitude')
|
||||
legend
|
||||
a = legend;
|
||||
a.Location = "best";
|
||||
hold off
|
||||
|
||||
subplot(1,3,3)
|
||||
xindices = 1:yk_lvsm.length;
|
||||
scatter(xindices(loc==0),yk_lvsm.signal(loc==0),4,'.','MarkerEdgeColor',col(4,:),'DisplayName','After A2');
|
||||
hold on
|
||||
scatter(xindices(loc~=0),yk_lvsm.signal(loc~=0),8,'x','MarkerEdgeColor',col(6,:),'DisplayName','Wrong Decision');
|
||||
hold off
|
||||
xlim([1, xax(end)]);
|
||||
ylim([-2 2]);
|
||||
xlabel('Sampling Index')
|
||||
ylabel('Amplitude')
|
||||
legend
|
||||
a = legend;
|
||||
a.Location = "best";
|
||||
hold off
|
||||
|
||||
|
||||
end
|
||||
|
||||
if 0
|
||||
col = cbrewer2('Paired',8);
|
||||
|
||||
figure(11)
|
||||
clf
|
||||
|
||||
subplot(2,1,1)
|
||||
hold on
|
||||
plot(digimod_out.signal(4150:4175),'DisplayName','Tx','Color',col(1,:),'LineWidth',3);
|
||||
plot(Eq_out.signal(4150:4175),'DisplayName','Rx after EQ','Color',col(6,:),'LineWidth',1);
|
||||
title('Modulated Sequence Zoom');
|
||||
legend
|
||||
hold off
|
||||
subplot(2,1,2)
|
||||
hold on
|
||||
stem(d_bm.signal(4150:4175,1),'DisplayName','Tx','Color',col(1,:),'LineStyle','-','LineWidth',5)
|
||||
stem(bitpattern(4150:4175,1)','DisplayName','Rx','Color',col(6,:),'LineStyle','--','LineWidth',2)
|
||||
title('Bitpattern Tx - Rx');
|
||||
legend
|
||||
hold off
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
83
projects/IMDD_base_system/submit_simulations.m
Normal file
83
projects/IMDD_base_system/submit_simulations.m
Normal file
@@ -0,0 +1,83 @@
|
||||
function wh = submit_simulations(wh,options)
|
||||
|
||||
arguments
|
||||
wh
|
||||
options.parallel = 1;
|
||||
options.simulation_mode = 1;
|
||||
end
|
||||
|
||||
%%% 2) SUBMIT SIMULATION
|
||||
% Initialize job results
|
||||
if options.parallel
|
||||
curpool = gcp('nocreate');
|
||||
if isempty(curpool)
|
||||
parpool;
|
||||
else
|
||||
% stop all forgotten or unfetched jobs from queue
|
||||
if ~isempty(curpool.FevalQueue.QueuedFutures) || ~isempty(curpool.FevalQueue.RunningFutures)
|
||||
oldq = length(curpool.FevalQueue.QueuedFutures) +length(curpool.FevalQueue.RunningFutures);
|
||||
curpool.FevalQueue.cancelAll
|
||||
fprintf('Canceled %d unfetched jobs from old queue.',oldq);
|
||||
end
|
||||
|
||||
end
|
||||
results = parallel.FevalFuture.empty();
|
||||
else
|
||||
results = [];
|
||||
end
|
||||
|
||||
fprintf('Requested %d loops',wh.getLastLinIndice);
|
||||
|
||||
lin_idx = 1;
|
||||
for lin_idx = 1:wh.getLastLinIndice
|
||||
optionalVars = struct();
|
||||
if ~isempty(wh.getDimension)
|
||||
% Build the optionalVars struct
|
||||
[parametervalues,parameternames]=wh.getPhysIndicesByLinIndex(lin_idx);
|
||||
for pidx = 1:numel(parameternames)
|
||||
optionalVars.(parameternames{pidx}) = parametervalues{pidx};
|
||||
end
|
||||
end
|
||||
|
||||
%%% SIMULATION HERE
|
||||
if options.parallel
|
||||
|
||||
numOutputs = 1;
|
||||
results(lin_idx) = parfeval(@imdd_model, numOutputs, options.simulation_mode, optionalVars);
|
||||
|
||||
else
|
||||
|
||||
finalresults{lin_idx} = imdd_model(options.simulation_mode,optionalVars);
|
||||
wh.addValueToStorageByLinIdx(finalresults{lin_idx}, 'ber', lin_idx);
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
if options.parallel
|
||||
|
||||
%%% 4) Setup waitbar
|
||||
h = waitbar(0, 'Processing Simulations...');
|
||||
% Helper function to compute progress
|
||||
updateWaitbar = @(~) waitbar(mean(arrayfun(@(f) strcmp(f.State, 'finished'), results)), h);
|
||||
|
||||
fprintf('Fetching results... \n');
|
||||
|
||||
% Update the waitbar after each simulation
|
||||
updateWaitbarFutures = afterEach(results, updateWaitbar, 0);
|
||||
|
||||
% Close the waitbar after all simulations complete
|
||||
afterAll(updateWaitbarFutures, @(~) delete(h), 0);
|
||||
|
||||
%%% 7) Fetch final results after all computations
|
||||
fetchOutputs(results);
|
||||
|
||||
for ridx = 1:length(results)
|
||||
wh.addValueToStorageByLinIdx(results(ridx).OutputArguments{1}, 'ber', ridx);
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
31
projects/IMDD_base_system/tx_simulation.m
Normal file
31
projects/IMDD_base_system/tx_simulation.m
Normal file
@@ -0,0 +1,31 @@
|
||||
|
||||
|
||||
Pform = Pulseformer("fsym",fsym,"fdac",4*fsym,"pulse","rrc","pulselength",16,"rrcalpha",rcalpha);
|
||||
|
||||
[Digi_sig,Symbols,Tx_bits] = PAMsource(...
|
||||
"fsym",fsym,"M",M,"order",19,"useprbs",1,...
|
||||
"fs_out",fdac,...
|
||||
"applyclipping",0,"clipfactor",1.5,...
|
||||
"applypulseform",apply_pulsef,"pulseformer",Pform,...
|
||||
"randkey",random_key,...
|
||||
"db_precode",db_precode,"db_encode",db_encode,...
|
||||
"mrds_code",0,"mrds_blocklength",512).process();
|
||||
|
||||
% Digi_sig.spectrum("displayname",'Digi Spectrum','fignum',10,'normalizeTo0dB',1);
|
||||
|
||||
%%%%% AWG
|
||||
% El_sig = M8199A("kover",kover).process(Digi_sig);
|
||||
El_sig = AWG("fdac",fdac,"f_cutoff",fsym,"lpf_active",0,"kover",kover,"bit_resolution",12,"upsampling_method","samplehold","precomp_sinc_rolloff",1).process(Digi_sig);
|
||||
% El_sig.spectrum("displayname",'Digi Spectrum','fignum',100,'normalizeTo0dB',0);
|
||||
% El_sig = El_sig.setPower(0,"dBm");
|
||||
|
||||
%%%%% Low-pass el. components %%%%%%
|
||||
El_sig = Filter('filtdegree',4,"f_cutoff",tx_bw_nyquist.*f_nyquist,"fs",fdac*kover,"filterType",filtertypes.butterworth,"active",true).process(El_sig);
|
||||
|
||||
%%%%% Electrical Driver Amplifier %%%%%%
|
||||
El_sig = Amplifier("amp_mode","ideal_no_noise","gain_mode","gain","amplification_db",3).process(El_sig);
|
||||
El_sig = El_sig.normalize("mode","oneone");
|
||||
|
||||
%%%%% MODULATE E/O CONVERSION %%%%%%
|
||||
[Opt_sig] = EML("mode",eml_mode.im_cosinus,"power",3,"fsimu",El_sig.fs,"lambda",laser_wavelength,"bias",vbias,"u_pi",u_pi,"linewidth",laser_linewidth,"randomkey",random_key+1).process(El_sig);
|
||||
|
||||
@@ -1,29 +1,22 @@
|
||||
|
||||
|
||||
|
||||
filename = "C:\Users\sioe\Documents\High_Speed_Measurement_2024\bias_testing\PAM4_b2b_bias_sweep_20241023_130342_wh.mat";
|
||||
|
||||
filename = "/Users/silasoettinghaus/Documents/MATLAB/PAM4_b2b_bias_sweep_20241023_145739_wh.mat";
|
||||
a = load(filename);
|
||||
wh2 = a.obj;
|
||||
|
||||
m = wh2.getStoValue('m',wh2.parameter.vbias.values(1),wh2.parameter.awg_vpp.values(1));
|
||||
precomp_max = 5;
|
||||
m = wh2.getStoValue('m',wh2.parameter.vbias.values(1),wh2.parameter.awg_vpp.values(1),precomp_max);
|
||||
|
||||
v_bias_vals = wh2.parameter.vbias.values;
|
||||
awg_vpp_vals = wh2.parameter.awg_vpp.values;
|
||||
|
||||
ber_ffe= [];
|
||||
ber_mlse= [];
|
||||
rop_measured= [];
|
||||
pd_in_measured= [];
|
||||
|
||||
bers = [];
|
||||
rop_measured = [];
|
||||
cnt = 0;
|
||||
for awg_vpp_cur = awg_vpp_vals
|
||||
cnt = cnt+1;
|
||||
ber_ffe(cnt,:) = wh2.getStoValue('ber_ffe',v_bias_vals,awg_vpp_cur)';
|
||||
ber_mlse(cnt,:) = wh2.getStoValue('ber_mlse',v_bias_vals,awg_vpp_cur);
|
||||
rop_measured(cnt,:) = wh2.getStoValue('rop',v_bias_vals,awg_vpp_cur);
|
||||
pd_in_measured(cnt,:) = wh2.getStoValue('pd_in',v_bias_vals,awg_vpp_cur);
|
||||
bers(cnt,:) = wh2.getStoValue('ber_mlse',v_bias_vals,awg_vpp_cur,precomp_max);
|
||||
rop_measured(cnt,:) = wh2.getStoValue('rop',v_bias_vals,awg_vpp_cur,precomp_max);
|
||||
end
|
||||
|
||||
[bestber,bestindex] = min(bers,[],'all');
|
||||
@@ -34,14 +27,27 @@ bestvbias=v_bias_vals(v_bias_pos);
|
||||
disp(['Best Vpp: ',num2str(bestvbias),' V; Best Vpp AWG: ',num2str(bestawgvpp),' V' ])
|
||||
|
||||
|
||||
figure(100)
|
||||
|
||||
figure()
|
||||
hold on
|
||||
plot(v_bias_vals,ber_ffe,'DisplayName',['FFE only']);
|
||||
plot(v_bias_vals,ber_mlse,'DisplayName',['MLSE']);
|
||||
for i = 1:numel(awg_vpp_vals)
|
||||
va=awg_vpp_vals(i);
|
||||
a=scatter(rop_measured(i,:),bers(i,:),'DisplayName',['FFE AWG:',num2str(va)],'LineWidth',1);
|
||||
|
||||
a.DataTipTemplate.DataTipRows(1).Label = 'P out';
|
||||
|
||||
a.DataTipTemplate.DataTipRows(2).Label = 'BER';
|
||||
|
||||
a.DataTipTemplate.DataTipRows(3).Label = 'Vbias';
|
||||
a.DataTipTemplate.DataTipRows(3).Value = v_bias_vals;
|
||||
a.DataTipTemplate.DataTipRows(3).Format = 'auto';
|
||||
end
|
||||
|
||||
% Continue with the rest of your plot settings
|
||||
yline(3.8e-3, 'DisplayName', 'HD-FEC', 'LineStyle', '--', 'HandleVisibility', 'off');
|
||||
xlabel('V bias');
|
||||
xlabel('ROP');
|
||||
ylabel('Bit Error Rate (BER)');
|
||||
title('Bit Error Rate vs. V bias');
|
||||
title('Bit Error Rate vs. ROP');
|
||||
set(gca, 'yscale', 'log');
|
||||
set(gca, 'Box', 'on');
|
||||
grid on;
|
||||
@@ -49,7 +55,6 @@ grid minor;
|
||||
legend('Interpreter', 'none');
|
||||
|
||||
|
||||
|
||||
figure();
|
||||
sgtitle(['PAM ', num2str(m)])
|
||||
subplot1 = subplot(1,2,1);
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
|
||||
% load data points
|
||||
if 0
|
||||
foldername = '/Users/silasoettinghaus/Nextcloud/Dokumente/02_Ablage_Office/Lab_Data_24/sir_sweep_sd40/';
|
||||
foldername = 'C:\Users\Silas\Nextcloud4\Dokumente\02_Ablage_Office\Lab_Data_24\sir_sweep_sd40';
|
||||
filename = 'PAM4_56_';
|
||||
filename = 'PAM4_56_v2';
|
||||
else
|
||||
foldername = '/Users/silasoettinghaus/Nextcloud/Dokumente/02_Ablage_Office/Lab_Data_24/sir_sweep_sd40/DB_coded';
|
||||
foldername = 'C:\Users\Silas\Nextcloud4\Dokumente\02_Ablage_Office\Lab_Data_24\sir_sweep_sd40\DB_coded';
|
||||
filename = 'PAM4_68_v2';
|
||||
end
|
||||
|
||||
stuff = load([foldername,filesep,filename,'wh']);
|
||||
%stuff = load([foldername,filesep,'PAM4_v2_10km_wh']);
|
||||
wh = stuff.obj;
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
|
||||
precomp_path = "C:\Users\Silas\Documents\MATLAB\imdd_simulation\projects\standard_system";
|
||||
precomp_filename = "lab_mpi_setup_2";
|
||||
|
||||
freqresp = ChannelFreqResp("Nacq",1024,"Navg",64,"Ncp",63,'f_ref',92e9);
|
||||
freqresp.load('loadPath',precomp_path,'fileName',precomp_filename);
|
||||
freqresp.plot();
|
||||
Binary file not shown.
Reference in New Issue
Block a user