function forwardReversibleFigures2(model,directions)
% Figures of different classes of reactions: qualitatively forward -> quantitatively reversible
%
%INPUT
%model.DrGt0

%model.S
%
% directions        subsets of qualtiatively forward  -> quantiatively reversible
%   .forwardReversible
%   .forwardReversible_bydGt0
%   .forwardReversible_bydGt0LHS
%   .forwardReversible_bydGt0Mid
%   .forwardReversible_bydGt0RHS
%   .forwardReversible_byConc_zero_fixed_DrG0
%   .forwardReversible_byConc_negative_fixed_DrG0
%   .forwardReversible_byConc_positive_fixed_DrG0
%   .forwardReversible_byConc_negative_uncertain_DrG0
%   .forwardReversible_byConc_positive_uncertain_DrG0

% thorStandard

[nMet,nRxn]=size(model.S);

% if ~isfield(model,'DrGt0Mean')
%     model.DrGt0Mean=(model.DrGt0Min+model.DrGt0Max)/2;
% end
% if ~isfield(model,'DrGtMean')
%     model.DrGtMean=(model.DrGtMin+model.DrGtMax)/2;
% end

directions=model.directions;

% close all
figureMaster=1;
figure1=1;
figure2=1;
figure345=1;
figure6=1;
figure7=1;

if figureMaster
%     %make the master plot of all 7 regions, 2, 4,6 are shaded
%     X1=1:nRxn;%nnz(directions.forwardReversible);
%     %dGrt0
%     Y0=(model.dGt0Min+model.dGt0Max)/2;
%     L0=Y0-model.dGt0Min;
%     U0=model.dGt0Max-Y0;
%     %dGrt
%     Y=(model.dGtMin+model.dGtMax)/2;
%     L=Y-model.dGtMin;
%     U=model.dGtMax-Y;
%     %find the amount of reactions with normal cumulative distribution over
%     %range of dGt0
%     P = normcdf(0,Y0,L0);

    %Y0=model.DrGt0; %model.DrGt0 = model.DrGt0 + delta_pH + delta_chi;
    Y0=(model.DrGt0Min+model.DrGt0Max)/2;%old vonB11
    L0=Y0-model.DrGt0Min;
    U0=model.DrGt0Max-Y0;

    Y=model.DrGtMean; %model.DrGtMean=(model.DrGtMax+model.DrGtMin)/2;
    L=Y-model.DrGtMin;
    U=model.DrGtMax-Y;

    P=directions.forwardProbability;
    %sort by probability that a reaction is forward (puts any NaN first)
    [tmp,xip]=sort(P,'descend');

    %     only take the indices of the problematic reactions, but be sure to
    %     take them in order of descending P
    xip2=zeros(nnz(directions.forwardReversible),1);
    p=1;
    for n=1:nRxn
         if directions.forwardReversible(xip(n))
            xip2(p)=xip(n);
            p=p+1;
        end
    end
    xip=xip2;
    X1=1:length(xip);

    %replace the NaN due to zero st dev
    %NaNpLHS=nnz(directions.forwardReversible_byConc_negative_uncertain_DrG0);
    %nNaNpRHS=nnz(directions.forwardReversible_byConc_positive_uncertain_DrG0);
    nNaNpLHS=nnz(isnan(directions.forwardReversible_byConc_negative_uncertain_DrG0));
    nNaNpRHS=nnz(isnan(directions.forwardReversible_byConc_positive_uncertain_DrG0));
    if (nNaNpLHS+nNaNpRHS)~=nnz(isnan((P(directions.forwardReversible))))
        warning('A:B','Extra category of NaN P(Delta_{r}G^{primem}<0) not taken into account');
        %nans are first in the ordering of indexes
        NaNPInd=xip(1:nNaNpLHS+nNaNpRHS);
        %sorts indices of the zero std dev met by their mean dG0t
        [tmp,xipNaNPInd]=sort(model.DrGt0Mean(NaNPInd));
        %new ordering
        xip=[NaNPInd(xipNaNPInd(1:nNaNpLHS)); xip(nNaNpLHS+nNaNpRHS+1:end); NaNPInd(xipNaNPInd(nNaNpLHS+1:nNaNpLHS+nNaNpRHS))];
    end

    figure1 = figure('PaperSize',[11 8.5],'PaperOrientation','landscape');
    % Create axes
    axes1 = axes('Parent',figure1,'Color',[0.702 0.7804 1]);
    hold on;
    %upper and lower Y
    minY=min(model.DrGtMin(directions.forwardReversible));
    maxY=max(model.DrGtMax(directions.forwardReversible));
    %baselines
    PreversibleBar_byConcLHS=ones(1,nRxn)*minY;
    PreversibleBar_byConcRHS=ones(1,nRxn)*minY;
    PreversibleBar_bydGt0=ones(1,nRxn)*minY;
    %bar for 2 & 6
    PreversibleBar_byConcLHS(directions.forwardReversible_byConc_negative_uncertain_DrG0)=maxY;
    PreversibleBar_byConcRHS(directions.forwardReversible_byConc_positive_uncertain_DrG0)=maxY;
    %bar for 4
    PreversibleBar_bydGt0(directions.forwardReversible_bydGt0Mid)=maxY;
    bar_handle4=bar(X1,PreversibleBar_bydGt0(xip),1,'BaseValue',minY,'FaceColor',[0.86 0.86 0.86],'EdgeColor','none');
    bar_handle2=bar(X1,PreversibleBar_byConcLHS(xip),1,'BaseValue',minY,'FaceColor',[0.86 0.86 0.86],'EdgeColor','none');
    bar_handle6=bar(X1,PreversibleBar_byConcRHS(xip),1,'BaseValue',minY,'FaceColor',[0.86 0.86 0.86],'EdgeColor','none');

    %dGrt errorbar
    hE=errorbar(X1,Y(xip),L(xip),U(xip),'LineStyle','none','LineWidth',2,'DisplayName','forwardReversible','Color','r');
    if 0
        % adjust error bar width
        %hE_c=get(hE, 'Children'); % deprecated since 2014b
        %errorbarXData= get(hE_c(2), 'XData');
        errorbarXData=get(hE, 'XData');
        errorbarXData(4:9:end) = errorbarXData(1:9:end) - 0;
        errorbarXData(7:9:end) = errorbarXData(1:9:end) - 0;
        errorbarXData(5:9:end) = errorbarXData(1:9:end) + 0;
        errorbarXData(8:9:end) = errorbarXData(1:9:end) + 0;
        %set(hE_c(2), 'XData', errorbarXData);
        set(hE, 'XData', errorbarXData);
    end
    %dGrt0 errorbar on top and inside dGrt
    hE2=errorbar(X1,Y0(xip),L0(xip),U0(xip),'LineStyle','none','LineWidth',2,'DisplayName','forwardReversible','Color','b');
    if 0
        % adjust error bar width
        %hE_c=get(hE2, 'Children');
        %errorbarXData= get(hE_c(2), 'XData');
        errorbarXData= get(hE2, 'XData');
        errorbarXData(4:9:end) = errorbarXData(1:9:end) - 0;
        errorbarXData(7:9:end) = errorbarXData(1:9:end) - 0;
        errorbarXData(5:9:end) = errorbarXData(1:9:end) + 0;
        errorbarXData(8:9:end) = errorbarXData(1:9:end) + 0;
        %set(hE_c(2), 'XData', errorbarXData);
        set(hE2, 'XData', errorbarXData);
    end

    %mean dGrt0
    plot(X1,Y0(xip),'.','LineStyle','none','Color',[0.3412 0.7961 0.1922]);
    %zero line
    %cumulative probability that reaction is really forward, assuming a
    %normal distribution about the mean dGt0
    [AX,H1,H2]=plotyy(X1,zeros(1,length(X1)),X1,P(xip));
    set(AX(1),'YTickMode','manual','YTick',floor(minY/100)*200:100:maxY);%,'TickDirMode','manual','TickDir','out');
    set(AX(2),'YTick',[0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1]);
    set(H1,'LineStyle','none')
    set(H2,'LineStyle','-','LineWidth',2,'Color','k')
    plot(X1,zeros(1,length(X1)),'w','LineWidth',2,'LineStyle','--');
    %axis limits
    %     axis(AX(1),[0 length(X1) minY maxY])
    axis(AX(1),[0 length(X1) -500 500]);
    set(AX(1),'FontSize',16)
    set(AX(2),'FontSize',16,'YColor','k')
    axis(AX(2),[0 length(X1) 0 1])
    title('Qualitatively forward, but quantitatively reversible using group contribution estimates of \Delta_{r}G^{\primem}.','FontSize',16)
    set(get(AX(1),'Ylabel'),'String','\Delta_{r}G^{\primem}  (blue)    or     \Delta_{r}G^{\prime} (red) (kJ/mol)')
    set(get(AX(2),'Ylabel'),'String','P(\Delta_{r}G^{\primem}<0)')
    set(get(AX(1),'Ylabel'),'FontSize',16)
    set(get(AX(2),'Ylabel'),'FontSize',16)
    xlabel('Reactions, sorted by \Delta_{r}G^{\primem} or P(\Delta_{r}G^{\primem}<0)');
    saveas(figure1 ,'fwdReversible','fig');
end

%qualitatively forward reactions that are quantitatively
%reversible by concentration alone (no dGt0 error)
% fprintf('%i%s\n',nnz(dGfGCforwardReversibleBool_byConc_No_dGt0ErrorLHS),' qualitatively forward reactions that are GC quantitatively forward by dGr0t, but reversible by concentration alone (No error in GC dGr0t).');
%if figure1 && any(dGfGCforwardReversibleBool_byConc_No_dGt0ErrorLHS)
if ishandle(figure1) && any(dGfGCforwardReversibleBool_byConc_No_dGt0ErrorLHS)

    %make the master plot of all 7 regions, 2, 4,6 are shaded
    X1=1:nRxn;%nnz(directions.forwardReversible);
    %dGrt0
    Y0=(model.dGt0Min+model.dGt0Max)/2;
    L0=Y0-model.dGt0Min;
    U0=model.dGt0Max-Y0;
    %dGrt
    Y=(model.dGtMin+model.dGtMax)/2;
    L=Y-model.dGtMin;
    U=model.dGtMax-Y;
    %find the amount of reactions with normal cumulative distribution over
    %range of dGt0
    P = normcdf(0,Y0,L0);
    %sort by probability that a reaction is forward (puts any NaN first)
    [tmp,xip]=sort(P,'descend');

    %     only take the indices of the problematic reactions, but be sure to
    %     take them in order of descending P
    xip2=zeros(nnz(directions.forwardReversible),1);
    p=1;
    for n=1:nRxn
        if directions.forwardReversible(xip(n))
            xip2(p)=xip(n);
            p=p+1;
        end
    end
    xip=xip2;
    X1=1:length(xip);

    %replace the NaN due to zero st dev
    nNaNpLHS=nnz(dGfGCforwardReversibleBool_byConc_No_dGt0ErrorLHS);
    nNaNpRHS=nnz(dGfGCforwardReversibleBool_byConc_No_dGt0ErrorRHS);
    if (nNaNpLHS+nNaNpRHS)~=nnz(isnan((P(directions.forwardReversible))))
        warning('ExtraCategory');
    end
    %nans are first in the ordering of indexes
    NaNPInd=xip(1:nNaNpLHS+nNaNpRHS);
    %sorts indices of the zero std dev met by their mean dG0t
    [tmp,xipNaNPInd]=sort(Y0(NaNPInd));
    %new ordering
    xip=[NaNPInd(xipNaNPInd(1:nNaNpLHS)); xip(nNaNpLHS+nNaNpRHS+1:end); NaNPInd(xipNaNPInd(nNaNpLHS+1:nNaNpLHS+nNaNpRHS))];
    %     xip=xip(nNaNpLHS+nNaNpRHS+1:end);

    %reactions that cannot be assigned directionality
    %cuttoff for probabilities: must be reflective about 0.5;
%     dGfGCforwardReversibleBool_bydGt0Mid=P<0.6 & P>0.4 & directions.forwardReversible;

    %     only take the indices of the problematic reactions, but be sure to
    %     take them in order of descending P
    xip2=zeros(nnz(dGfGCforwardReversibleBool_byConc_No_dGt0ErrorLHS),1);
    p=1;
    for n=1:length(xip)
        if dGfGCforwardReversibleBool_byConc_No_dGt0ErrorLHS(xip(n))
            xip2(p)=xip(n);
            p=p+1;
        end
    end
    xip=xip2;
    X1=1:length(xip);

    figure1 = figure('PaperSize',[11 8.5],'PaperOrientation','landscape');
    % Create axes
    axes1 = axes('Parent',figure1,'Color',[0.702 0.7804 1]);
    hold on;
    %upper and lower Y
    minY=min(model.dGtMin(dGfGCforwardReversibleBool_byConc_No_dGt0ErrorLHS));
    maxY=max(model.dGtMax(dGfGCforwardReversibleBool_byConc_No_dGt0ErrorLHS));
    %baselines
    PreversibleBar_byConcLHS=ones(1,nRxn)*minY;
    PreversibleBar_byConcRHS=ones(1,nRxn)*minY;
    PreversibleBar_bydGt0=ones(1,nRxn)*minY;
    %bar for 2 & 6
    PreversibleBar_byConcLHS(dGfGCforwardReversibleBool_byConcLHS)=maxY;
    bar_handle2=bar(X1,PreversibleBar_byConcLHS(xip),1,'BaseValue',minY,'FaceColor',[0.86 0.86 0.86],'EdgeColor','none');

    %dGrt errorbar
    hE=errorbar(X1,Y(xip),L(xip),U(xip),'LineStyle','none','LineWidth',9,'DisplayName','forwardReversible','Color','r');
    % adjust error bar width
    hE_c=get(hE, 'Children');
    errorbarXData= get(hE_c(2), 'XData');
    errorbarXData(4:9:end) = errorbarXData(1:9:end) - 0;
    errorbarXData(7:9:end) = errorbarXData(1:9:end) - 0;
    errorbarXData(5:9:end) = errorbarXData(1:9:end) + 0;
    errorbarXData(8:9:end) = errorbarXData(1:9:end) + 0;
    set(hE_c(2), 'XData', errorbarXData);
    %dGrt0 errorbar on top and inside dGrt
    hE2=errorbar(X1,Y0(xip),L0(xip),U0(xip),'LineStyle','none','LineWidth',9,'DisplayName','forwardReversible','Color','b');
    % adjust error bar width
    hE_c=get(hE2, 'Children');
    errorbarXData= get(hE_c(2), 'XData');
    errorbarXData(4:9:end) = errorbarXData(1:9:end) - 0;
    errorbarXData(7:9:end) = errorbarXData(1:9:end) - 0;
    errorbarXData(5:9:end) = errorbarXData(1:9:end) + 0;
    errorbarXData(8:9:end) = errorbarXData(1:9:end) + 0;
    set(hE_c(2), 'XData', errorbarXData);

    %mean dGrt0
    plot(X1,Y0(xip),'.','MarkerSize',20,'LineStyle','none','Color',[0.3412 0.7961 0.1922]);
    %zero line
    %cumulative probability that reaction is really forward, assuming a
    %normal distribution about the mean dGt0
    [AX,H1,H2]=plotyy(X1,zeros(1,length(X1)),X1,P(xip));
    set(AX(1),'YTickMode','manual','YTick',floor(minY/100)*200:20:maxY);%,'TickDirMode','manual','TickDir','out');
    set(AX(2),'YTick',[0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1]);
    set(H1,'LineStyle','none')
    set(H2,'LineStyle','-','LineWidth',2,'Color','k')
    plot(X1,zeros(1,length(X1)),'w','LineWidth',2,'LineStyle','--');
    %axis limits
%     axis(AX(1),[0 length(X1) minY maxY])
    axis(AX(1),[0 length(X1) -200 200]);
    set(AX(1),'FontSize',16)
    set(AX(2),'FontSize',16,'YColor','k')
    axis(AX(2),[0 length(X1) 0 1])
    title({'Qualitatively forward, but quantitatively reversible. Exact negative \Delta_{r}G^{\primem},';...
            'but with a quantitatively reversible concentration range.'},'FontSize',16)
    set(get(AX(1),'Ylabel'),'String','\Delta_{r}G^{\primem}  (blue)    or     \Delta_{r}G^{\prime} (red) (kJ/mol)')
    set(get(AX(2),'Ylabel'),'String','P(\Delta_{r}G^{\primem}<0)')
    set(get(AX(1),'Ylabel'),'FontSize',16)
    set(get(AX(2),'Ylabel'),'FontSize',16)
    xlabel('Reactions, sorted by P(\Delta_{r}G^{\primem}<0)');
end

%qualitatively reverse reactions that are quantitatively
%reversible by concentration alone (no dGt0 error)
% fprintf('%i%s\n',nnz(dGfGCforwardReversibleBool_byConc_No_dGt0ErrorRHS),' qualitatively forward reactions that are GC quantitatively reverse by dGr0t, but reversible by concentration.(No error in GC dGr0t).');
if figure7 && any(dGfGCforwardReversibleBool_byConc_No_dGt0ErrorRHS)
    X1=1:nRxn;
    %dGrt0
    Y0=(model.dGt0Min+model.dGt0Max)/2;
    L0=Y0-model.dGt0Min;
    U0=model.dGt0Max-Y0;
    %dGrt
    Y=(model.dGtMin+model.dGtMax)/2;
    L=Y-model.dGtMin;
    U=model.dGtMax-Y;
    %find the amount of reactions with normal cumulative distribution over
    %range of dGt0
    P = normcdf(0,Y0,L0);
    %sort by probability that a reaction is forward (puts any NaN first)
    [tmp,xip]=sort(P,'descend');

    %     only take the indices of the problematic reactions, but be sure to
    %     take them in order of descending P
    xip2=zeros(nnz(directions.forwardReversible),1);
    p=1;
    for n=1:nRxn
        if directions.forwardReversible(xip(n))
            xip2(p)=xip(n);
            p=p+1;
        end
    end
    xip=xip2;
    X1=1:length(xip);

    %replace the NaN due to zero st dev
    nNaNpLHS=nnz(dGfGCforwardReversibleBool_byConc_No_dGt0ErrorLHS);
    nNaNpRHS=nnz(dGfGCforwardReversibleBool_byConc_No_dGt0ErrorRHS);
    if (nNaNpLHS+nNaNpRHS)~=nnz(isnan((P(directions.forwardReversible))))
        warning('ExtraCategory');
    end
    %nans are first in the ordering of indexes
    NaNPInd=xip(1:nNaNpLHS+nNaNpRHS);
    %sorts indices of the zero std dev met by their mean dG0t
    [tmp,xipNaNPInd]=sort(Y0(NaNPInd));
    %new ordering
    xip=[NaNPInd(xipNaNPInd(1:nNaNpLHS)); xip(nNaNpLHS+nNaNpRHS+1:end); NaNPInd(xipNaNPInd(nNaNpLHS+1:nNaNpLHS+nNaNpRHS))];
    %     xip=xip(nNaNpLHS+nNaNpRHS+1:end);

    %reactions that cannot be assigned directionality
    %cuttoff for probabilities: must be reflective about 0.5;
%     dGfGCforwardReversibleBool_bydGt0Mid=P<0.6 & P>0.4 & directions.forwardReversible;

    %     only take the indices of the problematic reactions, but be sure to
    %     take them in order of descending P
    xip2=zeros(nnz(dGfGCforwardReversibleBool_byConc_No_dGt0ErrorRHS),1);
    p=1;
    for n=1:length(xip)
        if dGfGCforwardReversibleBool_byConc_No_dGt0ErrorRHS(xip(n))
            xip2(p)=xip(n);
            p=p+1;
        end
    end
    xip=xip2;
    X1=1:length(xip);

    figure1 = figure('PaperSize',[11 8.5],'PaperOrientation','landscape');
    % Create axes
    axes1 = axes('Parent',figure1,'Color',[0.702 0.7804 1]);
    hold on;
    %upper and lower Y
    minY=min(model.dGtMin(dGfGCforwardReversibleBool_byConc_No_dGt0ErrorRHS));
    maxY=max(model.dGtMax(dGfGCforwardReversibleBool_byConc_No_dGt0ErrorRHS));
    %baselines
    PreversibleBar_byConcLHS=ones(1,nRxn)*minY;
    PreversibleBar_byConcRHS=ones(1,nRxn)*minY;
    PreversibleBar_bydGt0=ones(1,nRxn)*minY;
    %bar for 2 & 6
    PreversibleBar_byConcLHS(dGfGCforwardReversibleBool_byConcLHS)=maxY;
    bar_handle2=bar(X1,PreversibleBar_byConcLHS(xip),1,'BaseValue',minY,'FaceColor',[0.86 0.86 0.86],'EdgeColor','none');

    %dGrt errorbar
    hE=errorbar(X1,Y(xip),L(xip),U(xip),'LineStyle','none','LineWidth',16,'DisplayName','forwardReversible','Color','r');
    % adjust error bar width
    hE_c=get(hE, 'Children');
    errorbarXData= get(hE_c(2), 'XData');
    errorbarXData(4:9:end) = errorbarXData(1:9:end) - 0;
    errorbarXData(7:9:end) = errorbarXData(1:9:end) - 0;
    errorbarXData(5:9:end) = errorbarXData(1:9:end) + 0;
    errorbarXData(8:9:end) = errorbarXData(1:9:end) + 0;
    set(hE_c(2), 'XData', errorbarXData);
    %dGrt0 errorbar on top and inside dGrt
    hE2=errorbar(X1,Y0(xip),L0(xip),U0(xip),'LineStyle','none','LineWidth',16,'DisplayName','forwardReversible','Color','b');
    % adjust error bar width
    hE_c=get(hE2, 'Children');
    errorbarXData= get(hE_c(2), 'XData');
    errorbarXData(4:9:end) = errorbarXData(1:9:end) - 0;
    errorbarXData(7:9:end) = errorbarXData(1:9:end) - 0;
    errorbarXData(5:9:end) = errorbarXData(1:9:end) + 0;
    errorbarXData(8:9:end) = errorbarXData(1:9:end) + 0;
    set(hE_c(2), 'XData', errorbarXData);

    %mean dGrt0
    plot(X1,Y0(xip),'.','MarkerSize',24,'LineStyle','none','Color',[0.3412 0.7961 0.1922]);
    %zero line
    %cumulative probability that reaction is really forward, assuming a
    %normal distribution about the mean dGt0
    [AX,H1,H2]=plotyy(X1,zeros(1,length(X1)),X1,P(xip));
    set(AX(1),'YTickMode','manual','YTick',floor(minY/100)*200:20:maxY);%,'TickDirMode','manual','TickDir','out');
    set(AX(2),'YTick',[0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1]);
    set(H1,'LineStyle','none')
    set(H2,'LineStyle','-','LineWidth',2,'Color','k')
    plot(X1,zeros(1,length(X1)),'w','LineWidth',2,'LineStyle','--');
    %axis limits
    axis(AX(1),[0 (length(X1)+1) minY maxY])
%     axis(AX(1),[0 length(X1) -500 500]);
    set(AX(1),'FontSize',16)
    set(AX(2),'FontSize',16,'YColor','k')
    axis(AX(2),[0 (length(X1)+1) 0 1])
    title({'Qualitatively forward, but quantitatively reversible. Exact positive \Delta_{r}G^{\primem},';...
            'but with a quantitatively reversible concentration range.'},'FontSize',16)
    set(get(AX(1),'Ylabel'),'String','\Delta_{r}G^{\primem}  (blue)    or     \Delta_{r}G^{\prime} (red) (kJ/mol)')
    set(get(AX(2),'Ylabel'),'String','P(\Delta_{r}G^{\primem}<0)')
    set(get(AX(1),'Ylabel'),'FontSize',16)
    set(get(AX(2),'Ylabel'),'FontSize',16)
    xlabel('Reactions, sorted by P(\Delta_{r}G^{\primem}<0)');
end

%qualitatively reverse reactions that are quantitatively
%reversible by concentration alone (with dGt0 error)
% fprintf('%i%s\n',nnz(dGfGCforwardReversibleBool_byConcLHS),' qualitatively forward reactions that are GC quantitatively reverse by dGr0t, but reversible by concentration.');
if figure2 && any(dGfGCforwardReversibleBool_byConcLHS)
    %make the master plot of all 7 regions, 2, 4,6 are shaded
    X1=1:nRxn;%nnz(directions.forwardReversible);
    %dGrt0
    Y0=(model.dGt0Min+model.dGt0Max)/2;
    L0=Y0-model.dGt0Min;
    U0=model.dGt0Max-Y0;
    %dGrt
    Y=(model.dGtMin+model.dGtMax)/2;
    L=Y-model.dGtMin;
    U=model.dGtMax-Y;
    %find the amount of reactions with normal cumulative distribution over
    %range of dGt0
    P = normcdf(0,Y0,L0);
    %sort by probability that a reaction is forward (puts any NaN first)
    [tmp,xip]=sort(P,'descend');

    %     only take the indices of the problematic reactions, but be sure to
    %     take them in order of descending P
    xip2=zeros(nnz(directions.forwardReversible),1);
    p=1;
    for n=1:nRxn
        if directions.forwardReversible(xip(n))
            xip2(p)=xip(n);
            p=p+1;
        end
    end
    xip=xip2;
    X1=1:length(xip);

    %replace the NaN due to zero st dev
    nNaNpLHS=nnz(dGfGCforwardReversibleBool_byConc_No_dGt0ErrorLHS);
    nNaNpRHS=nnz(dGfGCforwardReversibleBool_byConc_No_dGt0ErrorRHS);
    if (nNaNpLHS+nNaNpRHS)~=nnz(isnan((P(directions.forwardReversible))))
        warning('ExtraCategory');
    end
    %nans are first in the ordering of indexes
    NaNPInd=xip(1:nNaNpLHS+nNaNpRHS);
    %sorts indices of the zero std dev met by their mean dG0t
    [tmp,xipNaNPInd]=sort(Y0(NaNPInd));
    %new ordering
    xip=[NaNPInd(xipNaNPInd(1:nNaNpLHS)); xip(nNaNpLHS+nNaNpRHS+1:end); NaNPInd(xipNaNPInd(nNaNpLHS+1:nNaNpLHS+nNaNpRHS))];
    %     xip=xip(nNaNpLHS+nNaNpRHS+1:end);

    %reactions that cannot be assigned directionality
    %cuttoff for probabilities: must be reflective about 0.5;
%     dGfGCforwardReversibleBool_bydGt0Mid=P<0.6 & P>0.4 & directions.forwardReversible;

        %     only take the indices of the problematic reactions, but be sure to
    %     take them in order of descending P
    xip2=zeros(nnz(dGfGCforwardReversibleBool_byConcLHS),1);
    p=1;
    for n=1:length(xip)
        if dGfGCforwardReversibleBool_byConcLHS(xip(n))
            xip2(p)=xip(n);
            p=p+1;
        end
    end
    xip=xip2;
    X1=1:length(xip);

    figure1 = figure('PaperSize',[11 8.5],'PaperOrientation','landscape');
    % Create axes
    axes1 = axes('Parent',figure1,'Color',[0.702 0.7804 1]);
    hold on;
    %upper and lower Y
    minY=min(model.dGtMin(dGfGCforwardReversibleBool_byConcLHS));
    maxY=max(model.dGtMax(dGfGCforwardReversibleBool_byConcLHS));
    %baselines
    PreversibleBar_byConcLHS=ones(1,nRxn)*minY;
    PreversibleBar_byConcRHS=ones(1,nRxn)*minY;
    PreversibleBar_bydGt0=ones(1,nRxn)*minY;
    %bar for 2 & 6
    PreversibleBar_byConcLHS(dGfGCforwardReversibleBool_byConcLHS)=maxY;
    PreversibleBar_byConcRHS(dGfGCforwardReversibleBool_byConcRHS)=maxY;
    %bar for 4
    PreversibleBar_bydGt0(dGfGCforwardReversibleBool_bydGt0Mid)=maxY;
    bar_handle2=bar(X1,PreversibleBar_byConcLHS(xip),1,'BaseValue',minY,'FaceColor',[0.86 0.86 0.86],'EdgeColor','none');
%     bar_handle4=bar(X1,PreversibleBar_bydGt0(xip),1,'BaseValue',minY,'FaceColor',[0.86 0.86 0.86],'EdgeColor','none');
%     bar_handle6=bar(X1,PreversibleBar_byConcRHS(xip),1,'BaseValue',minY,'FaceColor',[0.86 0.86 0.86],'EdgeColor','none');
%
    %dGrt errorbar
    hE=errorbar(X1,Y(xip),L(xip),U(xip),'LineStyle','none','LineWidth',4.5,'DisplayName','forwardReversible','Color','r');
    % adjust error bar width
    hE_c=get(hE, 'Children');
    errorbarXData= get(hE_c(2), 'XData');
    errorbarXData(4:9:end) = errorbarXData(1:9:end) - 0;
    errorbarXData(7:9:end) = errorbarXData(1:9:end) - 0;
    errorbarXData(5:9:end) = errorbarXData(1:9:end) + 0;
    errorbarXData(8:9:end) = errorbarXData(1:9:end) + 0;
    set(hE_c(2), 'XData', errorbarXData);
    %dGrt0 errorbar on top and inside dGrt
    hE2=errorbar(X1,Y0(xip),L0(xip),U0(xip),'LineStyle','none','LineWidth',4.5,'DisplayName','forwardReversible','Color','b');
    % adjust error bar width
    hE_c=get(hE2, 'Children');
    errorbarXData= get(hE_c(2), 'XData');
    errorbarXData(4:9:end) = errorbarXData(1:9:end) - 0;
    errorbarXData(7:9:end) = errorbarXData(1:9:end) - 0;
    errorbarXData(5:9:end) = errorbarXData(1:9:end) + 0;
    errorbarXData(8:9:end) = errorbarXData(1:9:end) + 0;
    set(hE_c(2), 'XData', errorbarXData);

    %mean dGrt0
    plot(X1,Y0(xip),'.','MarkerSize',9,'LineStyle','none','Color',[0.3412 0.7961 0.1922]);
    %zero line
    %cumulative probability that reaction is really forward, assuming a
    %normal distribution about the mean dGt0
    [AX,H1,H2]=plotyy(X1,zeros(1,length(X1)),X1,P(xip));
    set(AX(1),'YTickMode','manual','YTick',floor(minY/100)*200:50:maxY);%,'TickDirMode','manual','TickDir','out');
    set(AX(2),'YTick',[0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1]);
    set(H1,'LineStyle','none');
    set(H2,'LineStyle','-','LineWidth',2,'Color','k');
    plot(X1,zeros(1,length(X1)),'w','LineWidth',2,'LineStyle','--');
    %axis limits
    if length(X1)~=1
        axis(AX(1),[1 length(X1) minY maxY])
    else
        axis(AX(1),[1-0.5 length(X1)+0.5 minY maxY])
    end
%     axis(AX(1),[1 length(X1) -500 500]);
    set(AX(1),'FontSize',16)
    set(AX(2),'FontSize',16,'YColor','k')
    if length(X1)~=1
        axis(AX(2),[1 length(X1) 0 1])
    else
        axis(AX(2),[1-0.5 length(X1)+0.5 0 1])
    end
    title({'Qualitatively forward, but quantitatively reversible. Negative group contribution \Delta_{r}G^{\primem} estimate,';...
            'even with uncertainty, but with a quantitatively reversible concentration range.'},'FontSize',16)
    set(get(AX(1),'Ylabel'),'String','\Delta_{r}G^{\primem}  (blue)    or     \Delta_{r}G^{\prime} (red) (kJ/mol)')
    set(get(AX(2),'Ylabel'),'String','P(\Delta_{r}G^{\primem}<0)')
    set(get(AX(1),'Ylabel'),'FontSize',16)
    set(get(AX(2),'Ylabel'),'FontSize',16)
    xlabel('Reactions, sorted by P(\Delta_{r}G^{\primem}<0)');
end

%qualitatively reverse reactions that are quantitatively
%reversible by concentration alone (with dGt0 error)
% fprintf('%i%s\n',nnz(dGfGCforwardReversibleBool_byConcRHS),' qualitatively forward reactions that are GC quantitatively reverse by dGr0t, but reversible by concentration.');
if figure6 && any(dGfGCforwardReversibleBool_byConcRHS)
    %make the master plot of all 7 regions, 2, 4,6 are shaded
    X1=1:nRxn;%nnz(directions.forwardReversible);
    %dGrt0
    Y0=(model.dGt0Min+model.dGt0Max)/2;
    L0=Y0-model.dGt0Min;
    U0=model.dGt0Max-Y0;
    %dGrt
    Y=(model.dGtMin+model.dGtMax)/2;
    L=Y-model.dGtMin;
    U=model.dGtMax-Y;
    %find the amount of reactions with normal cumulative distribution over
    %range of dGt0
    P = normcdf(0,Y0,L0);
    %sort by probability that a reaction is forward (puts any NaN first)
    [tmp,xip]=sort(P,'descend');

    %     only take the indices of the problematic reactions, but be sure to
    %     take them in order of descending P
    xip2=zeros(nnz(directions.forwardReversible),1);
    p=1;
    for n=1:nRxn
        if directions.forwardReversible(xip(n))
            xip2(p)=xip(n);
            p=p+1;
        end
    end
    xip=xip2;
    X1=1:length(xip);

    %replace the NaN due to zero st dev
    nNaNpLHS=nnz(dGfGCforwardReversibleBool_byConc_No_dGt0ErrorLHS);
    nNaNpRHS=nnz(dGfGCforwardReversibleBool_byConc_No_dGt0ErrorRHS);
    if (nNaNpLHS+nNaNpRHS)~=nnz(isnan((P(directions.forwardReversible))))
        warning('ExtraCategory');
    end
    %nans are first in the ordering of indexes
    NaNPInd=xip(1:nNaNpLHS+nNaNpRHS);
    %sorts indices of the zero std dev met by their mean dG0t
    [tmp,xipNaNPInd]=sort(Y0(NaNPInd));
    %new ordering
    xip=[NaNPInd(xipNaNPInd(1:nNaNpLHS)); xip(nNaNpLHS+nNaNpRHS+1:end); NaNPInd(xipNaNPInd(nNaNpLHS+1:nNaNpLHS+nNaNpRHS))];
    %     xip=xip(nNaNpLHS+nNaNpRHS+1:end);

    %reactions that cannot be assigned directionality
    %cuttoff for probabilities: must be reflective about 0.5;
%     dGfGCforwardReversibleBool_bydGt0Mid=P<0.6 & P>0.4 & directions.forwardReversible;

        %     only take the indices of the problematic reactions, but be sure to
    %     take them in order of descending P
    xip2=zeros(nnz(dGfGCforwardReversibleBool_byConcRHS),1);
    p=1;
    for n=1:length(xip)
        if dGfGCforwardReversibleBool_byConcRHS(xip(n))
            xip2(p)=xip(n);
            p=p+1;
        end
    end
    xip=xip2;
    X1=1:length(xip);

    figure1 = figure('PaperSize',[11 8.5],'PaperOrientation','landscape');
    % Create axes
    axes1 = axes('Parent',figure1,'Color',[0.702 0.7804 1]);
    hold on;
    %upper and lower Y
    minY=min(model.dGtMin(dGfGCforwardReversibleBool_byConcRHS));
    maxY=max(model.dGtMax(dGfGCforwardReversibleBool_byConcRHS));
    %baselines
    PreversibleBar_byConcLHS=ones(1,nRxn)*minY;
    PreversibleBar_byConcRHS=ones(1,nRxn)*minY;
    PreversibleBar_bydGt0=ones(1,nRxn)*minY;
    %bar for 2 & 6
    PreversibleBar_byConcLHS(dGfGCforwardReversibleBool_byConcLHS)=maxY;
    PreversibleBar_byConcRHS(dGfGCforwardReversibleBool_byConcRHS)=maxY;
    %bar for 4
    PreversibleBar_bydGt0(dGfGCforwardReversibleBool_bydGt0Mid)=maxY;
%     bar_handle2=bar(X1,PreversibleBar_byConcLHS(xip),1,'BaseValue',minY,'FaceColor',[0.86 0.86 0.86],'EdgeColor','none');
%     bar_handle4=bar(X1,PreversibleBar_bydGt0(xip),1,'BaseValue',minY,'FaceColor',[0.86 0.86 0.86],'EdgeColor','none');
    bar_handle6=bar(X1,PreversibleBar_byConcRHS(xip),1,'BaseValue',minY,'FaceColor',[0.86 0.86 0.86],'EdgeColor','none');
%
    %dGrt errorbar
    hE=errorbar(X1,Y(xip),L(xip),U(xip),'LineStyle','none','LineWidth',10,'DisplayName','forwardReversible','Color','r');
    % adjust error bar width
    hE_c=get(hE, 'Children');
    errorbarXData= get(hE_c(2), 'XData');
    errorbarXData(4:9:end) = errorbarXData(1:9:end) - 0;
    errorbarXData(7:9:end) = errorbarXData(1:9:end) - 0;
    errorbarXData(5:9:end) = errorbarXData(1:9:end) + 0;
    errorbarXData(8:9:end) = errorbarXData(1:9:end) + 0;
    set(hE_c(2), 'XData', errorbarXData);
    %dGrt0 errorbar on top and inside dGrt
    hE2=errorbar(X1,Y0(xip),L0(xip),U0(xip),'LineStyle','none','LineWidth',10,'DisplayName','forwardReversible','Color','b');
    % adjust error bar width
    hE_c=get(hE2, 'Children');
    errorbarXData= get(hE_c(2), 'XData');
    errorbarXData(4:9:end) = errorbarXData(1:9:end) - 0;
    errorbarXData(7:9:end) = errorbarXData(1:9:end) - 0;
    errorbarXData(5:9:end) = errorbarXData(1:9:end) + 0;
    errorbarXData(8:9:end) = errorbarXData(1:9:end) + 0;
    set(hE_c(2), 'XData', errorbarXData);

    %mean dGrt0
    plot(X1,Y0(xip),'.','MarkerSize',16,'LineStyle','none','Color',[0.3412 0.7961 0.1922]);
    %zero line
    %cumulative probability that reaction is really forward, assuming a
    %normal distribution about the mean dGt0
    [AX,H1,H2]=plotyy(X1,zeros(1,length(X1)),X1,P(xip));
    set(AX(1),'YTickMode','manual','YTick',floor(minY/100)*200:20:maxY);%,'TickDirMode','manual','TickDir','out');
    set(AX(2),'YTick',[0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1]);
    set(H1,'LineStyle','none');
    set(H2,'LineStyle','-','LineWidth',2,'Color','k');
    plot(X1,zeros(1,length(X1)),'w','MarkerSize',10,'LineWidth',2,'LineStyle','--');
    %axis limits
    axis(AX(1),[0.48 (length(X1)+0.48) minY maxY])
%     axis(AX(1),[0.48 (length(X1)+0.48) -500 500]);
    set(AX(1),'FontSize',16)
    set(AX(2),'FontSize',16,'YColor','k')
    axis(AX(2),[0.48 (length(X1)+0.48) 0 1])
    title({'Qualitatively forward, but quantitatively reversible. Positive group contribution \Delta_{r}G^{\primem} estimate,';...
            'even with uncertainty, but with a quantitatively reversible concentration range.'},'FontSize',16)
    set(get(AX(1),'Ylabel'),'String','\Delta_{r}G^{\primem}  (blue)    or     \Delta_{r}G^{\prime} (red) (kJ/mol)')
    set(get(AX(2),'Ylabel'),'String','P(\Delta_{r}G^{\primem}<0)')
    set(get(AX(1),'Ylabel'),'FontSize',16)
    set(get(AX(2),'Ylabel'),'FontSize',16)
    xlabel('Reactions, sorted by P(\Delta_{r}G^{\primem}<0)');
end

%qualitatively forward reactions that are quantitatively reversible by
%the range of dGt0
% fprintf('%i%s\n',nnz(dGfGCforwardReversibleBool_bydGt0),' qualitatively forward reactions that are GC quantitatively reversible by range of dGt0.');
if figure345 && any(dGfGCforwardReversibleBool_bydGt0)
    %make the master plot of all 7 regions, 2, 4,6 are shaded
    X1=1:nRxn;%nnz(directions.forwardReversible);
    %dGrt0
    Y0=(model.dGt0Min+model.dGt0Max)/2;
    L0=Y0-model.dGt0Min;
    U0=model.dGt0Max-Y0;
    %dGrt
    Y=(model.dGtMin+model.dGtMax)/2;
    L=Y-model.dGtMin;
    U=model.dGtMax-Y;
    %find the amount of reactions with normal cumulative distribution over
    %range of dGt0
    P = normcdf(0,Y0,L0);
    %sort by probability that a reaction is forward (puts any NaN first)
    [tmp,xip]=sort(P,'descend');

    %     only take the indices of the problematic reactions, but be sure to
    %     take them in order of descending P
    xip2=zeros(nnz(directions.forwardReversible),1);
    p=1;
    for n=1:nRxn
        if directions.forwardReversible(xip(n))
            xip2(p)=xip(n);
            p=p+1;
        end
    end
    xip=xip2;
    X1=1:length(xip);

    %replace the NaN due to zero st dev
    nNaNpLHS=nnz(dGfGCforwardReversibleBool_byConc_No_dGt0ErrorLHS);
    nNaNpRHS=nnz(dGfGCforwardReversibleBool_byConc_No_dGt0ErrorRHS);
    if (nNaNpLHS+nNaNpRHS)~=nnz(isnan((P(directions.forwardReversible))))
        warning('ExtraCategory');
    end
    %nans are first in the ordering of indexes
    NaNPInd=xip(1:nNaNpLHS+nNaNpRHS);
    %sorts indices of the zero std dev met by their mean dG0t
    [tmp,xipNaNPInd]=sort(Y0(NaNPInd));
    %new ordering
    xip=[NaNPInd(xipNaNPInd(1:nNaNpLHS)); xip(nNaNpLHS+nNaNpRHS+1:end); NaNPInd(xipNaNPInd(nNaNpLHS+1:nNaNpLHS+nNaNpRHS))];
    %     xip=xip(nNaNpLHS+nNaNpRHS+1:end);

    %reactions that cannot be assigned directionality
    %cuttoff for probabilities: must be reflective about 0.5;
%     dGfGCforwardReversibleBool_bydGt0Mid=P<0.6 & P>0.4 & directions.forwardReversible;

            %     only take the indices of the problematic reactions, but be sure to
    %     take them in order of descending P
    xip2=zeros(nnz(dGfGCforwardReversibleBool_bydGt0),1);% dGfGCforwardReversibleBool_byConcRHS),1);
    p=1;
    for n=1:length(xip)
        if dGfGCforwardReversibleBool_bydGt0(xip(n))
            xip2(p)=xip(n);
            p=p+1;
        end
    end
    xip=xip2;
    X1=1:length(xip);

    figure1 = figure('PaperSize',[11 8.5],'PaperOrientation','landscape');
    % Create axes
    axes1 = axes('Parent',figure1,'Color',[0.702 0.7804 1]);
    hold on;
    %upper and lower Y
    minY=min(model.dGtMin(dGfGCforwardReversibleBool_bydGt0));
    maxY=max(model.dGtMax(dGfGCforwardReversibleBool_bydGt0));

    %baselines
    PreversibleBar_byConcLHS=ones(1,nRxn)*minY;
    PreversibleBar_byConcRHS=ones(1,nRxn)*minY;
    PreversibleBar_bydGt0=ones(1,nRxn)*minY;
    %bar for 2 & 6
    PreversibleBar_byConcLHS(dGfGCforwardReversibleBool_byConcLHS)=maxY;
    PreversibleBar_byConcRHS(dGfGCforwardReversibleBool_byConcRHS)=maxY;
    %bar for 4
    PreversibleBar_bydGt0(dGfGCforwardReversibleBool_bydGt0Mid)=maxY;
    bar_handle2=bar(X1,PreversibleBar_byConcLHS(xip),1,'BaseValue',minY,'FaceColor',[0.86 0.86 0.86],'EdgeColor','none');
    bar_handle4=bar(X1,PreversibleBar_bydGt0(xip),1,'BaseValue',minY,'FaceColor',[0.86 0.86 0.86],'EdgeColor','none');
    bar_handle6=bar(X1,PreversibleBar_byConcRHS(xip),1,'BaseValue',minY,'FaceColor',[0.86 0.86 0.86],'EdgeColor','none');

    %dGrt errorbar
    hE=errorbar(X1,Y(xip),L(xip),U(xip),'LineStyle','none','LineWidth',2,'DisplayName','forwardReversible','Color','r');
    % adjust error bar width
    %hE_c=get(hE, 'Children');
    %errorbarXData= get(hE_c(2), 'XData');
    errorbarXData= get(hE, 'XData');
    errorbarXData(4:9:end) = errorbarXData(1:9:end) - 0;
    errorbarXData(7:9:end) = errorbarXData(1:9:end) - 0;
    errorbarXData(5:9:end) = errorbarXData(1:9:end) + 0;
    errorbarXData(8:9:end) = errorbarXData(1:9:end) + 0;
    %set(hE_c(2), 'XData', errorbarXData);
    set(hE, 'XData', errorbarXData);
    %dGrt0 errorbar on top and inside dGrt
    hE2=errorbar(X1,Y0(xip),L0(xip),U0(xip),'LineStyle','none','LineWidth',2,'DisplayName','forwardReversible','Color','b');
    % adjust error bar width
    %hE_c=get(hE2, 'Children');
    %errorbarXData= get(hE_c(2), 'XData');
    errorbarXData= get(hE2, 'XData');
    errorbarXData(4:9:end) = errorbarXData(1:9:end) - 0;
    errorbarXData(7:9:end) = errorbarXData(1:9:end) - 0;
    errorbarXData(5:9:end) = errorbarXData(1:9:end) + 0;
    errorbarXData(8:9:end) = errorbarXData(1:9:end) + 0;
    %set(hE_c(2), 'XData', errorbarXData);
    set(hE2, 'XData', errorbarXData);

    %mean dGrt0
    plot(X1,Y0(xip),'.','MarkerSize',6,'LineStyle','none','Color',[0.3412 0.7961 0.1922]);
    %zero line
    %cumulative probability that reaction is really forward, assuming a
    %normal distribution about the mean dGt0
    [AX,H1,H2]=plotyy(X1,zeros(1,length(X1)),X1,P(xip));
    set(AX(1),'YTickMode','manual','YTick',floor(minY/100)*200:100:maxY);%,'TickDirMode','manual','TickDir','out');
    set(AX(2),'YTick',[0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1]);
    set(H1,'LineStyle','none')
    set(H2,'LineStyle','-','LineWidth',2,'Color','k')
    plot(X1,zeros(1,length(X1)),'w','LineWidth',2,'LineStyle','--');
    %axis limits
    %     axis(AX(1),[0 length(X1) minY maxY])
    axis(AX(1),[0 length(X1) -500 500]);
    set(AX(1),'FontSize',16)
    set(AX(2),'FontSize',16,'YColor','k')
    axis(AX(2),[0 length(X1) 0 1])
    title({'Qualitatively forward, but quantitatively reversible. The group contribution ';
           '\Delta_{r}G^{\primem} estimates span the zero line.'},'FontSize',16)
    set(get(AX(1),'Ylabel'),'String','\Delta_{r}G^{\primem}  (blue)    or     \Delta_{r}G^{\prime} (red) (kJ/mol)')
    set(get(AX(2),'Ylabel'),'String','P(\Delta_{r}G^{\primem}<0)')
    set(get(AX(1),'Ylabel'),'FontSize',16)
    set(get(AX(2),'Ylabel'),'FontSize',16)
    xlabel('Reactions, sorted by P(\Delta_{r}G^{\primem}<0)');
end

changedDirections = directions;
% old code
%         %reactions that are qualitatively forward but quantitatively reverse
%         X=1:nnz(changedDirections.forwardReversible);
%         Y=(model.dGt0Min(changedDirections.forwardReversible)+model.dGt0Max(changedDirections.forwardReversible))/2;
%         L=Y-model.dGt0Min(changedDirections.forwardReversible);
%         U=model.dGt0Max(changedDirections.forwardReversible)-Y;
%         [tmp,xi]=sort(Y);
%         [tmp,xi]=sort(model.dGt0Max(changedDirections.forwardReversible)-model.dGt0Min(changedDirections.forwardReversible));
%         errorbar(X,Y(xi),L(xi),U(xi),'b.')
%         title('All reactions that are qualitatively forward, yet quantitatively reversible');
%         ylabel('dGt0 (kJ/mol)')
%         xlabel('Reactions, sorted by uncertainty in dGt0')
%
%         X=1:nnz(forwardReversibleKeq);
%         Y=(model.dGt0Min(forwardReversibleKeq)+model.dGt0Max(forwardReversibleKeq))/2;
%         L=Y-model.dGt0Min(forwardReversibleKeq);
%         U=model.dGt0Max(forwardReversibleKeq)-Y;
%         [tmp,xi]=sort(Y);
%         figure;
%         errorbar(X,Y(xi),L(xi),U(xi),'b.')
%         title('Reactions qualitiatively forward, but quantitatively reversible by Alberty');
%         ylabel('dGt0 (kJ/mol)')
%         xlabel('Reactions, sorted by mean dGt0')
% %     %GC forward prediction of reactions qualitiatively forward
% %     X1=1:nnz(dGfGCforwardForwardBool);
% %     Y=(model.dGt0Min(dGfGCforwardForwardBool)+model.dGt0Max(dGfGCforwardForwardBool))/2;
% %     L=Y-model.dGt0Min(dGfGCforwardForwardBool);
% %     U=model.dGt0Max(dGfGCforwardForwardBool)-Y;
% %     [tmp,xi]=sort(Y);
% %     figure;
% %     hold on
% %     errorbar(X1,Y(xi),L(xi),U(xi),'b.')
% %     legend('forwardForward')
% %     title('GC forward prediction of reactions qualitiatively forward')
% %     ylabel('dGt0 (kJ/mol)')
% %     xlabel('Reactions, sorted by mean dGt0')
% %
% %     [tmp,xi]=sort(abs(model.dGt0Max(dGfGCforwardForwardBool)-model.dGt0Min(dGfGCforwardForwardBool)));
% %     figure;
% %     hold on
% %     errorbar(X1,Y(xi),L(xi),U(xi),'b.')
% %     legend('forwardForward')
% %     title('GC forward prediction of reactions qualitiatively forward')
% %     ylabel('dGt0 (kJ/mol)')
% %     xlabel('Reactions, sorted by uncertainty in dGt0')
% %
% %     figure
% %     plot(Y(xi),L(xi),'.g')
% %     title('GC forward prediction of reactions qualitiatively forward')
% %     ylabel('dGt0 Uncertainty (kJ/mol)')
% %     xlabel('Reaction dGt0 (kJ/mol), sorted by uncertainty in dGt0')
%
%     %GC reversible prediction of reactions qualitiatively forward by dGrt
%     %dGr0t
%     X1=1:nnz(directions.forwardReversible);
%     Y=(model.dGt0Min(directions.forwardReversible)+model.dGt0Max(directions.forwardReversible))/2;
%     L=Y-model.dGt0Min(directions.forwardReversible);
%     U=model.dGt0Max(directions.forwardReversible)-Y;
% %     [tmp,xi]=sort(Y);
% %     figure
% %     errorbar(X1,Y(xi),L(xi),U(xi),'r.')
% %     title('All GC reversible prediction of reactions qualitiatively forward')
% %     legend('forwardReversible')
% %     ylabel('dGt0 (kJ/mol)')
% %     xlabel('Reactions, sorted by mean dGt0')
%     %dGrt
%     Y2=(model.dGtMin(directions.forwardReversible)+model.dGtMax(directions.forwardReversible))/2;
%     L2=Y2-model.dGtMin(directions.forwardReversible);
%     U2=model.dGtMax(directions.forwardReversible)-Y2;
%     [tmp,xi]=sort(abs(model.dGt0Max(directions.forwardReversible)-model.dGt0Min(directions.forwardReversible)));
%     figure
%     hold on;
%     %dGrt errorbar
%     hE=errorbar(X1,Y2(xi),L2(xi),U2(xi),'LineStyle','none','LineWidth',2,'DisplayName','forwardReversible','Color','r');
%     % adjust error bar width
% %     hE_c=get(hE, 'Children');
% %     errorbarXData= get(hE_c(2), 'XData');
%     errorbarXData= get(hE, 'XData');
%     errorbarXData(4:9:end) = errorbarXData(1:9:end) - 0.2;
%     errorbarXData(7:9:end) = errorbarXData(1:9:end) - 0.2;
%     errorbarXData(5:9:end) = errorbarXData(1:9:end) + 0.2;
%     errorbarXData(8:9:end) = errorbarXData(1:9:end) + 0.2;
%     %set(hE_c(2), 'XData', errorbarXData);
%     set(hE, 'XData', errorbarXData);
%     %dGrt0 errorbar on top and inside dGrt
%     hE2=errorbar(X1,Y(xi),L(xi),U(xi),'LineStyle','none','LineWidth',2,'DisplayName','forwardReversible','Color','b');
%     % adjust error bar width
%     %hE_c=get(hE2, 'Children');
%     %errorbarXData= get(hE_c(2), 'XData');
%     errorbarXData= get(hE2, 'XData');
%
%     errorbarXData(4:9:end) = errorbarXData(1:9:end) - 0.2;
%     errorbarXData(7:9:end) = errorbarXData(1:9:end) - 0.2;
%     errorbarXData(5:9:end) = errorbarXData(1:9:end) + 0.2;
%     errorbarXData(8:9:end) = errorbarXData(1:9:end) + 0.2;
%     %set(hE_c(2), 'XData', errorbarXData);
%     set(hE2, 'XData', errorbarXData);
%     %mean dGrt0
%     plot(X1,Y(xi),'.g','LineStyle','none');
%     %zero line
%     plot(X1,zeros(1,length(X1)),'k');
%     title('GC reversible prediction of reactions qualitiatively forward');
%     ylabel('dGt0 (kJ/mol)');
%     xlabel('Reactions, sorted by uncertainty in dGt0');
%
%     %%%%%%%%
%     %qualitatively forward reactions that are quantitatively reversible by concentration alone
%     %dGrt0
%     Y=(model.dGt0Min(dGfGCforwardReversibleBool_byConc)+model.dGt0Max(dGfGCforwardReversibleBool_byConc))/2;
%     L=Y-model.dGt0Min(dGfGCforwardReversibleBool_byConc);
%     U=model.dGt0Max(dGfGCforwardReversibleBool_byConc)-Y;
%     %dGrt
%     Y2=(model.dGtMin(dGfGCforwardReversibleBool_byConc)+model.dGtMax(dGfGCforwardReversibleBool_byConc))/2;
%     L2=Y2-model.dGtMin(dGfGCforwardReversibleBool_byConc);
%     U2=model.dGtMax(dGfGCforwardReversibleBool_byConc)-Y2;
%     [tmp,xi]=sort(abs(model.dGt0Max(dGfGCforwardReversibleBool_byConc)-model.dGt0Min(dGfGCforwardReversibleBool_byConc)));
%
%     figure
%     hold on;
%     %dGrt errorbar underneath
%     X1=1:nnz(dGfGCforwardReversibleBool_byConc);
%     hE=errorbar(X1,Y2(xi),L2(xi),U2(xi),'LineStyle','none','LineWidth',2,'DisplayName','forwardReversible','Color','r');
%     % adjust error bar width
%     %hE_c=get(hE, 'Children');
%     %errorbarXData= get(hE_c(2), 'XData');
%     errorbarXData= get(hE, 'XData');
%
%     errorbarXData(4:9:end) = errorbarXData(1:9:end) - 0.2;
%     errorbarXData(7:9:end) = errorbarXData(1:9:end) - 0.2;
%     errorbarXData(5:9:end) = errorbarXData(1:9:end) + 0.2;
%     errorbarXData(8:9:end) = errorbarXData(1:9:end) + 0.2;
%     %set(hE_c(2), 'XData', errorbarXData);
%     set(hE, 'XData', errorbarXData);
%
%     %dGrt0 errorbar on top and inside dGrt
%     hE2=errorbar(X1,Y(xi),L(xi),U(xi),'LineStyle','none','LineWidth',2,'DisplayName','forwardReversible','Color','b');
%     % adjust error bar width
%     %hE_c=get(hE2, 'Children');
%     %errorbarXData= get(hE_c(2), 'XData');
%     errorbarXData= get(hE2, 'XData');
%
%     errorbarXData(4:9:end) = errorbarXData(1:9:end) - 0.2;
%     errorbarXData(7:9:end) = errorbarXData(1:9:end) - 0.2;
%     errorbarXData(5:9:end) = errorbarXData(1:9:end) + 0.2;
%     errorbarXData(8:9:end) = errorbarXData(1:9:end) + 0.2;
%     %set(hE_c(2), 'XData', errorbarXData);
%     set(hE2, 'XData', errorbarXData);
%
%
%     %mean dGrt0
% %     plot(X1,Y(xi),'Marker','none','LineStyle','none');
%     plot(X1,Y(xi),'.g','LineStyle','none');
%     %zero line
%     plot(X1,zeros(1,length(X1)),'k');
%     title('Qualitatively forward reactions that are GC quantitatively reversible by concentration');
%     ylabel('dGt0 or dGt(kJ/mol)');
%     xlabel('Reactions, sorted by uncertainty in dGt0');
%
%
%     %qualitatively forward reactions that are quantitatively reversible by
%     %the range of dGt0
%     fprintf('%i%s\n',nnz(dGfGCforwardReversibleBool_bydGt0),' qualitatively forward reactions that are gc quantitatively reversible by range of dGt0');
%     X1=1:nnz(dGfGCforwardReversibleBool_bydGt0);
%     %dGrt0
%     Y=(model.dGt0Min(dGfGCforwardReversibleBool_bydGt0)+model.dGt0Max(dGfGCforwardReversibleBool_bydGt0))/2;
%     L=Y-model.dGt0Min(dGfGCforwardReversibleBool_bydGt0);
%     U=model.dGt0Max(dGfGCforwardReversibleBool_bydGt0)-Y;
%     %dGrt
%     Y2=(model.dGtMin(dGfGCforwardReversibleBool_bydGt0)+model.dGtMax(dGfGCforwardReversibleBool_bydGt0))/2;
%     L2=Y2-model.dGtMin(dGfGCforwardReversibleBool_bydGt0);
%     U2=model.dGtMax(dGfGCforwardReversibleBool_bydGt0)-Y2;
%     [tmp,xi]=sort(abs(model.dGt0Max(dGfGCforwardReversibleBool_bydGt0)-model.dGt0Min(dGfGCforwardReversibleBool_bydGt0)));
%
%     figure;
%     hold on;
%     %dGrt errorbar
%     hE=errorbar(X1,Y2(xi),L2(xi),U2(xi),'LineStyle','none','LineWidth',2,'DisplayName','forwardReversible','Color','r');
%     % adjust error bar width
%     %hE_c=get(hE, 'Children');
%     %errorbarXData= get(hE_c(2), 'XData');
%     errorbarXData= get(hE, 'XData');
%
%     errorbarXData(4:9:end) = errorbarXData(1:9:end) - 0.2;
%     errorbarXData(7:9:end) = errorbarXData(1:9:end) - 0.2;
%     errorbarXData(5:9:end) = errorbarXData(1:9:end) + 0.2;
%     errorbarXData(8:9:end) = errorbarXData(1:9:end) + 0.2;
%     %set(hE_c(2), 'XData', errorbarXData);
%     set(hE, 'XData', errorbarXData);
%
%     %dGrt0 errorbar on top and inside dGrt
%     hE2=errorbar(X1,Y(xi),L(xi),U(xi),'LineStyle','none','LineWidth',2,'DisplayName','forwardReversible','Color','b');
%     % adjust error bar width
%     %hE_c=get(hE2, 'Children');
%     %errorbarXData= get(hE_c(2), 'XData');
%     errorbarXData= get(hE2, 'XData');
%
%     errorbarXData(4:9:end) = errorbarXData(1:9:end) - 0.2;
%     errorbarXData(7:9:end) = errorbarXData(1:9:end) - 0.2;
%     errorbarXData(5:9:end) = errorbarXData(1:9:end) + 0.2;
%     errorbarXData(8:9:end) = errorbarXData(1:9:end) + 0.2;
%     %set(hE_c(2), 'XData', errorbarXData);
%     set(hE2, 'XData', errorbarXData);
%
%     %mean dGrt0
% %     plot(X1,Y(xi),'Marker','none','LineStyle','none');
%     plot(X1,Y(xi),'.g','LineStyle','none');
%     %zero line
%     plot(X1,zeros(1,length(X1)),'k');
%     title('Qualitatively forward reactions that are GC quantitatively reversible by range of dGt0');
%     ylabel('dGt0 or dGt(kJ/mol)');
%     xlabel('Reactions, sorted by uncertainty in dGt0');
%
%      %qualitatively forward reactions that are quantitatively reverseible by
%     %the range of dGt0
%     fprintf('%i%s\n',nnz(dGfGCforwardReversibleBool_bydGt0),' qualitatively forward reactions that are gc quantitatively reversible by range of dGt0');
%     X1=1:nnz(dGfGCforwardReversibleBool_bydGt0);
%     %dGrt0
%     Y=(model.dGt0Min(dGfGCforwardReversibleBool_bydGt0)+model.dGt0Max(dGfGCforwardReversibleBool_bydGt0))/2;
%     L=Y-model.dGt0Min(dGfGCforwardReversibleBool_bydGt0);
%     U=model.dGt0Max(dGfGCforwardReversibleBool_bydGt0)-Y;
%     %dGrt
%     Y2=(model.dGtMin(dGfGCforwardReversibleBool_bydGt0)+model.dGtMax(dGfGCforwardReversibleBool_bydGt0))/2;
%     L2=Y2-model.dGtMin(dGfGCforwardReversibleBool_bydGt0);
%     U2=model.dGtMax(dGfGCforwardReversibleBool_bydGt0)-Y2;
%     %find the amount of reactions with normal cumulative distribution
%     P = normcdf(0,Y,L);
%
%     %sort by fraction of uncertainty that is negative
% %     [tmp,xi]=sort(abs(model.dGt0Min(dGfGCforwardReversibleBool_bydGt0))./abs(model.dGt0Max(dGfGCforwardReversibleBool_bydGt0)-model.dGt0Min(dGfGCforwardReversibleBool_bydGt0)),'descend');
%     %     [tmp,xi]=sort(Y);
%     [tmp,xi]=sort(P,'descend');
%     %cuttoff for probabilities: must be reflective about 0.5;
%     PSortedeversibleBool=tmp<0.6 & tmp>0.4;
%     %reversible section bar in the background
%     figure1=figure;
%     hold on;
%     xbar=1:length(PSortedeversibleBool);
%     PSortedeversibleBar=ones(1,length(PSortedeversibleBool))*min(model.dGtMin(dGfGCforwardReversibleBool_bydGt0));
%     PSortedeversibleBar(PSortedeversibleBool)=max(model.dGtMax(dGfGCforwardReversibleBool_bydGt0));
%     bar_handle=bar(xbar,PSortedeversibleBar,1,'BaseValue',min(model.dGtMin(dGfGCforwardReversibleBool_bydGt0)),'EdgeColor',[0.86 0.86 0.86]);
%     %dGrt errorbar
%     hE=errorbar(X1,Y2(xi),L2(xi),U2(xi),'LineStyle','none','LineWidth',2,'DisplayName','forwardReversible','Color','r');
%     % adjust error bar width
%     %hE_c=get(hE, 'Children');
%     %errorbarXData= get(hE_c(2), 'XData');
%     errorbarXData= get(hE, 'XData');
%
%     errorbarXData(4:9:end) = errorbarXData(1:9:end) - 0.2;
%     errorbarXData(7:9:end) = errorbarXData(1:9:end) - 0.2;
%     errorbarXData(5:9:end) = errorbarXData(1:9:end) + 0.2;
%     errorbarXData(8:9:end) = errorbarXData(1:9:end) + 0.2;
%     %set(hE_c(2), 'XData', errorbarXData);
%     set(hE, 'XData', errorbarXData);
%
%     %dGrt0 errorbar on top and inside dGrt
%     hE2=errorbar(X1,Y(xi),L(xi),U(xi),'LineStyle','none','LineWidth',2,'DisplayName','forwardReversible','Color','b');
%     % adjust error bar width
%     %hE_c=get(hE2, 'Children');
%     %errorbarXData= get(hE_c(2), 'XData');
%     errorbarXData= get(hE2, 'XData');
%
%     errorbarXData(4:9:end) = errorbarXData(1:9:end) - 0.2;
%     errorbarXData(7:9:end) = errorbarXData(1:9:end) - 0.2;
%     errorbarXData(5:9:end) = errorbarXData(1:9:end) + 0.2;
%     errorbarXData(8:9:end) = errorbarXData(1:9:end) + 0.2;
%     %set(hE_c(2), 'XData', errorbarXData);
%     set(hE2, 'XData', errorbarXData);
%
%
%     %mean dGrt0
% %     plot(X1,Y(xi),'Marker','none','LineStyle','none');
%     plot(X1,Y(xi),'.g','LineStyle','none');
%     %zero line
%     %cumulative probability that reaction is really forward, assuming a
%     %normal distribution about the mean dGt0
%     [AX,H1,H2]=plotyy(X1,zeros(1,length(X1)),X1,P(xi));
%     set(AX(2),'YTick',[0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1]);
%     set(H1,'LineStyle','none')
%     set(H2,'LineStyle','--','Color','k')
%     plot(X1,zeros(1,length(X1)),'k');
%     axis(AX(1),[0 length(X1) min(model.dGtMin(dGfGCforwardReversibleBool_bydGt0)) max(model.dGtMax(dGfGCforwardReversibleBool_bydGt0))])
%     axis(AX(2),[0 length(X1) 0 1])
%     title('Qualitatively forward reactions that are GC quantitatively reversible by range of dGt0');
%     ylabel('dGt0 or dGt(kJ/mol)');
%     xlabel('Reactions, sorted by cumulative probability of being forward');
%
%     %qualitatively forward reactions that are quantitatively reverse by
%     %dGt0
%     fprintf('%i%s\n',nnz(dGfGCforwardReversibleBool_byConcRHS),' qualitatively forward reactions that are GC quantitatively forward by dGf0');
%     X1=1:nnz(dGfGCforwardReversibleBool_byConcRHS);
%     %dGrt0
%     Y=(model.dGt0Min(dGfGCforwardReversibleBool_byConcRHS)+model.dGt0Max(dGfGCforwardReversibleBool_byConcRHS))/2;
%     L=Y-model.dGt0Min(dGfGCforwardReversibleBool_byConcRHS);
%     U=model.dGt0Max(dGfGCforwardReversibleBool_byConcRHS)-Y;
%     %dGrt
%     Y2=(model.dGtMin(dGfGCforwardReversibleBool_byConcRHS)+model.dGtMax(dGfGCforwardReversibleBool_byConcRHS))/2;
%     L2=Y2-model.dGtMin(dGfGCforwardReversibleBool_byConcRHS);
%     U2=model.dGtMax(dGfGCforwardReversibleBool_byConcRHS)-Y2;
%     [tmp,xi]=sort(abs(model.dGt0Max(dGfGCforwardReversibleBool_byConcRHS)-model.dGt0Min(dGfGCforwardReversibleBool_byConcRHS)));
%
%     figure
%     hold on;
%     %dGrt errorbar
%     hE=errorbar(X1,Y2(xi),L2(xi),U2(xi),'LineStyle','none','LineWidth',2,'DisplayName','forwardReversible','Color','r');
%     % adjust error bar width
%     %hE_c=get(hE, 'Children');
%     %errorbarXData= get(hE_c(2), 'XData');
%     errorbarXData= get(hE, 'XData');
%
%     errorbarXData(4:9:end) = errorbarXData(1:9:end) - 0.2;
%     errorbarXData(7:9:end) = errorbarXData(1:9:end) - 0.2;
%     errorbarXData(5:9:end) = errorbarXData(1:9:end) + 0.2;
%     errorbarXData(8:9:end) = errorbarXData(1:9:end) + 0.2;
%     %set(hE_c(2), 'XData', errorbarXData);
%     set(hE, 'XData', errorbarXData);
%
%     %dGrt0 errorbar on top and inside dGrt
%     hE2=errorbar(X1,Y(xi),L(xi),U(xi),'LineStyle','none','LineWidth',2,'DisplayName','forwardReversible','Color','b');
%     % adjust error bar width
%     %hE_c=get(hE2, 'Children');
%     %errorbarXData= get(hE_c(2), 'XData');
%     errorbarXData= get(hE2, 'XData');
%
%     errorbarXData(4:9:end) = errorbarXData(1:9:end) - 0.2;
%     errorbarXData(7:9:end) = errorbarXData(1:9:end) - 0.2;
%     errorbarXData(5:9:end) = errorbarXData(1:9:end) + 0.2;
%     errorbarXData(8:9:end) = errorbarXData(1:9:end) + 0.2;
%     %set(hE_c(2), 'XData', errorbarXData);
%     set(hE2, 'XData', errorbarXData);
%     %mean dGrt0
% %     plot(X1,Y(xi),'Marker','none','LineStyle','none');
%     plot(X1,Y(xi),'.g','LineStyle','none');
%     %zero line
%     plot(X1,zeros(1,length(X1)),'k');
%     title('Qualitatively forward reactions that are GC quantitatively forward by dGf0');
%     ylabel('dGt0 or dGt(kJ/mol)');
%     xlabel('Reactions, sorted by uncertainty in dGt0');


function [ y, j ] = j_borrow_islamic ( y, j )

%*****************************************************************************80
%
%% J_BORROW_ISLAMIC borrows year-days from years in an Islamic date.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    21 June 2012
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input/output, integer Y, J, a YJ date.
%
  while ( j <= 0 )

    y = y - 1;

    days = year_length_islamic ( y );

    j = j + days;

  end

  return
end


function X = naninterp(X)
% Interpolate over NaNs
% See INTERP1 for more info
X(isnan(X)) = interp1(find(~isnan(X)), X(~isnan(X)), find(isnan(X)),'cubic');
return


clear all
cbmex('open');
cbmex('trialconfig',1,'absolute')

samplingFreq = 30000;
eventChannel = 1;
contChannel = 1;
EventLFPs = [];
EventLFPTotal = [];
contRange = -50:50;
pause(0.5);

while size(EventLFPTotal,1) < 500
    [spikeData, procTime, contData] = cbmex('trialdata',1);
    %Example channel to choose for perievent marks
    continuousData = contData{contChannel,3};
    spikeTimes = spikeData{eventChannel,2}- procTime * samplingFreq;

    if ~isempty(spikeTimes)
        eventSpikes = bsxfun(@plus, contRange, double(spikeTimes(1:end-3)));
        EventLFPs = continuousData(eventSpikes);
        EventLFPTotal = [EventLFPTotal; EventLFPs];
        EventLFPTotal = reshape(EventLFPTotal, size(eventSpikes));

    end
%    for i = 1:length(SpikeTimes)

%     	  try
%             EventLFPs(size(EventLFPs,1)+1,:) = ContinuousData(SpikeTimes(i):SpikeTimes(i)+100);
%         catch
%         end
%    end
    pause(0.5);
end
cbmex('close');

plot(mean(EventLFPTotal,1));


function plot_GridPointAnalyse(params,nMode,nPlot)
% Example : plot_GridPointAnalyse(params,0,2)
% function to analyse grid points and plots distribution of rate change
% values
%
% Input
% params    : Input matrix with result
% nMode     : calculate gridpoint from synthetic PSQ (0) or ask for grid
%               point (1)
% nPlot     : plots Z (1), sigma(Z) (2), beta (3), sigma(beta) (4)
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[vIn,vBnd] = inpoly(params.mPolygon,params.mPSQ);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%  controlling inpoly
figure;
plot(params.mPolygon(:,1),params.mPolygon(:,2),'.');
hold on;plot(params.mPSQ(:,1),params.mPSQ(:,2),'r')
hold on;plot(params.mPolygon(vIn,1),params.mPolygon(vIn,2),'ro')
hold on;plot(params.mPolygon(vBnd,1),params.mPolygon(vBnd,2),'ko')
%%

switch nPlot
    case 1
        mPlot=squeeze(params.mResult1(:,1,:));
    case 2
        mPlot=calc_ProbColorbar2Value(squeeze(params.mResult2(:,1,:)));
    case 3
        mPlot=squeeze(params.mResult3(:,1,:));
    case 4
        mPlot=calc_ProbColorbar2Value(squeeze(params.mResult4(:,1,:)));
end

mPlot=mPlot(vIn,:);
mPlot=reshape(mPlot,size(mPlot,1)*size(mPlot,2),1);
figure;
[n,xout] = hist(mPlot(~isinf(mPlot)));
plot(xout,n,'r');


function handles = dtiAdjustDtiXform(handles, refPointName, newCoords, oldCoords)
%  handles = dtiAdjustDtiXform(handles, refPointName, newCoords, [oldCoords])
%
% TO DO:
% Change all coordinate frame transforms so that they are with respect to
% the origin (eg. image center or ac) so that rotations are easier to
% understand!
%
% HISTORY:
%   2004.03.12 RFD (bob@white.stanford.edu) wrote it.

newXform = handles.bg(1).mat;
switch(refPointName)
    case 'ac'
        % FIX THIS! It assumes that the anatomical scale factors are all 1.
        % If we assume that the anatomicals are bg(3), then we can apply
        % that xform to correct this. But maybe there are no anatomicals?
        %handles.bg(3).mat
        %newImgCoords=mrAnatXformCoords(inv(dtiGetStandardXform(handles,handles.bg(1).mat)),newCoords)
        [t,r,s,k] = affineDecompose(newXform);
        if(~exist('oldCoords','var')) oldCoords = t; end
        t = [oldCoords-newCoords];
        newXform = affineBuild(t,r,s,k);
    case 'pc'
        if(~exist('oldCoords','var')) oldCoords = [0 -23 0]; end
        % from the PC, we can compute rotation about Z- and X-axes and the
        % Y-axis scale.
        %[t,r,s,k] = affineDecompose(newXform);
        oldXform = dtiGetStandardXform(handles,handles.bg(1).mat);
        x = [inv(oldXform)*[0,0,0,1; [oldCoords,1]]']'...
            \ [inv(oldXform)*[0,0,0,1; [newCoords,1]]']';
        % set zero scales to 1
        x([(xor(x,eye(4))).*eye(4)]>0) = 1;
        %newXform = newXform*inv(x);
        [t,r,s,k] = affineDecompose(newXform*inv(x));
        % FIX THIS
%         curAcPcDist = sqrt(sum(([0 0 0]-oldCoords).^2));
%         newAcPcDist = sqrt(sum(([0 0 0]-newCoords).^2));
%         scaleDiff = (curAcPcDist-newAcPcDist)./curAcPcDist
%         s(2) = s(2) + scaleDiff;
%         t(2) = t(2) + t(2) .* scaleDiff;
        newXform = affineBuild(t,r,s,k);
    case 'ppc'
        % FIX THIS! We aren't rotating about the proper origin.
        if(~exist('oldCoords','var')) oldCoords = [0 -102 0]; end
        x = [0,0,0,1; [oldCoords,1]] \ [0,0,0,1; [newCoords,1]];
        x([1,11]) = 1;
        [t,r,s,k] = affineDecompose(inv(x)*newXform);
        newXform = affineBuild(t,r,s,k);
    case 'rot'
        [t,r,s,k] = affineDecompose(newXform);
        r = r+newCoords;
        newXform = affineBuild(t,r,s,k);
    case 'scale'
        [t,r,s,k] = affineDecompose(newXform);
        s = s.*newCoords;
        t = t.*newCoords;
        newXform = affineBuild(t,r,s,k);

    otherwise
        error('Unrecognized refpoint name!');
end

% FIX THIS!
handles.bg(1).mat = newXform;
handles.bg(2).mat = newXform;
handles.vec.mat = newXform;

return;


function varargout = erfc(varargin)
%ERFC (overloaded)

switch class(varargin{1})

    case 'double'
        error('Overloaded SDPVAR/ERFC CALLED WITH DOUBLE. Report error')

    case 'sdpvar'
        varargout{1} = InstantiateElementWise(mfilename,varargin{:});

    case 'char'

        operator = struct('convexity','none','monotonicity','decreasing','definiteness','positive','model','callback');
        operator.bounds = @bounds;
        operator.range = [0 2];
        operator.derivative =@(x)-exp(-x.^2)*2/sqrt(pi);
        operator.inverse = @(x)(erfcinv(x));

        varargout{1} = [];
        varargout{2} = operator;
        varargout{3} = varargin{3};

    otherwise
        error('SDPVAR/ERF called with CHAR argument?');
end

function [L,U] = bounds(xL,xU)
L = erfc(xU);
U = erfc(xL);


% This is a test script which demonstrates the usage of the "PhdTrackInitiatorX" class.
% =========================================================================>

% Load the ground truth data
load('multi-target-tracking-1.mat');
GroundTruthStateSequence = GroundTruthStateSequence(~cellfun('isempty',GroundTruthStateSequence));

% Plot settings
ShowPlots = 0;              % Set to 0 to hide plots
numTrueTracks = 3;

% Model parameter shortcuts
lambdaV = 10; % Expected number of clutter measurements over entire surveillance region
V = 5000^2;     % Volume of surveillance region (10x10 2D-grid)
V_bounds = [-2500 2500 -2500 2500]; % [x_min x_max y_min y_max]
P_D = 0.9;    % Probability of detection
timestep_duration = duration(0,0,1);

%% Models
transition_model = ConstantVelocityX('VelocityErrVariance', 5^2,...
                                     'NumDims', 2,...
                                     'TimestepDuration', timestep_duration);
% measurement_model = LinearGaussianX('NumMeasDims', 2,...
%                                     'NumStateDims', 4,...
%                                     'MeasurementErrVariance', 10^2,...
%                                     'Mapping', [1 3]);
% clutter_model = PoissonRateUniformPositionX('ClutterRate',lambdaV,...
%                                             'Limits',[V_bounds(1:2);...
%                                                       V_bounds(3:4)]);
measurement_model = RangeBearing2CartesianX('NumStateDims', 4,...
                                    'MeasurementErrVariance', [(pi/180)^2, 10^2],...
                                    'Mapping', [1 3]);
clutter_model = PoissonRateUniformPositionX('ClutterRate',lambdaV,...
                                            'Limits',[[-pi, pi];...
                                                      [0, 2500]]);
detection_model = ConstantDetectionProbabilityX('DetectionProbability',P_D);

birth_model = DistributionBasedBirthModelX('Distribution', UniformDistributionX([V_bounds(1:2); ...
                                                                                [-10 10 ];...
                                                                                V_bounds(3:4);...
                                                                                [-10 10 ]]),...
                                           'BirthIntensity', 0.0001);

% Compile the State-Space model
model = StateSpaceModelX(transition_model, measurement_model,...
                        'Clutter',clutter_model,...
                        'Detection', detection_model,...
                        'Birth', birth_model);

%% Simulate measurements, based on ground-truth
meas_simulator = MultiTargetMeasurementSimulatorX('Model',model);
DataList = meas_simulator.simulate(GroundTruthStateSequence);
N = numel(DataList);

%% Base Filter
obs_covar= measurement_model.covar();
PriorState = GaussianStateX(zeros(4,1), transition_model.covar() + blkdiag(obs_covar(1,1), 0, obs_covar(2,2),0));
base_filter = UnscentedKalmanFilterX('Model', model, 'StatePrior', PriorState);
% base_filter = ParticleFilterX('Model', model, 'StatePrior', PriorState);

%% Data Associator
config.ClutterModel = clutter_model;
config.DetectionModel = detection_model;
config.Clusterer = NaiveClustererX();
config.Gater = EllipsoidalGaterX(2,'GateLevel',10)';
config.DetectionProbability = P_D;
jpdaf = JointIntegratedProbabilisticDataAssocX(config);

%% Track Initiator

% Initiate Data Associator
config_phd.Model = model;
[priorParticles, priorWeights] = model.Birth.random(50000);
config_phd.StatePrior = ParticleStateX(priorParticles,10*priorWeights);
config_phd.BirthScheme = {'Expansion', 5000};
config_phd.SurvivalProbability = 0.99;

% Instantiate PHD filter
myphd = SMC_PHDFilterX(config_phd);

% Initiate Tag Generator
tag_gen = UuidTagGeneratorX();

% Prepare initiator parameters
config_ti.TagGenerator = tag_gen;
config_ti.InitFilter = base_filter;
config_ti.PhdFilter = myphd;
config_ti.ConfirmThreshold = 0.8;

% Create the track initiator
myti = PhdTrackInitiatorX(config_ti);

%% Track Deleter
config_td = struct('Fieldname', 'ExistenceProbability',...
                   'ReferenceValue', 0.1,...
                   'ReferenceOperand', 'lt');
mytd = FieldBasedDeleterX(config_td);

%% Metric Generators
ospa = OSPAX('CutOffThreshold',100,'Order',2);
gospa = GOSPAX('CutOffThreshold',100,'Order',2);

%% START OF SIMULATION
%  ===================>

% Create figure windows
if(ShowPlots)
    img = imread('maze.png');

    % set the range of the axes
    % The image will be stretched to this.
    min_x = 0;
    max_x = 10;
    min_y = 0;
    max_y = 10;

    % make data to plot - just a line.
    x = min_x:max_x;
    y = (6/8)*x;

    figure('units','normalized','outerposition',[0 0 .5 1])
    ax(1) = gca;
end

TrackList = [];
gospa_vals= zeros(N,4);
timestamp_km1 = DataList(1).Timestamp;
for k=2:N
    fprintf('Iteration = %d/%d\n================>\n',k,N);

    %% Extract DataList at time k
    MeasurementList = DataList(k);
    if(MeasurementList.NumMeasurements == 0)
        continue;
    end
    timestamp_km1 = DataList(k-1).Timestamp;
    timestamp_k = MeasurementList.Timestamp;
    dt = timestamp_k - timestamp_km1;
    transition_model.TimestepDuration = dt;
    fprintf('Timestamp = %s\n================>\n',timestamp_k);

    %% Process JPDAF
    jpdaf.MeasurementList = MeasurementList;
    jpdaf.TrackList = TrackList;
    jpdaf.predictTracks();
    jpdaf.associate(TrackList, MeasurementList);
    jpdaf.updateTracks();

    %% Perform Track initiation
    [TrackList] = myti.initiateTracks(jpdaf.TrackList, MeasurementList, jpdaf.AssocWeightsMatrix);

    %% Perform Track deletion
    TrackList = mytd.deleteTracks(TrackList);

    %% Evaluate metric
    [gospa_vals(k,1), gospa_vals(k,2), gospa_vals(k,3), gospa_vals(k,4)]= ...
        gospa.evaluate(GroundTruthStateSequence{k},jpdaf.TrackList);
    %% Plot update step results
    if(ShowPlots)

        cla(ax(1));
        %imagesc(ax(1),[min_x max_x], [min_y max_y], flipud(img));
        hold on;
        if(exist('data_plot','var'))
            delete(data_plot);
        end
        data_inv = measurement_model.finv(MeasurementList.Vectors);
        data_plot = plot(ax(1), data_inv(1,:), data_inv(3,:),'k*','MarkerSize', 10);

        % Plot confirmed tracks
        for j=1:numel(TrackList)
            means = [TrackList{j}.Trajectory.Mean];
            h2 = plot(ax(1), means(1,:),means(3,:),'-','LineWidth',1);
            h2 = plotgaussellipse(TrackList{j}.Filter.StatePosterior.Mean([1 3]),...
                                  TrackList{j}.Filter.StatePosterior.Covar([1 3],[1 3]),...
                                  'Color','r',...
                                  'Axis',ax(1));
        end

        % set the y-axis back to normal.
        set(ax(1),'ydir','normal');
        str = sprintf('Robot positions (Update)');
        title(ax(1),str)
        xlabel('X position (m)')
        ylabel('Y position (m)')
        axis(ax(1),V_bounds)
        pause(0.01)
    end
end
figure
title("GOSPA");
subplot(2,3,[1 2 3]), plot(1:k,gospa_vals(1:k,1)), title("GOSPA Metric");
subplot(2,3,4), plot(1:k,gospa_vals(1:k,2)), title("GOSPA Localisation");
subplot(2,3,5), plot(1:k,gospa_vals(1:k,3)), title("GOSPA Missed");
subplot(2,3,6), plot(1:k,gospa_vals(1:k,4)), title("GOSPA False");


function [varargout]=faces2elementSideSets(varargin)
% function [elementId,elementSides,elemSets,elemSetSides]=faces2elementSideSets(f,E)
% ------------------------------------------------------------------------
%
% Kevin Mattheus Moerman
% 2020/05/30 Created
% ------------------------------------------------------------------------

%%

switch nargin
    case 2
        f=varargin{1};
        E=varargin{2};
        reorderOpt=0;
    case 3
        f=varargin{1};
        E=varargin{2};
        reorderOpt=varargin{3};
end
%%
logicTouch=sum(ismember(E,f),2)==size(f,2);
ind=(1:1:size(E,1))';
[Fs,C,CF]=element2patch(E(logicTouch,:),ind(logicTouch));
logicMember=isrowmember(Fs,f,reorderOpt);
elementId=C(logicMember);
elementSides=CF(logicMember);
varargout{1}=elementId;
varargout{2}=elementSides;
if nargout>2
    setSideUni=unique(elementSides);
    numSets=numel(setSideUni);
    elemSets=cell(1,numSets);
    elemSetSides=zeros(1,numSets);
    for q=1:1:numSets
        sideType=setSideUni(q);
        logicNow=elementSides==sideType;
        indElem=unique(elementId(logicNow));
        elemSets{q}=indElem(:)';
        elemSetSides(q)=sideType;
    end
    varargout{3}=elemSets;
    varargout{4}=elemSetSides;
end

end
%%
% _*GIBBON footer text*_
%
% License: <https://github.com/gibbonCode/GIBBON/blob/master/LICENSE>
%
% GIBBON: The Geometry and Image-based Bioengineering add-On. A toolbox for
% image segmentation, image-based modeling, meshing, and finite element
% analysis.
%
% Copyright (C) 2006-2022 Kevin Mattheus Moerman and the GIBBON contributors
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program.  If not, see <http://www.gnu.org/licenses/>.


function b=isequal(f, g)
%ISEQUAL Equality test for BALLFUNV.
%   ISEQUAL(F, G) returns 1 then F and G are the same
%   BALLFUNV and 0 otherwise.
%
%   See also ISZERO.

% Copyright 2019 by The University of Oxford and The Chebfun Developers.
% See http://www.chebfun.org/ for Chebfun information.

b = iszero(f-g);
end


function [posR, triR, keeppos] = remove_double_vertices(pos, tri)

% REMOVE_DOUBLE_VERTICES removes double vertices from a triangular mesh
% renumbering the vertex-indices for the triangles and removing all
% triangles with one of the specified vertices.
%
% Use as
%   [pos, tri] = remove_double_vertices(pos, tri)

[pos1,i1,i2] = unique(pos, 'rows');
%keeppos   = find(ismember(pos,pos1,'rows'));
%removepos = setdiff([1:size(pos,1)],keeppos);
keeppos   = i1;
removepos = setdiff(1:size(pos,1), keeppos);

npos = size(pos,1);
ntri = size(tri,1);

if all(removepos==0 | removepos==1)
  removepos = find(removepos);
end

% remove the vertices and determine the new numbering (indices) in numb
keeppos = setdiff(1:npos, removepos);
numb    = zeros(1,npos);
numb(keeppos) = 1:length(keeppos);

% look for triangles referring to removed vertices
removetri = false(ntri,1);
removetri(ismember(tri(:,1), removepos)) = true;
removetri(ismember(tri(:,2), removepos)) = true;
removetri(ismember(tri(:,3), removepos)) = true;

% remove the vertices and triangles
posR = pos(keeppos, :);
triR = tri(~removetri,:);

% renumber the vertex indices for the triangles
triR = numb(triR);


function [params, names] = dnetExtractParam(model)

% DNETEXTRACTPARAM Extract weights and biases from an DNET.
% FORMAT
% DESC returns a vector of all the parameters from a density network.
% ARG model : the model from which we wish to extract the weights
% and biases.
% RETURN params : vector of all the weights and biases returned by
% the model. The structure is governed by dnetpak.
% RETURN names : optional additional returned cell array of the
% names of the parameters.
%
% SEEALSO : dnetCreate, dnetExpandParam, modelExtractParam
%
% COPYRIGHT : Neil D. Lawrence, 2008

% MLTOOLS

if nargout > 1
  [params, names] = modelExtractParam(model.mapping);
  names{end+1} = 'Output Precision';
else
  params = modelExtractParam(model.mapping);
end
func = str2func([model.betaTransform 'Transform']);
params(end+1) = func(model.beta, 'xtoa');


function y = isPalindrome(inputWord)
    % Return 1 if input string is a palindrome; 0 otherwise.

    % Gets the length of the input word.
    inputLength = length(inputWord);

    % Number of pairs to compare.
    lastIndex = floor( inputLength / 2);
    y=1;
    % for every pair of letters in the word check if they match
    for i = 1 : lastIndex
        if inputWord(i) ~= inputWord(end + (1 - i))
            y = 0;
        end
    end

end


function varargout = kdtreebuild(varargin)
% VL_KDTREEBUILD  Build randomized kd-tree
%   FOREST = VL_KDTREEBUILD(X) returns a structure FOREST containing
%   the kd-tree indexing the data X. X is a M x N dimensional matrix
%   of class DOUBLE or SINGLE with one data point per column. Use
%   VL_KDTREEQUERY() to query the index.
%
%   VL_KDETREEBUILD() accepts the following options:
%
%   NumTrees:: [1]
%     Specifies the number of semi-randomized KD-trees to add to the
%     forest. Multiple trees can be used to improve approximate
%     nearest-neighbors searches with VL_KDTREEQUERY().
%
%   ThresholdMethod:: [MEDIAN]
%     Specifies the thresholding method used to split the data.  Two
%     methods are supported: split around the median (MEDIAN) or split
%     around the mean (MEAN).
%
%   Verbose::
%     Increases the verbosity level (can be repeated).
%
%   The FOREST structure has the following fields:
%
%   FOREST.TREES::
%     A structure array with one element per tree.
%
%   FOREST.DIMENSION::
%     Dimensionality of the indexed data.
%
%   FOREST.NUMDATA::
%     Number of indexed data points.
%
%   The TREE structure has the following fields:
%
%   TREE.NODES::
%      A structure array representing the nodes of the tree.
%
%   TREE.DATAINDEX::
%      A 1 x NUMDATA vector of class UINT32 representing a permutation
%      of the data.
%
%   Nodes are numbered from 1 to NUMNODES.  The NODES structure array
%   has the following fields:
%
%   NODES.LOWERCHILD and NODES.UPPERCHILD::
%      1 x NUMNODES vectors of class INT32. A positive value is the
%      index of the lower/upper child node. A negative value denotes a
%      leaf and is (after negation) is the first or last element plus
%      one of a range of entries in the permutation TREE.DATAINDEX.
%      Such entries are in turn indexes of the data points that belong
%      to that leaf. Typically there is one point per leaf.
%
%   NODES.SPLITDIMENSION and NODES.SPLITTHRESHOLD::
%      1 x NUMNODES vector of class UINT32 and DOUBLE, respectively,
%      with the index of the splitting dimension and the threshold for
%      each node.
%
%   See also: VL_KDTREEQUERY(), VL_HELP().
[varargout{1:nargout}] = vl_kdtreebuild(varargin{:});


function out = feval(S, varargin)
%FEVAL   Evaluate the operator of a SPINOP (1, 2 or 3) at a CHEBFUN (1, 2, 3) or
%at a CHEBMATRIX.
%   OUT = FEVAL(S, U) for a CHEBFUN (1, 2, or 3) or CHEBMATRIX U applies S to U.
%
%   OUT = FEVAL(S, U, V, ...) for CHEBFUN'S (1, 2, 3) U, V, ... applies S to
%   the CHEBFUN'S.
%
% See also SPINOPERATOR/SUBSREF.

% Copyright 2017 by The University of Oxford and The Chebfun Developers.
% See http://www.chebfun.org/ for Chebfun information.

L = S.lin;
N = S.nonlin;

% CASE 1: S(U).
if ( nargin == 2 )

    u = varargin{1};

    if ( isa(u, 'chebfun') || isa(u, 'chebfun2') || isa(u, 'chebfun3') )

        out = L(u) + N(u);

    elseif ( isa(u, 'chebmatrix' ) )

        u = u.blocks.';
        out = L(u{:}) + N(u{:});

    end

% CASE 2: S(U,V,...).
else

    out = L(varargin{:}) + N(varargin{:});

end

% Convert to a CHEBMATRIX if it's a CHEBFUN2V or a CHEBFUN3V:
if ( isa(out, 'chebfun2v') || isa(out, 'chebfun3v') )

    u = chebmatrix(out(1));
    for k = 2:size(out, 1)
        u(k,1) = out(k);
    end
    out = u;

end

end


classdef GeneralizedHoughGuil < handle
    %GENERALIZEDHOUGHGUIL  Generalized Hough transform
    %
    % Finds arbitrary template in the grayscale image using
    % Generalized Hough Transform.
    %
    % Detects position, translation and rotation.
    %
    % ## References
    % > Guil, N., Gonzalez-Linares, J.M. and Zapata, E.L. (1999).
    % > Bidimensional shape detection using an invariant approach.
    % > Pattern Recognition 32 (6): 1025-1038.
    %
    % See also: cv.GeneralizedHoughBallard
    %

    properties (SetAccess = private)
        % Object ID
        id
    end

    properties (Dependent)
        % Canny low threshold. default 50
        CannyLowThresh
        % Canny high threshold. default 100
        CannyHighThresh
        % Minimum distance between the centers of the detected objects.
        % default 1.0
        MinDist
        % Inverse ratio of the accumulator resolution to the image resolution.
        % default 1.0
        Dp
        % Maximal size of inner buffers. default 1000
        MaxBufferSize

        % Angle difference in degrees between two points in feature.
        % default 90.0
        Xi
        % Maximal difference between angles that treated as equal. default 1.0
        AngleEpsilon
        % Feature table levels. default 360
        Levels
        % Minimal rotation angle to detect in degrees. default 0.0
        MinAngle
        % Maximal rotation angle to detect in degrees. default 360
        MaxAngle
        % Angle step in degrees. default 1.0
        AngleStep
        % Angle votes threshold. default 15000
        AngleThresh
        % Minimal scale to detect. default 0.5
        MinScale
        % Maximal scale to detect. default 2.0
        MaxScale
        % Scale step. default 0.05
        ScaleStep
        % Scale votes threshold. default 1000
        ScaleThresh
        % Position votes threshold. default 100
        PosThresh
    end

    %% GeneralizedHoughGuil
    methods
        function this = GeneralizedHoughGuil()
            %GENERALIZEDHOUGHGUIL  Constructor
            %
            %     obj = cv.GeneralizedHoughGuil()
            %
            % See also: cv.GeneralizedHoughGuil.detect
            %
            this.id = GeneralizedHoughGuil_(0, 'new');
        end

        function delete(this)
            %DELETE  Destructor
            %
            %     obj.delete()
            %
            % See also: cv.GeneralizedHoughGuil
            %
            if isempty(this.id), return; end
            GeneralizedHoughGuil_(this.id, 'delete');
        end
    end

    %% Algorithm
    methods (Hidden)
        function clear(this)
            %CLEAR  Clears the algorithm state
            %
            %     obj.clear()
            %
            % See also: cv.GeneralizedHoughGuil.empty,
            %  cv.GeneralizedHoughGuil.load
            %
            GeneralizedHoughGuil_(this.id, 'clear');
        end

        function load(this, filename, varargin)
            %LOAD  Loads algorithm from a file or a string
            %
            %     obj.load(fname)
            %     obj.load(str, 'FromString',true)
            %     obj.load(..., 'OptionName',optionValue, ...)
            %
            % ## Input
            % * __fname__ Name of the file to read.
            % * __str__ String containing the serialized model you want to
            %   load.
            %
            % ## Options
            % * __ObjName__ The optional name of the node to read (if empty,
            %   the first top-level node will be used). default empty
            % * __FromString__ Logical flag to indicate whether the input is a
            %   filename or a string containing the serialized model.
            %   default false
            %
            % This method reads algorithm parameters from the specified XML or
            % YAML file (either from disk or serialized string). The previous
            % algorithm state is discarded.
            %
            % See also: cv.GeneralizedHoughGuil.save
            %
            GeneralizedHoughGuil_(this.id, 'load', filename, varargin{:});
        end

        function save(this, filename)
            %SAVE  Saves the algorithm parameters to a file
            %
            %     obj.save(filename)
            %
            % ## Input
            % * __filename__ Name of the file to save to.
            %
            % This method stores the algorithm parameters in the specified
            % XML or YAML file.
            %
            % See also: cv.GeneralizedHoughGuil.load
            %
            GeneralizedHoughGuil_(this.id, 'save', filename);
        end

        function b = empty(this)
            %EMPTY  Returns true if the algorithm is empty
            %
            %     b = obj.empty()
            %
            % ## Output
            % * __b__ Returns true if the object is empty (e.g in the
            %   very beginning or after unsuccessful read).
            %
            % See also: cv.GeneralizedHoughGuil.clear,
            %  cv.GeneralizedHoughGuil.load
            %
            b = GeneralizedHoughGuil_(this.id, 'empty');
        end

        function name = getDefaultName(this)
            %GETDEFAULTNAME  Returns the algorithm string identifier
            %
            %     name = obj.getDefaultName()
            %
            % ## Output
            % * __name__ This string is used as top level XML/YML node tag
            %   when the object is saved to a file or string.
            %
            % See also: cv.GeneralizedHoughGuil.save,
            %  cv.GeneralizedHoughGuil.load
            %
            name = GeneralizedHoughGuil_(this.id, 'getDefaultName');
        end
    end

    %% GeneralizedHough
    methods
        function [positions,votes] = detect(this, varargin)
            %DETECT  Find template on image
            %
            %     [positions,votes] = hough.detect(image)
            %     [positions,votes] = hough.detect(edges, dx, dy)
            %
            % ## Input
            % * __image__ input image, 8-bit 1-channel image
            % * __edges__ image edges
            % * __dx__ image x-derivative of the same size as `edges` and
            %   single-precision floating type.
            % * __dy__ image y-derivate of the same size and type as `dx`.
            %
            % ## Output
            % * __positions__ Cell array of 4-element vectors, each of the
            %   form: `[posx, posy, scale, angle]`
            % * __votes__ Cell array of 3-element vectors, of the same length
            %   as `positions`.
            %
            [positions,votes] = GeneralizedHoughGuil_(this.id, 'detect', varargin{:});
        end

        function setTemplate(this, varargin)
            %SETTEMPLATE  Set template to search
            %
            %     hough.setTemplate(templ)
            %     hough.setTemplate(edges, dx, dy)
            %     hough.setTemplate(..., 'OptionName', optionValue, ...)
            %
            % ## Input
            % * __templ__ template, 8-bit 1-channel image
            % * __edges__ template edges
            % * __dx__ template x-derivative of the same size as `edges` and
            %   single-precision floating type.
            % * __dy__ template y-derivate of the same size and type as `dx`.
            %
            % ## Options
            % * __Center__ Template center `[x,y]`. The default `[-1,-1]`
            %   will use `[size(templ,2) size(templ,1)]./2` as center.
            %
            % In the first variant of the function (with the `templ` input),
            % the `edges` are internally calculated using the cv.Canny filter,
            % and the derivatives `dx` and `dy` using cv.Sobel operator.
            %
            GeneralizedHoughGuil_(this.id, 'setTemplate', varargin{:});
        end
    end

    %% Getters/Setters
    methods
        function value = get.CannyHighThresh(this)
            value = GeneralizedHoughGuil_(this.id, 'get', 'CannyHighThresh');
        end
        function set.CannyHighThresh(this, value)
            GeneralizedHoughGuil_(this.id, 'set', 'CannyHighThresh', value);
        end

        function value = get.CannyLowThresh(this)
            value = GeneralizedHoughGuil_(this.id, 'get', 'CannyLowThresh');
        end
        function set.CannyLowThresh(this, value)
            GeneralizedHoughGuil_(this.id, 'set', 'CannyLowThresh', value);
        end

        function value = get.Dp(this)
            value = GeneralizedHoughGuil_(this.id, 'get', 'Dp');
        end
        function set.Dp(this, value)
            GeneralizedHoughGuil_(this.id, 'set', 'Dp', value);
        end

        function value = get.MaxBufferSize(this)
            value = GeneralizedHoughGuil_(this.id, 'get', 'MaxBufferSize');
        end
        function set.MaxBufferSize(this, value)
            GeneralizedHoughGuil_(this.id, 'set', 'MaxBufferSize', value);
        end

        function value = get.MinDist(this)
            value = GeneralizedHoughGuil_(this.id, 'get', 'MinDist');
        end
        function set.MinDist(this, value)
            GeneralizedHoughGuil_(this.id, 'set', 'MinDist', value);
        end

        function value = get.AngleEpsilon(this)
            value = GeneralizedHoughGuil_(this.id, 'get', 'AngleEpsilon');
        end
        function set.AngleEpsilon(this, value)
            GeneralizedHoughGuil_(this.id, 'set', 'AngleEpsilon', value);
        end

        function value = get.AngleStep(this)
            value = GeneralizedHoughGuil_(this.id, 'get', 'AngleStep');
        end
        function set.AngleStep(this, value)
            GeneralizedHoughGuil_(this.id, 'set', 'AngleStep', value);
        end

        function value = get.AngleThresh(this)
            value = GeneralizedHoughGuil_(this.id, 'get', 'AngleThresh');
        end
        function set.AngleThresh(this, value)
            GeneralizedHoughGuil_(this.id, 'set', 'AngleThresh', value);
        end

        function value = get.Levels(this)
            value = GeneralizedHoughGuil_(this.id, 'get', 'Levels');
        end
        function set.Levels(this, value)
            GeneralizedHoughGuil_(this.id, 'set', 'Levels', value);
        end

        function value = get.MaxAngle(this)
            value = GeneralizedHoughGuil_(this.id, 'get', 'MaxAngle');
        end
        function set.MaxAngle(this, value)
            GeneralizedHoughGuil_(this.id, 'set', 'MaxAngle', value);
        end

        function value = get.MaxScale(this)
            value = GeneralizedHoughGuil_(this.id, 'get', 'MaxScale');
        end
        function set.MaxScale(this, value)
            GeneralizedHoughGuil_(this.id, 'set', 'MaxScale', value);
        end

        function value = get.MinAngle(this)
            value = GeneralizedHoughGuil_(this.id, 'get', 'MinAngle');
        end
        function set.MinAngle(this, value)
            GeneralizedHoughGuil_(this.id, 'set', 'MinAngle', value);
        end

        function value = get.MinScale(this)
            value = GeneralizedHoughGuil_(this.id, 'get', 'MinScale');
        end
        function set.MinScale(this, value)
            GeneralizedHoughGuil_(this.id, 'set', 'MinScale', value);
        end

        function value = get.PosThresh(this)
            value = GeneralizedHoughGuil_(this.id, 'get', 'PosThresh');
        end
        function set.PosThresh(this, value)
            GeneralizedHoughGuil_(this.id, 'set', 'PosThresh', value);
        end

        function value = get.ScaleStep(this)
            value = GeneralizedHoughGuil_(this.id, 'get', 'ScaleStep');
        end
        function set.ScaleStep(this, value)
            GeneralizedHoughGuil_(this.id, 'set', 'ScaleStep', value);
        end

        function value = get.ScaleThresh(this)
            value = GeneralizedHoughGuil_(this.id, 'get', 'ScaleThresh');
        end
        function set.ScaleThresh(this, value)
            GeneralizedHoughGuil_(this.id, 'set', 'ScaleThresh', value);
        end

        function value = get.Xi(this)
            value = GeneralizedHoughGuil_(this.id, 'get', 'Xi');
        end
        function set.Xi(this, value)
            GeneralizedHoughGuil_(this.id, 'set', 'Xi', value);
        end
    end

end


function [fo, ip] = func_excludeoutlier_cor( fi, g, g_s );
%======================================================================
%
% Version 1.0
%
% This program excludes the points which below g_s of g
%
% Input
%   fi : input x data
%
% Output
%   fo : excluded x data
%   ip : excluded array element number in xi and yi
%
% Example:
%   [fo, ip] = func_excludeoutlier_cor( fi, g, g_s );
%
%
%======================================================================
% Terms:
%
%       Distributed under the terms of the terms of the BSD License
%
% Copyright:
%
%       Nobuhito Mori, Kyoto University
%
%========================================================================
%
% Update:
%       1.00    2005/01/12 Nobuhito Mori
%
%========================================================================

n = max(size(fi));
fo = [];
ip = find(g<g_s);
%fo = fi(find(g>=g_s));
fo =fi;
fo(ip) = NaN;


function [xpos, u] = firstzero(s)

%tstoolbox/@signal/firstzero
%   Syntax:
%     * [xpos, unit] = firstzero(s)
%
%   Give information about first zero of scalar signal s, using linear
%   interpolation.
%
% Copyright 1997-2001 DPI Goettingen, License http://www.physik3.gwdg.de/tstool/gpl.txt
narginchk(1,1);

if ndim(s) ~= 1
	help(mfilename)
	return
end

d = data(s);
ze = find(d==0);
if isempty(ze)		% no exact zero found, looking for zero crossings
	tmp = d(2:end) .* d(1:end-1);
	ze = find(tmp < 0);
	if isempty(ze)
		error('no zero crossing found')
	else
		A = getaxis(s, 1);
		a = abs(d(ze(1)));
		b = abs(d(ze(1)+1));
		if (a+b) > 0
			xpos = first(A) + (ze(1)-1 + a/(a+b) )*delta(A);
		else
			xpos = first(A) + (ze(1)-1)*delta(A);
		end
		u = unit(A);
	% 	disp(['first zero/zero crossing at x = ' num2str(xpos) ' ' label(A)]);
	end
else		% use first sample that matches zero exactly
	A = getaxis(s, 1);
	xpos = first(A) + (ze(1)-1)*delta(A);
	u = unit(A);
end


classdef m_47_IHM19_16p_4s < MARRMoT_model
% Class for hydrologic conceptual model: Forellenbach model

% Copyright (C) 2021 Clara Brandes, Luca Trotter
% This file is part of the Modular Assessment of Rainfall-Runoff Models
% Toolbox (MARRMoT).
% MARRMoT is a free software (GNU GPL v3) and distributed WITHOUT ANY
% WARRANTY. See <https://www.gnu.org/licenses/> for details.
%
% Model reference
% Brandes, C. (2020). Erstellung eines Konzeptionellen
% Hochwasserabfluss-modells für das Einzugsgebiet des Forellenbachs, NP
% Bayerischer Wald. MSc Thesis. Technische Univerisität Dresden, Germany.

    properties
        % model-specific attributes
    end
    methods

        % creator method
        function obj = m_47_IHM19_16p_4s()
            obj.numStores = 4;                                             % number of model stores
            obj.numFluxes = 18;                                            % number of model fluxes
            obj.numParams = 16;

            obj.JacobPattern  = [1,0,0,0;
                                 1,1,0,0;
                                 1,1,1,0;
                                 0,1,1,1];                                 % Jacobian matrix of model store ODEs

            obj.parRanges = [   2,     5;      % 01 SIMAX, maximum interception storage [mm]
                                0.9,   1;      % 02 A, splitting coeffcient for excess precipitation [-]
                                0.4,   0.95;   % 03 FF, forest fraction [-]
                                0.05,  5;      % 04 SMPMAX, maximum storage macropores [mm]
                                0,     1;      % 05 CQMP, runoff time parameter (fast/slow runnoff) first soil layer [1/d]
                                1,     5;      % 06 XQMP, runoff scale parameter first soil layer [-]
                              400,   600;      % 07 SS1MAX, maximum soil moisture storage first soil layer [mm]
                                0.3,   0.7;    % 08 FCCS1, field capacity as fraction of maximum storage first soil layer [-]
                                0,  1000;      % 09 CFS1, maximum infiltration rate first soil layer [mm/d]
                                0,    15;      % 10 XFS1, infiltration loss exponent first soil layer [-]
                                0,     1;      % 11 CQS1, runoff time parameter for (fast/slow runnoff) first soil layer [1/d]
                                1,     5;      % 12 XQS1, runoff scale parameter first soil layer [-]
                              300,   500;      % 13 SS2MAX, maximum soil moisture storage second soil layer [mm]
                                0,     1;      % 14 CQS2, runoff time parameter for (fast/slow runnoff) second soil layer [1/d]
                                1,     5;      % 15 XQS2, runoff scale parameter second soil layer [-]
                                0.01,  5];     % 16 D, Flow delay before surface runoff [d]

            obj.StoreNames = {"S1", "S2" "S3" "S4"};                        % Names for the stores
            obj.FluxNames  = {"ei",    "pex", "pexmp",  "pexs1", "fmp",...
                              "qexmp", "qmp", "pqexsl", "fs1",   "etas1",...
                              "qs1",   "q0",  "q0r",    "qmps1", "pc",...
                              "qh",    "qs2", "qgw"};                      % Names for the fluxes

            obj.FluxGroups.Ea = [1 10];                                    % Index or indices of fluxes to add to Actual ET
            obj.FluxGroups.Q  = [13 16 17 18];                             % Index or indices of fluxes to add to Streamflow
            obj.FluxGroups.GW = -18;                                       % Index of GW runoff flow.

        end

        % INITialisation function
        function obj = init(obj)
            % parameters
            theta   = obj.theta;
            delta_t = obj.delta_t;
            SIMAX   = theta(1);                         % maximum interception storage [mm]
            SMPMAX  = theta(4);                         % maximum storage macropores [mm]
            SS1MAX  = theta(7);                         % maximum soil moisture storage first soil layer [mm]
            SS2MAX  = theta(13);                        % maximum soil moisture storage second soil layer [mm]
            D       = theta(16);                        % Flow delay before surface runoff [d]

            % initial store values
            obj.S0 = 0.8 * [SIMAX;                   % Initial interception storage
                            SMPMAX;                  % Initial macropore storage
                            SS1MAX;                  % Initial soil moisture storage 1
                            SS2MAX];                 % Initial soil moisture storage 2

            % initialise the unit hydrographs and still-to-flow vectors
            uh_q0r = uh_4_full(D,delta_t);

            obj.uhs = {uh_q0r};
        end

        % MODEL_FUN are the model governing equations in state-space formulation
        function [dS, fluxes] = model_fun(obj, S)
            % parameters
            theta   = obj.theta;
            SIMAX   = theta(1);                         % maximum interception storage [mm]
            A       = theta(2);                         % splitting coeffcient for excess precipitation [-]
            FF      = theta(3);                         % forest fraction [-]
            SMPMAX  = theta(4);                         % maximum storage macropores [mm]
            CQMP    = theta(5);                         % runoff time parameter (fast/slow runnoff) first soil layer [1/d]
            XQMP    = theta(6);                         % runoff scale parameter first soil layer [-]
            SS1MAX  = theta(7);                         % maximum soil moisture storage first soil layer [mm]
            FCCS1   = theta(8);                         % field capacity coefficient fist soil layer [-]
            CFS1    = theta(9);                         % maximum infiltration rate first soil layer [-]
            XFS1    = theta(10);                        % infiltration loss exponent first soil layer [-]
            CQS1    = theta(11);                        % runoff time parameter for (fast/slow runnoff) first soil layer [1/d]
            XQS1    = theta(12);                        % runoff scale parameter first soil layer [-]
            SS2MAX  = theta(13);                        % maximum soil moisture storage second soil layer [mm]
            CQS2    = theta(14);                        % runoff time parameter for (fast/slow runnoff) second soil layer [1/d]
            XQS2    = theta(15);                        % runoff scale parameter second soil layer [-]

            % delta_t
            delta_t = obj.delta_t;

            % unit hydrographs and still-to-flow vectors
            uhs = obj.uhs;
            uh_q0r = uhs{1};

            % stores
            S1 = S(1);
            S2 = S(2);
            S3 = S(3);
            S4 = S(4);

            % climate input
            t = obj.t;                             % this time step
            climate_in = obj.input_climate(t,:);   % climate at this step
            P  = climate_in(1);
            Ep = climate_in(2);
            T  = climate_in(3);

            % fluxes functions
            flux_ei      = evap_1(S1,Ep,delta_t);
            flux_pex     = interception_1(P,S1,SIMAX);
            flux_pexmp   = split_1(A,flux_pex);
            flux_pexs1   = split_2(A,flux_pex);
            flux_fmp     = infiltration_3(flux_pexmp,S2,SMPMAX);
            flux_qexmp   = flux_pexmp - flux_fmp;
            flux_qmp     = interflow_3(CQMP,XQMP,S2,delta_t);
            flux_pqexs1  = flux_pexs1 + flux_qexmp;
            flux_fs1     = infiltration_7(CFS1,XFS1,S3,SS1MAX,flux_pqexs1);
            flux_etas1   = evap_23(FF,FCCS1,S3,SS1MAX,Ep,delta_t);
            flux_qs1     = interflow_9(S3,CQS1,FCCS1*SS1MAX,XQS1,delta_t);
            flux_q0      = flux_pqexs1 - flux_fs1;
            flux_q0r     = route(flux_q0, uh_q0r);
            flux_qmps1   = flux_qmp + flux_qs1;
            flux_pc      = infiltration_3(flux_qmps1,S4,SS2MAX);
            flux_qh      = flux_qmps1 - flux_pc;
            flux_qs2     = interflow_3(CQS2,XQS2,S4,delta_t);
            flux_qgw     = 0.0195;

            % stores ODEs
            dS1 = P - flux_ei - flux_pex;
            dS2 = flux_fmp - flux_qmp;
            dS3 = flux_fs1 - flux_etas1 - flux_qs1;
            dS4 = flux_pc - flux_qs2;

            % outputs
            dS = [dS1 dS2 dS3 dS4];
            fluxes = [flux_ei, flux_pex, flux_pexmp, flux_pexs1,...
                      flux_fmp, flux_qexmp, flux_qmp, flux_pqexs1,...
                      flux_fs1, flux_etas1, flux_qs1, flux_q0,...
                      flux_q0r, flux_qmps1, flux_pc , flux_qh,...
                      flux_qs2, flux_qgw];
        end

        % STEP runs at the end of every timestep.
        function obj = step(obj)
            % unit hydrographs and still-to-flow vectors
            uhs = obj.uhs;
            uh_q0r = uhs{1};

            % input fluxes to the unit hydrographs
            fluxes = obj.fluxes(obj.t,:);
            flux_q0   = fluxes(12);

            % update still-to-flow vectors using fluxes at current step and
            % unit hydrographs
            uh_q0r = update_uh(uh_q0r, flux_q0);
            obj.uhs = {uh_q0r};
        end
    end
end