QT Interval Measurement: The PhysioNet/Computing in Cardiology Challenge 2006 1.0.0

function [T_off T_error] = find_T_off(Tecg, maxT, maxT2, maxT2_rel,zaporne_T)

T_error=0;

%Computations of gradients
gradient2 = zeros(1,length(Tecg)-10); gradient4 = zeros(1,length(Tecg)-10); gradient6 = zeros(1,length(Tecg)-10);
gradient8 = zeros(1,length(Tecg)-10); gradient10 = zeros(1,length(Tecg)-10);
for i = 1:(length(Tecg)-21),
    gradient2(i) = (Tecg(i+2) - Tecg(i));
    gradient4(i) = (Tecg(i+4) - Tecg(i));
    gradient6(i) = (Tecg(i+6) - Tecg(i));
    gradient8(i) = (Tecg(i+8) - Tecg(i));
    gradient10(i) = (Tecg(i+10) - Tecg(i));
end

[unused1 posNejvetsi_gradient2] = max(gradient2);
[unused2 posNejvetsi_gradient4] = max(gradient4);
[unused3 posNejvetsi_gradient6] = max(gradient6);
[unused4 posNejvetsi_gradient8] = max(gradient8);
[unused5 posNejvetsi_gradient10] = max(gradient10);

pocet_minim_Ton2 = 1; pocet_minim_Ton4 = 1; pocet_minim_Ton6 = 1; pocet_minim_Ton8 = 1; pocet_minim_Ton10 = 1;
for i = 2:length(gradient2),
    if zaporne_T==0,
        if (((gradient2(i-1)<0)&&(gradient2(i+1)>0))||((gradient2(i-1)<0)&&(abs(gradient2(i+1))<abs(mean(gradient2(1:11))/5))))
            posT_on_minima2(pocet_minim_Ton2) = i;
            pocet_minim_Ton2 = pocet_minim_Ton2 + 1;
        end
        if ((gradient4(i-1)<0)&&(gradient4(i+1)>0))||((gradient2(i-1)<0)&&(abs(gradient4(i+1))<abs(mean(gradient4(1:11))/5)))
            posT_on_minima4(pocet_minim_Ton4)= i;
            pocet_minim_Ton4 = pocet_minim_Ton4 + 1;
        end
        if ((gradient6(i-1)<0)&&(gradient6(i)>0))||((gradient2(i-1)<0)&&(abs(gradient6(i+1))<abs(mean(gradient6(1:11))/5)))
            posT_on_minima6(pocet_minim_Ton6) = i;
            pocet_minim_Ton6 = pocet_minim_Ton6 + 1;
        end
        if ((gradient8(i-1)<0)&&(gradient8(i)>0))||((gradient2(i-1)<0)&&(abs(gradient8(i+1))<abs(mean(gradient8(1:11))/5)))
            posT_on_minima8(pocet_minim_Ton8) = i;
            pocet_minim_Ton8 = pocet_minim_Ton8 + 1;
        end
        if ((gradient10(i-1)<0)&&(gradient10(i)>0))||((gradient2(i-1)<0)&&(abs(gradient10(i+1))<abs(mean(gradient10(1:11))/5)))
            posT_on_minima10(pocet_minim_Ton10) = i;
            pocet_minim_Ton10 = pocet_minim_Ton10 + 1;
        end
    else
        if (i<maxT2_rel)||(maxT==maxT2),
            if ((gradient2(i-1)<0)&&(gradient2(i+1)>0))||((gradient2(i-1)>0)&&(abs(gradient2(i+1))<abs(mean(gradient2(1:11))/4)))
                posT_on_minima2(pocet_minim_Ton2) = i;
                pocet_minim_Ton2 = pocet_minim_Ton2 + 1;
            end
            if ((gradient4(i-1)<0)&&(gradient4(i+1)>0))||((gradient2(i-1)>0)&&(abs(gradient4(i+1))<abs(mean(gradient4(1:11))/4)))
                posT_on_minima4(pocet_minim_Ton4)= i;
                pocet_minim_Ton4 = pocet_minim_Ton4 + 1;
            end
            if ((gradient6(i-1)<0)&&(gradient6(i)>0))||((gradient2(i-1)>0)&&(abs(gradient6(i+1))<abs(mean(gradient6(1:11))/4)))
                posT_on_minima6(pocet_minim_Ton6) = i;
                pocet_minim_Ton6 = pocet_minim_Ton6 + 1;
            end
            if ((gradient8(i-1)<0)&&(gradient8(i)>0))||((gradient2(i-1)>0)&&(abs(gradient8(i+1))<abs(mean(gradient8(1:11))/4)))
                posT_on_minima8(pocet_minim_Ton8) = i;
                pocet_minim_Ton8 = pocet_minim_Ton8 + 1;
            end
            if ((gradient10(i-1)<0)&&(gradient10(i)>0))||((gradient2(i-1)>0)&&(abs(gradient10(i+1))<abs(mean(gradient10(1:11))/4)))
                posT_on_minima10(pocet_minim_Ton10) = i;
                pocet_minim_Ton10 = pocet_minim_Ton10 + 1;
            end
        else
            if (((gradient2(i-1)<0)&&(gradient2(i+1)>0))||((gradient2(i-1)<0)&&(abs(gradient2(i+1))<abs(mean(gradient2(1:11))/5))))
                posT_on_minima2(pocet_minim_Ton2) = i;
                pocet_minim_Ton2 = pocet_minim_Ton2 + 1;
            end
            if ((gradient4(i-1)<0)&&(gradient4(i+1)>0))||((gradient2(i-1)<0)&&(abs(gradient4(i+1))<abs(mean(gradient4(1:11))/5)))
                posT_on_minima4(pocet_minim_Ton4)= i;
                pocet_minim_Ton4 = pocet_minim_Ton4 + 1;
            end
            if ((gradient6(i-1)<0)&&(gradient6(i)>0))||((gradient2(i-1)<0)&&(abs(gradient6(i+1))<abs(mean(gradient6(1:11))/5)))
                posT_on_minima6(pocet_minim_Ton6) = i;
                pocet_minim_Ton6 = pocet_minim_Ton6 + 1;
            end
            if ((gradient8(i-1)<0)&&(gradient8(i)>0))||((gradient2(i-1)<0)&&(abs(gradient8(i+1))<abs(mean(gradient8(1:11))/5)))
                posT_on_minima8(pocet_minim_Ton8) = i;
                pocet_minim_Ton8 = pocet_minim_Ton8 + 1;
            end
            if ((gradient10(i-1)<0)&&(gradient10(i)>0))||((gradient2(i-1)<0)&&(abs(gradient10(i+1))<abs(mean(gradient10(1:11))/5)))
                posT_on_minima10(pocet_minim_Ton10) = i;
                pocet_minim_Ton10 = pocet_minim_Ton10 + 1;
            end
        end
    end
end

if ~exist('posT_on_minima2','var'),
    posT_on_minima2 = 1;
end
if ~exist('posT_on_minima4','var'),
    posT_on_minima4 = 1;
end
if ~exist('posT_on_minima6','var'),
    posT_on_minima6 = 1;
end
if ~exist('posT_on_minima8','var'),
    posT_on_minima8 = 1;
end
if ~exist('posT_on_minima10','var'),
    posT_on_minima10 = 1;
end

[pocet_minim_Ton nejvice_minim_z_gradientu] = max([length(posT_on_minima2),length(posT_on_minima4),length(posT_on_minima6),length(posT_on_minima8),length(posT_on_minima10)]);
offset_min = 4; byl_jsem_tu = 0; global_min = 0;
if pocet_minim_Ton>1,
    switch nejvice_minim_z_gradientu,
        case 1,
            for i = 1:length(posT_on_minima2),
                if (posT_on_minima2(i) > maxT2_rel+10),
                    fired_at_least = 0;
                    if pocet_minim_Ton4>1,
                        if (find((posT_on_minima4<posT_on_minima2(i)+offset_min)&(posT_on_minima4>posT_on_minima2(i)-offset_min))),
                            fired_at_least = fired_at_least + 1;
                        end
                    end
                    if pocet_minim_Ton6>1,
                        if (find((posT_on_minima6<posT_on_minima2(i)+offset_min)&(posT_on_minima6>posT_on_minima2(i)-offset_min))),
                            fired_at_least = fired_at_least + 1;
                        end
                    end
                    if pocet_minim_Ton8>1,
                        if (find((posT_on_minima8<posT_on_minima2(i)+offset_min)&(posT_on_minima8>posT_on_minima2(i)-offset_min))),
                            fired_at_least = fired_at_least + 1;
                        end
                    end
                    if pocet_minim_Ton10>1,
                        if (find((posT_on_minima10<posT_on_minima2(i)+offset_min)&(posT_on_minima10>posT_on_minima2(i)-offset_min))),
                            fired_at_least = fired_at_least + 1;
                        end
                    end

                    if ((fired_at_least > 3)&&(byl_jsem_tu == 0)),
                        T_off = posT_on_minima2(i);
                        byl_jsem_tu = 1;
                    end
                end
            end
        case 2,
            for i = 1:length(posT_on_minima4),
                if (posT_on_minima4(i) > maxT2_rel+10),
                    fired_at_least = 0;
                    if pocet_minim_Ton2>1,
                        if (find((posT_on_minima2<posT_on_minima4(i)+offset_min)&(posT_on_minima2>posT_on_minima4(i)-offset_min))),
                            fired_at_least = fired_at_least + 1;
                        end
                    end
                    if pocet_minim_Ton6>1,
                        if (find((posT_on_minima6<posT_on_minima4(i)+offset_min)&(posT_on_minima6>posT_on_minima4(i)-offset_min))),
                            fired_at_least = fired_at_least + 1;
                        end
                    end
                    if pocet_minim_Ton8>1,
                        if (find((posT_on_minima8<posT_on_minima4(i)+offset_min)&(posT_on_minima8>posT_on_minima4(i)-offset_min))),
                            fired_at_least = fired_at_least + 1;
                        end
                    end
                    if pocet_minim_Ton10>1,
                        if (find((posT_on_minima10<posT_on_minima4(i)+offset_min)&(posT_on_minima10>posT_on_minima4(i)-offset_min))),
                            fired_at_least = fired_at_least + 1;
                        end
                    end
                    if ((fired_at_least > 3)&&(byl_jsem_tu == 0)),
                        T_off = posT_on_minima4(i);
                        byl_jsem_tu = 1;
                    end
                end
            end
        case 3,
            for i = 1:length(posT_on_minima6),
                if (posT_on_minima6(i) > maxT2_rel+10),
                    fired_at_least = 0;
                    if pocet_minim_Ton4>1,
                        if (find((posT_on_minima4<posT_on_minima6(i)+offset_min)&(posT_on_minima4>posT_on_minima6(i)-offset_min))),
                            fired_at_least = fired_at_least + 1;
                        end
                    end
                    if pocet_minim_Ton2>1,
                        if (find((posT_on_minima2<posT_on_minima6(i)+offset_min)&(posT_on_minima2>posT_on_minima6(i)-offset_min))),
                            fired_at_least = fired_at_least + 1;
                        end
                    end
                    if pocet_minim_Ton8>1,
                        if (find((posT_on_minima8<posT_on_minima6(i)+offset_min)&(posT_on_minima8>posT_on_minima6(i)-offset_min))),
                            fired_at_least = fired_at_least + 1;
                        end
                    end
                    if pocet_minim_Ton10>1,
                        if (find((posT_on_minima10<posT_on_minima6(i)+offset_min)&(posT_on_minima10>posT_on_minima6(i)-offset_min))),
                            fired_at_least = fired_at_least + 1;
                        end
                    end
                    if ((fired_at_least >= 3)&&(byl_jsem_tu == 0)),
                        T_off = posT_on_minima6(i);
                        byl_jsem_tu = 1;
                    end
                end
            end
        case 4,
            for i = 1:length(posT_on_minima8),
                if (posT_on_minima8(i) > maxT2_rel+10),
                    fired_at_least = 0;
                    if pocet_minim_Ton4>1,
                        if (find((posT_on_minima4<posT_on_minima8(i)+offset_min)&(posT_on_minima4>posT_on_minima8(i)-offset_min))),
                            fired_at_least = fired_at_least + 1;
                        end
                    end
                    if pocet_minim_Ton6>1,
                        if (find((posT_on_minima6<posT_on_minima8(i)+offset_min)&(posT_on_minima6>posT_on_minima8(i)-offset_min))),
                            fired_at_least = fired_at_least + 1;
                        end
                    end
                    if pocet_minim_Ton2>1,
                        if (find((posT_on_minima2<posT_on_minima8(i)+offset_min)&(posT_on_minima2>posT_on_minima8(i)-offset_min))),
                            fired_at_least = fired_at_least + 1;
                        end
                    end
                    if pocet_minim_Ton10>1,
                        if (find((posT_on_minima10<posT_on_minima8(i)+offset_min)&(posT_on_minima10>posT_on_minima8(i)-offset_min))),
                            fired_at_least = fired_at_least + 1;
                        end
                    end
                    if ((fired_at_least >= 3)&&(byl_jsem_tu == 0)),
                        T_off = posT_on_minima8(i);
                        byl_jsem_tu = 1;
                    end
                end
            end
        case 5,
            for i = 1:length(posT_on_minima10),
                if (posT_on_minima10(i) > maxT2_rel+10),
                    fired_at_least = 0;
                    if pocet_minim_Ton4>1,
                        if (find((posT_on_minima4<posT_on_minima10(i)+offset_min)&(posT_on_minima4>posT_on_minima10(i)-offset_min))),
                            fired_at_least = fired_at_least + 1;
                        end
                    end
                    if pocet_minim_Ton6>1,
                        if (find((posT_on_minima6<posT_on_minima10(i)+offset_min)&(posT_on_minima6>posT_on_minima10(i)-offset_min))),
                            fired_at_least = fired_at_least + 1;
                        end
                    end
                    if pocet_minim_Ton8>1,
                        if (find((posT_on_minima8<posT_on_minima10(i)+offset_min)&(posT_on_minima8>posT_on_minima10(i)-offset_min))),
                            fired_at_least = fired_at_least + 1;
                        end
                    end
                    if pocet_minim_Ton2>1,
                        if (find((posT_on_minima2<posT_on_minima10(i)+offset_min)&(posT_on_minima2>posT_on_minima10(i)-offset_min))),
                            fired_at_least = fired_at_least + 1;
                        end
                    end
                    if ((fired_at_least >= 3)&&(byl_jsem_tu == 0)),
                        T_off = posT_on_minima10(i);
                        byl_jsem_tu = 1;
                    end
                end
            end
    end
end

if ~exist('T_off','var');
    disp('T-off was not found in find_T_off...')
    T_off = length(Tecg);
    T_error = 1;
end