function [pred_class,signal_proc,ns_info,hf_samp,m_arr1,swd_p] = noise_label(signal,sig_len,Fs)

    if(nargin < 3)
        Fs = 250;
    end
    
    if(nargin < 2)
        sig_len = length(signal);
    end
    
    load('hfMdl_RF.mat')
    load('nsMdl_RF.mat')
    
    signal_cl = clean_ecg(signal,Fs);
        
    signal_pad = power2pad(signal_cl,11);
    swd_clean = swt(signal_pad,11,'db5');
   
    swd_clean(1:2,:) = 0;
    swd_clean(8:end,:) = 0;
        
    signal_proc = iswt(swd_clean,'db5');
    signal_proc = signal_proc(1:sig_len);
    
    signal_cl1 = iqr_norm(signal_cl);
    
    sig_len = length(signal_cl1);
    signal_pad = power2pad(signal_cl1,11);
    [~,swd4] = swt(signal_pad,11,'db4');
    
    [swd_p,swd_max] = iqr_norm(swd4(3,1:sig_len),0.5);

    if(swd_max < 0.6)
        lim = 0.2;
    else
        lim = 0.16;
    end
    
    [~,locs1] = findpeaks(swd_p,'Minpeakheight',0.01,'Minpeakdistance',2);
    [~,locs2] = findpeaks((-1)*swd_p,'Minpeakheight',0.01,'Minpeakdistance',2);
    locs_all = union(locs1,locs2);
    
    pks_all = swd_p(locs_all);
    pks_abs = abs(pks_all);
           
    pksd = discretize(pks_abs,[0 lim 0.38 1.1]);
    
    seg_len = 2*Fs;
    no_seg = floor(sig_len/seg_len);
    
    m_arr1 = [];
    
    pred_y = [];
    m_sum = 0;
    for i=1:1:no_seg
        
        st_seg = ((i-1)*seg_len)+1;
        fi_seg = i*seg_len;
        
        loc_st = find(locs_all >= st_seg);
        loc_fi = find(locs_all <= fi_seg);
        
        locs = intersect(loc_st,loc_fi);
        
        pks_d = pksd(locs);
        
        % Markov chain for this segment
        m_mat1 = zeros(3,3);
        for ll = 1:1:length(pks_d)-1
            p_ind = pks_d(ll);
            n_ind = pks_d(ll+1);
            
            m_mat1(p_ind,n_ind) = m_mat1(p_ind,n_ind) + 1;
            
        end
        
        m_act = m_mat1;
        
        for i1=1:1:size(m_mat1,1)
            if(sum(m_mat1(i1,:)) > 0)
                m_mat1(i1,:) = m_mat1(i1,:)/sum(m_mat1(i1,:));
            end
        end
        
        m_sum = m_sum + m_act;
        
        
        % SD of peaks and diff(peaks)
        pks_pos = findpeaks(swd_p(st_seg:fi_seg),'Minpeakheight',0.4,'Minpeakdistance',(0.2*Fs),'minpeakprominence',0.2);
        if(length(pks_pos) >= 2)
            sd_pks = std(pks_pos);
            sd_dpks = std(diff(pks_pos));
        else
            sd_pks = 0;
            sd_dpks = 0;
        end
                
        % Entropy of all pks - negative and positive
        pks_temp = pks_all(locs);
        edges = -1:0.05:1;
        edge_mid = find(abs(edges) < lim);
        w = ones(1,length(edges));
        w(edge_mid) = 0.01;
        h = histcounts(pks_temp,edges)/length(pks_temp);
        ent = get_entropy(h,1,w);
        
        % Sum of peaks with magnitude greater than lim
        pks_a = pks_abs(locs);
        pks_avg = sum(pks_a(find(pks_a >= lim)));
        
        % Form feature vector
        
        fv = [m_mat1(1,1) m_mat1(2,2) m_act(1,1) m_act(2,2) ent];

        result = predict(hf_mdl,fv);
        pred_val = str2num(cell2mat(result));
        pred_y = [pred_y;pred_val];
        fv = [m_mat1(1,:) m_mat1(2,:) m_mat1(3,:) m_act(1,:) m_act(2,:) m_act(3,:) sd_pks sd_dpks ent pks_avg];
        m_arr1 = [m_arr1;[fv pred_val]];
    end
    
    signal_pad = power2pad(signal_cl,11);
    
    [~,swd2] = swt(signal_pad,11,'db2');
    
    % Find all points with magnitude greater than 4.5 
    % in 7th Detail coefficient level of Db2 decomposition - Low freq noise
    
    swd2 = swd2(7,1:sig_len);
    
    [lpks1,alow1] = findpeaks(swd2,'Minpeakheight',1,'Minpeakprominence',2);
    [lpks2,alow2] = findpeaks(((-1)*swd2),'Minpeakheight',1,'Minpeakprominence',2);
    alow_locs = union(alow1,alow2);
    alow_len = length(alow_locs);
    
    q1 = quantile(lpks1,0.25);
    q2 = quantile(lpks2,0.25);
  
    l1_thr = 1.5*q1;
    l2_thr = 1.5*q2;
    
    [~,low1] = findpeaks(swd2,'Minpeakheight',l1_thr,'Minpeakprominence',1);
    [~,low2] = findpeaks(((-1)*swd2),'Minpeakheight',l2_thr,'Minpeakprominence',1);
    low_locs = union(low1,low2);
    
    [~,vlow1] = findpeaks(swd2,'Minpeakheight',6.5,'Minpeakprominence',1);
    [~,vlow2] = findpeaks(((-1)*swd2),'Minpeakheight',6.5,'Minpeakprominence',1);
    vlow_locs = union(vlow1,vlow2);
        
    [~,low] = intersect(alow_locs,low_locs);
    [~,vlow] = intersect(alow_locs,vlow_locs);
    pks_vec = zeros(1,alow_len);
    pks_vec(low) = 1;
    pks_vec(vlow) = 2;
    
    % Lf segments
    lf = strfind(pks_vec,[1 1 1]);
    lf0 = lf + 1;
    lf1 = lf + 2;
    
    %VLF noise
    vlf0 = strfind(pks_vec,[1 2]);
    vlf1 = vlf0 + 1;
    vlf2 = strfind(pks_vec,[2 1]);
    vlf3 = vlf2 + 1;
    vlf4 = strfind(pks_vec,[2 2]);
    vlf5 = vlf4 + 1;
    
    lf_seg = union([lf lf0 lf1], [vlf0,vlf1,vlf2,vlf3,vlf4,vlf5]);
    
    pks_final = zeros(1,alow_len);
    pks_final(lf_seg) = lf_seg;
    
    % Find all the noisy sample points
    
    ns_samp = zeros(1,sig_len);
    hf_samp = zeros(1,sig_len);
    for p=1:1:length(pks_final)-1
        if(pks_final(p) > 0)
            if(pks_final(p+1) > 0)
                st_ns = alow_locs(pks_final(p));
                fi_ns = alow_locs(pks_final(p+1));
                
                ns_samp(st_ns:fi_ns) = 1;
            end
        end
    end
    
    % check for non zero windows on pred_y
    % Remove single ones if entropy and avgPks conditions fail
        
    % ns_samp: signal with ones for noise and zeros otherwise
    for k=1:1:size(pred_y,1)
        if(m_arr1(k,5) <= 0.25)
            
            pred_y(k,1) = 0;
        end
        if(pred_y(k,1) == 1)
            if((m_arr1(k,21) >= 1.6))
                st_ns = ((k-1)*seg_len)+1;
                fi_ns = k*seg_len;
                ns_samp(st_ns:fi_ns) = 1;
                hf_samp(st_ns:fi_ns) = 1;
            else
                pred_y(k,1) = 0;
            end               
        end
        
    end
    
    ns_len = length(find(ns_samp == 1));
    ns_ratio = ns_len/sig_len;
    cl_sig = (1-ns_ratio)*sig_len/Fs;
    
    [~,len1] = getCons(ns_samp,0);
    
    max1_s = 0;
    max2_s = 0;
    if(~isempty(len1))
        sort_len1 = sort(len1,'descend');

        max1 = sort_len1(1);
        max1_s = max1/Fs;
        
        if(length(len1) > 1)
            max2 = sort_len1(2);
            max2_s = max2/Fs;
        end
    end
    ns_info = [ns_ratio cl_sig max1_s max2_s];
    
    if(ns_ratio == 0)
        pred_class = 0;

    elseif(cl_sig >= 20)
        pred_class = 0;

    elseif(ns_ratio >= 0.7)
        pred_class = 1;
    else
        result1 = predict(ns_mdl,ns_info);
        pred_class = str2num(cell2mat(result1));
    end
    
end