%% AoD estimation in SU_MIMO systems
% Implements the Step3 of proposed algorithm to unquantized SU_MIMO system.

%%%%% Input parameters
% H_True : True channel (to obtain the received signal at the BS)
% SNR : uplink SNR at the BS
% u_grid : search grid for AoD
% T_s : number of times the same precoder is used at the UE
% A_RX_est:  estimated array manifold from step 1
% L : number of paths
% d_t :  inter-element spacing at the UE


%%% Output
% dod_est_dc_ind : index of the estimated AoD (1 \times L)



function dod_est_dc_ind = Dod_est_UQ(H_true, SNR, u_grid, T_s,  A_RX_est, L, d_t)

[N_r, N_t] = size(H_true);
dod_est_dc_ind = zeros(1,L);
M = length(u_grid);
K = 2; %  Beams per stage
Nstage = log2(M);

doa_check_a = zeros(K,1);

for iter=1:L
    
    d_index = 1; 
    w_mrc = A_RX_est(:,iter);
    
    for s = 1:Nstage 
        
        W = get_code_TX(N_t,d_t,M,K,s); % set of precoders for stage-s
        pos_req(1:K) = 2*(d_index-1)+(1:K); 

        for j=1:K
            f_tx = W(:,pos_req(j));
            N_noise = sqrt(1/2).*(randn(N_r,T_s) + 1j.*randn(N_r,T_s));
            X_rec = sqrt(SNR(1)).*H_true*repmat(f_tx,1,T_s) + N_noise;   
            doa_check_a(j) = abs(mean(w_mrc'*X_rec))^2; % received power
        end

        [val c_index] = max(doa_check_a);
        d_index = 2*(d_index-1) + c_index;

    end
    dod_est_dc_ind(iter) = (d_index);
end

end


