% Transform AxTandem into Array (necessary for splitapply)
Z.Time = datenum(Z.Time);
for i = 1:length(ClassType)
    % Filter based on Class - AxTandem is compromised after this (deleting entries)
    if strcmp(Class,'ClassOW')
        AxTandem(AxTandem.CLASS == 0,:) = [];
    elseif strcmp(Class,'Class')
        AxTandem(AxTandem.CLASS == 0,:) = [];
        AxTandem(AxTandem.CLASS > 39 & AxTandem.CLASS < 50,:) = [];
        Z(Z(:,5) > 39 & Z(:,5) < 50,:) = [];
        Max.(Class).(BlockM) = [];
        if strcmp(BlockM,'Daily')
            % Make groups out of unique locations and days
            [Gr, GrIDDay, GrIDZST] = findgroups(dateshift(AxTandem.Time,'start','day'),AxTandem.ZST);
        elseif strcmp(BlockM,'Weekly')
            [Gr, GrIDWeek, GrIDZST] = findgroups(dateshift(AxTandem.Time,'start','week'),AxTandem.ZST);
            [Gr, GrIDYear, GrIDZST] = findgroups(year(AxTandem.Time),AxTandem.ZST);
        % Perform splitapply (see function at end... not just Max as we want whole rows involving maxes)
        Max.(Class).(BlockM) = splitapply(@(Z)maxIndex(Z),Z,Gr);
        % Transform back into table form
        Max.(Class).(BlockM) = array2table(Max.(Class).(BlockM));
        Max.(Class).(BlockM).Properties.VariableNames = {'Max','AWT1kN','AWT2kN','W1_2M','ZST','CLASS','Time'};
        Max.(Class).(BlockM).Time = datetime(Max.(Class).(BlockM).Time,'ConvertFrom',"datenum");
DistTypes = {'Normal', 'Lognormal', 'GeneralizedExtremeValue'};
% Set CDF Scaling Factors for estimates
D2WFactor = 5; W2YFactor = 50; D2YFactor = D2WFactor*W2YFactor;
% Set x values to be use globally
% Fit Block Maxima to Normal Curve
for i = 1:length(ClassType)
        for k = 1:length(DistTypes)
            pd.(Class).(BlockM).(Dist) = fitdist(Max.(Class).(BlockM).Max/2,Dist);
            y_values.(Class).(BlockM).(Dist).PDF_Fit = pdf(pd.(Class).(BlockM).(Dist),x_values);
            y_values.(Class).(BlockM).(Dist).CDF_Fit = cdf(pd.(Class).(BlockM).(Dist),x_values);
            if strcmp(BlockM,'Daily')
                y_values.(Class).('Weekly').(Dist).CDF_D2W = y_values.(Class).(BlockM).(Dist).CDF_Fit.^D2WFactor;
                y_values.(Class).('Weekly').(Dist).PDF_D2W = [0 diff(y_values.(Class).('Weekly').(Dist).CDF_D2W)];
                y_values.(Class).('Yearly').(Dist).CDF_D2Y = y_values.(Class).(BlockM).(Dist).CDF_Fit.^D2YFactor;
                y_values.(Class).('Yearly').(Dist).PDF_D2Y = [0 diff(y_values.(Class).('Yearly').(Dist).CDF_D2Y)];
                    mu = trapz(y_values.(Class).('Weekly').(Dist).CDF_D2W,x_values);
                    sigma = sqrt(trapz(y_values.(Class).('Weekly').(Dist).CDF_D2W,(x_values-mu).^2));
                    pd.(Class).D2W.(Dist) = makedist(Dist,"mu",mu,"sigma",sigma);
                    mu = trapz(y_values.(Class).('Yearly').(Dist).CDF_D2Y,x_values);
                    sigma = sqrt(trapz(y_values.(Class).('Yearly').(Dist).CDF_D2Y,(x_values-mu).^2));
                    pd.(Class).D2Y.(Dist) = makedist(Dist,"mu",mu,"sigma",sigma);
                elseif strcmp(Dist,'Lognormal')
                    mu = trapz(y_values.(Class).('Weekly').(Dist).CDF_D2W,x_values);
                    sigma = sqrt(trapz(y_values.(Class).('Weekly').(Dist).CDF_D2W,(x_values-mu).^2));
                    zeta = sqrt(log(1+(sigma/mu)^2));
                    lambda = log(mu)-0.5*zeta^2;
                    pd.(Class).D2W.(Dist) = makedist(Dist,"mu",lambda,"sigma",zeta);
                    mu = trapz(y_values.(Class).('Yearly').(Dist).CDF_D2Y,x_values);
                    sigma = sqrt(trapz(y_values.(Class).('Yearly').(Dist).CDF_D2Y,(x_values-mu).^2));
                    zeta = sqrt(log(1+(sigma/mu)^2));
                    lambda = log(mu)-0.5*zeta^2;
                    pd.(Class).D2Y.(Dist) = makedist(Dist,"mu",lambda,"sigma",zeta);
            elseif strcmp(BlockM,'Weekly')
                y_values.(Class).('Yearly').(Dist).CDF_W2Y = y_values.(Class).(BlockM).(Dist).CDF_Fit.^W2YFactor;
                y_values.(Class).('Yearly').(Dist).PDF_W2Y = [0 diff(y_values.(Class).('Yearly').(Dist).CDF_W2Y)];
                    mu = trapz(y_values.(Class).('Yearly').(Dist).CDF_W2Y,x_values);
                    sigma = sqrt(trapz(y_values.(Class).('Yearly').(Dist).CDF_W2Y,(x_values-mu).^2));
                    pd.(Class).W2Y.(Dist) = makedist(Dist,"mu",mu,"sigma",sigma);
                elseif strcmp(Dist,'Lognormal')
                    mu = trapz(y_values.(Class).('Yearly').(Dist).CDF_W2Y,x_values);
                    sigma = sqrt(trapz(y_values.(Class).('Yearly').(Dist).CDF_W2Y,(x_values-mu).^2));
                    zeta = sqrt(log(1+(sigma/mu)^2));
                    lambda = log(mu)-0.5*zeta^2;
                    pd.(Class).W2Y.(Dist) = makedist(Dist,"mu",lambda,"sigma",zeta);
figure('Position',[0 0 1500 400]);
x = X(1:end-1) + diff(X);
for i = 1:length(ClassType)
        y = histcounts(Max.(Class).(BlockM).Max/2,'BinEdges',X,'normalization','pdf');
        bar(x,y/ScaleDown(j),1,'EdgeColor',C(j,:),'FaceColor',[.8 .8 .8],'FaceAlpha',0.5,'DisplayName',BlockM)
            plot(x_values,y_values.(Class).(BlockM).(Dist).PDF_Fit/ScaleDown(j),'k-','DisplayName',[Dist 'Fit'])
            if strcmp(BlockM,'Yearly')
                plot(x_values,y_values.(Class).(BlockM).(Dist).PDF_D2Y/ScaleDown(j),'k--','DisplayName',[Dist 'D2Y'])
                plot(x_values,y_values.(Class).(BlockM).(Dist).PDF_W2Y/ScaleDown(j),'k:','DisplayName',[Dist 'W2Y'])
    set(gca,'ytick',[],'yticklabel',[],'ycolor','k')
    xlim([LimitL+25 LimitR-25])
    ylabel('Normalized Histograms')
    xlabel('Total Tandem Load (kN) /2')
    title(['Maximum Tandem Axles ' Class])
    legend('location','northeast')
figure('Position',[0 0 1500 400]);
Xp = LimitL-Step/2:Step:LimitR-Step/2;
    histogram(Max.All.(BlockM).Max/2,'BinEdges',Xp,'normalization','pdf','EdgeColor',C(4,:),'FaceColor',[.8 .8 .8],'FaceAlpha',0.2,'DisplayName','All')
    histogram(Max.ClassOW.(BlockM).Max/2,'BinEdges',Xp,'normalization','pdf','EdgeColor',C(7,:),'FaceColor',[.8 .8 .8],'FaceAlpha',0.2,'DisplayName','ClassOW')
    histogram(Max.Class.(BlockM).Max/2,'BinEdges',Xp,'normalization','pdf','EdgeColor',C(9,:),'FaceColor',[.8 .8 .8],'FaceAlpha',0.2,'DisplayName','Class')
    set(gca,'ytick',[],'yticklabel',[])
    ylabel('Normalized Histograms')
    xlabel('Total Tandem Load (kN) /2')
    title(['Maximum Tandem Axles ' BlockM])
    legend('location','best')
    xlim([LimitL+25 LimitR-25])
figure('Position',[0 0 1500 400]);
Xp = LimitL-Step/2:Step:LimitR-Step/2;
x = X(1:end-1) + diff(X);
for i = 1:length(ClassType)
        y = histcounts(Max.(Class).(BlockM).W1_2M,'BinEdges',X,'normalization','pdf');
        bar(x,y/ScaleDown(j),1,'EdgeColor',C(j,:),'FaceColor',[.8 .8 .8],'FaceAlpha',0.5,'DisplayName',BlockM)
    set(gca,'ytick',[],'yticklabel',[],'ycolor','k')
    xlim([LimitL+.25 LimitR-.25])
    ylabel('Normalized Histograms')
    xlabel('Total Tandem Load (kN) /2')
    title(['Maximum Tandem Axles - Spacing ' Class])
    legend('location','best')
% According to Annex C of SIA 269
Beta.Yearly = 4.7; % Here we use the Beta annual - so we should use annual max effects
Beta.Weekly = 5.44422; % See Tail Fitting > Beta Conversion
% Right now we assume a normal distribution in the Edact calculation. Also
SumTableNorm = array2table(zeros(6,length(BM)*length(ClassType)));
SumTableLogNormComp = array2table(zeros(5,length(BM)*length(ClassType)));
SumTableNorm.Properties.VariableNames = {[BM{3} ' ' ClassType{3}], [BM{3} ' ' ClassType{2}], [BM{3} ' ' ClassType{1}], [BM{2} ' ' ClassType{3}],...
    [BM{2} ' ' ClassType{2}], [BM{2} ' ' ClassType{1}], [BM{1} ' ' ClassType{3}], [BM{1} ' ' ClassType{2}], [BM{1} ' ' ClassType{1}]};
SumTableLogNorm = SumTableNorm;
SumTableNorm.Properties.RowNames = {'Mu', 'Sigma', 'COV (%)', '95th %', 'Dist 95', 'AlphaQ'};
SumTableLogNorm.Properties.RowNames = {'Lambda', 'Zeta', '95th %', 'Dist 95', 'AlphaQN', 'AlphaQLN'};
SumTableLogNormComp.Properties.RowNames = {'Lambda', 'Zeta', '95th %', 'Dist 95', 'AlphaQLN Est'};
SumTableLogNormComp.Properties.VariableNames = {[BM{3} ' ' ClassType{3}], [BM{3} ' ' ClassType{2}], [BM{3} ' ' ClassType{1}], ['W2Y ' ClassType{3}],...
    ['W2Y ' ClassType{2}], ['W2Y ' ClassType{1}], ['D2Y ' ClassType{3}], ['D2Y ' ClassType{2}], ['D2Y ' ClassType{1}]};
for i = 1:length(ClassType)
        Emact = mean(Max.(Class).(BlockM).Max/2);
        Stdev = std(Max.(Class).(BlockM).Max/2);
        N5 = prctile(Max.(Class).(BlockM).Max/2,95);     
        Dist95N = norminv(0.95,pd.(Class).(BlockM).Normal.mu,pd.(Class).(BlockM).Normal.sigma);
        Dist95LN = logninv(0.95,pd.(Class).(BlockM).Lognormal.mu,pd.(Class).(BlockM).Lognormal.sigma);
        EdactN = Emact*(1+Alpha*Beta.(BlockM)*COV);
        AlphaQN = EdactN/(300*1.5);
        EdactLN = Emact*exp(Alpha*Beta.(BlockM)*sqrt(Delta2)-0.5*Delta2);
        AlphaQLN = EdactLN/(300*1.5);
        SumTableNorm.([BlockM ' ' Class]) = [Emact; Stdev; 100*COV; N5; Dist95N; AlphaQN];
        SumTableLogNorm.([BlockM ' ' Class]) = [pd.(Class).(BlockM).Lognormal.mu; pd.(Class).(BlockM).Lognormal.sigma; N5; Dist95LN; AlphaQN; AlphaQLN];
        if strcmp(BlockM,'Weekly')
            pdx = pd.(Class).W2Y.Lognormal;
            Emact = exp(pdx.mu+0.5*Delta2);
            SumTableLogNormComp.(['W2Y ' Class]) = [pdx.mu; pdx.sigma; prctile(Max.(Class).Yearly.Max/2,95); logninv(0.95,pdx.mu,pdx.sigma); Emact*exp(Alpha*Beta.Yearly*sqrt(Delta2)-0.5*Delta2)/(300*1.5)];
        elseif strcmp(BlockM,'Daily')
            pdx = pd.(Class).D2Y.Lognormal;
            Emact = exp(pdx.mu+0.5*Delta2);
            SumTableLogNormComp.(['D2Y ' Class]) = [pdx.mu; pdx.sigma; prctile(Max.(Class).Yearly.Max/2,95); logninv(0.95,pdx.mu,pdx.sigma); Emact*exp(Alpha*Beta.Yearly*sqrt(Delta2)-0.5*Delta2)/(300*1.5)];
            SumTableLogNormComp.([BlockM ' ' Class]) = [pd.(Class).(BlockM).Lognormal.mu; pd.(Class).(BlockM).Lognormal.sigma; N5; Dist95LN; AlphaQLN];
disp(SumTableNorm)
               Yearly Class    Yearly ClassOW    Yearly All    Weekly Class    Weekly ClassOW    Weekly All    Daily Class    Daily ClassOW    Daily All
               ____________    ______________    __________    ____________    ______________    __________    ___________    _____________    _________
    Mu            169.10           171.05          195.90         136.84           137.44          149.52        115.97          116.20         122.82  
    Sigma          15.07            15.94           21.92          16.41            16.73           21.66         18.50           18.71          23.18  
    COV (%)         8.91             9.32           11.19          11.99            12.17           14.49         15.95           16.10          18.88  
    95th %        195.27           200.74          235.65         164.12           165.36          186.53        148.14          148.84         163.24  
    Dist 95       193.89           197.27          231.96         163.84           164.96          185.14        146.39          146.98         160.95  
    AlphaQ          0.49             0.50            0.60           0.44             0.45            0.52          0.42            0.42           0.48  
disp(SumTableLogNorm)
                Yearly Class    Yearly ClassOW    Yearly All    Weekly Class    Weekly ClassOW    Weekly All    Daily Class    Daily ClassOW    Daily All
                ____________    ______________    __________    ____________    ______________    __________    ___________    _____________    _________
    Lambda           5.13             5.14            5.27           4.91             4.92            5.00          4.74            4.74           4.79  
    Zeta             0.09             0.09            0.11           0.12             0.12            0.14          0.16            0.16           0.19  
    95th %         195.27           200.74          235.65         164.12           165.36          186.53        148.14          148.84         163.24  
    Dist 95        195.24           198.44          234.26         165.53           166.67          187.52        149.53          150.13         164.83  
    AlphaQN          0.49             0.50            0.60           0.44             0.45            0.52          0.42            0.42           0.48  
    AlphaQLN         0.50             0.51            0.62           0.48             0.48            0.57          0.48            0.48           0.57  
disp(SumTableLogNormComp)
                    Yearly Class    Yearly ClassOW    Yearly All    W2Y Class    W2Y ClassOW    W2Y All    D2Y Class    D2Y ClassOW    D2Y All
                    ____________    ______________    __________    _________    ___________    _______    _________    ___________    _______
    Lambda               5.13             5.14            5.27         5.18          5.19         5.32        5.20          5.20         5.33 
    Zeta                 0.09             0.09            0.11         0.06          0.06         0.07        0.07          0.07         0.08 
    95th %             195.27           200.74          235.65       195.27        200.74       235.65      195.27        200.74       235.65 
    Dist 95            195.24           198.44          234.26       195.40        197.20       228.89      201.48        202.78       233.61 
    AlphaQLN Est         0.50             0.51            0.62         0.48          0.48         0.57        0.50          0.50         0.59 
figure('Position',[0 0 1500 400]);
for i = 1:length(ClassType)
        [MaxECDF, MaxECDFRank] = ecdf(Max.(Class).(BlockM).Max/2); MaxECDFRank = MaxECDFRank';  MaxECDF(1) = []; MaxECDFRank(1) = [];
        scatter(norminv((1:length(MaxECDFRank))/(length(MaxECDFRank) + 1)),log(MaxECDFRank),7,C(j,:),'filled','DisplayName','Max Data');
        mdl = fitlm(norminv((1:length(MaxECDFRank))/(length(MaxECDFRank) + 1)),log(MaxECDFRank),'linear');
        plot(norminv((1:length(MaxECDFRank))/(length(MaxECDFRank) + 1)),mdl.Fitted,'-','Color',C(j,:),'DisplayName',['Fitted ' num2str(mdl.Rsquared.Ordinary,3)]);
        %text(1,y1(1)+(y1(2)-y1(1))/j,['\lambda = ' sprintf('%.2f \n',mdl.Coefficients.Estimate(1)) '\zeta = ' sprintf('%.2f \n',mdl.Coefficients.Estimate(2)) sprintf('R^2:  %.1f%%',mdl.Rsquared.Ordinary*100)])
        text(1,y1(1)+(y1(2)-y1(1))*(j/6),sprintf('R^2:  %.1f%%',mdl.Rsquared.Ordinary*100),"Color",C(j,:))
        ylabel('log[ Total Tandem Load (kN) /2 ]')
        xlabel('Standard Normal Percentile')
    title(['Maximum Tandem Axles ' Class])
sgtitle('LogNormal Probability Paper','fontweight','bold','fontsize',12);
% Try with Gumbel Probability Paper
% for i = 1:length(ClassType)
%     figure('Position',[0 0 1500 400]);
%         [MaxECDF, MaxECDFRank] = ecdf(Max.(Class).(BlockM).Max/2); MaxECDFRank = MaxECDFRank';
%         scatter(MaxECDFRank,-log(-log(MaxECDF)),7,'k','filled','DisplayName','Max Data');
%         ylabel('-log(-log(Probability of non-exceedance))')
%         xlabel('Total Tandem Load (kN) /2')
%         legend('location','best')
%         title(['Maximum Tandem Axles ' BlockM])
%     sgtitle(['Gumbel Probability Paper - ' Class ' Axles'],'fontweight','bold','fontsize',12);