
% datarate = 128e9;
M = 4;
laser_linewidth = 0;
kover = 32;
fsym = 92e9;%round(datarate*1e-9 / log2(M))*1e9;
fdac = 256e9;

% 1) PRBS Generation
O = 18; %order of prbs
N = 2^(O-1); %length of prbs
[~,seed] = prbs(O,1); %initialize first seed of prbs
bitpattern=[];

for i = 1:log2(M)
    [bitpattern(:,i),seed] = prbs(O,N,seed);
end
if M == 6
    bitpattern = reshape(bitpattern,[],1);
    bitpattern = bitpattern(1:end-mod(length(bitpattern),5));
end
bits = Informationsignal(bitpattern);

% 2) Digi modulation -> PAM-M signal
digimod_out = PAMmapper(M,0).map(bits);
digimod_out.fs = fsym;

% 3) Pulseform Raised Cosine
X = Pulseformer("fsym",fsym,"fdac",fdac,"pulse","rrc","pulselength",16,"rrcalpha",0.2).process(digimod_out);

% Implememt Precompensation

% Implement Precoding

% 4) AWG (lowpass, quantization, sample and hold)
LP_awg = Filter('filtdegree',5,"f_cutoff",64e9,"fs",fdac*kover,"filterType",filtertypes.butterworth);
AWG_=AWG("fdac",fdac,"dac_min",-1,"dac_max",1,"H_lpf",LP_awg,"kover",kover,"bit_resolution",16,"lpf_active",1,"normalize2dac",1,"upsampling_method","samplehold");
X = AWG_.process(X);
plot_eye(X.signal,X.fs,fsym);
disp(['El. power: ',num2str(X.power),' dBm (into 50 Ohm)']);
disp(['El. RMS voltage: ',num2str(sqrt(mean(X.signal.^2))),' V']);
disp(['max voltage: ',num2str(max(X.signal)),' V']);

% 5) Lowpass behavior before laser
LP_modulator= Filter('filtdegree',4,"f_cutoff",70e9,"fs",fdac*kover,"filterType",filtertypes.butterworth);
X =  LP_modulator.process(X);

% 6) Laser; Modulation ->  OPTICAL DOMAIN
u_pi = 4;
vbias = -1.8;
extmodlaser = EML("mode",eml_mode.im_cosinus,"power",0,"fsimu",X.fs,"lambda",1290,"bias",vbias,"u_pi",u_pi,"linewidth",laser_linewidth,"randomkey",5);
[Opt,extmodlaser] = extmodlaser.process(X);

if 1
    f = figure(22);
    tiledlayout(2,2);
    nexttile
    hold on
    scatter(X.signal(1:100000),(abs(Opt.signal(1:100000)).^2)*1e3,0.1,'.','DisplayName','Modulator TF')
    xlabel('Input in V')
    ylabel('Output in mW')

    nexttile
    hold on
    plot(X.signal,'LineWidth',0.1);
    yline([max_, min_],'LineWidth',2,'LineStyle','--');
    yline([rms_, -rms_],'LineWidth',2,'LineStyle',':');
    ylim([-3 3]);
    title(['AWG output: ',num2str(X.power), 'dBm']);


    nexttile
    spectrum_plot(Opt.signal,Opt.fs);
    
    
    rms_ = rms(X.signal);
    max_ = max(X.signal);
    min_ = min(X.signal);
    

end










