function trackResults = trackingPostProcessing( settings, trackResults )

%==============================================================================%
%                                                                              %
%   trackResults = trackingPostProcessing( settings, trackResults )            %
%                                                                              %
%   Calculate and save additional information                                  %
%   David S. De Lorenzo                                                        %
%   01 November 2005                                                           %
%                                                                              %
%==============================================================================%
%                       GPS Software Receiver in Matlab                        %
%     Copyright (c) 2003-2017 David S. De Lorenzo / 2018-2023 Trimble Inc.     %
%==============================================================================%

%--- Assign temporary variables, making code more readable ---------------------
msToProcess  = settings.trk.msToProcess;
pullInTimeMs = settings.trk.pullInTimeMs;
msPerDataBit = settings.msPerDataBit;
navStartBit  = trackResults.navStartBit;
cnoMethod    = settings.trk.cnoMethod;

%--- Smooth C/No estimate across 'N' milliseconds ------------------------------
N = 300;

%--- Calculate C/No and determine navigation data bits -------------------------
%    But only do this if the navigation data bit transition boundary
%    has been estimated, which occurs on the first millisecond of the
%    transition mode.
if (msToProcess > pullInTimeMs)
    cno_state.method = cnoMethod; % 0 = previous SNR method, 1= Stinger SNR method
    cno_state.msPerDataBit = msPerDataBit;
    cno_state.signal_power = nan;
    cno_state.noise_power = nan;
    cno_state.cno = nan;
    %--- Calculate C/No --------------------------------------------------------
    for chunkStart = navStartBit:msPerDataBit:(msToProcess-msPerDataBit+1)
        
        %--- Index of samples to use in the C/No estimator ---------------------
        idx = chunkStart + (1:msPerDataBit) - 1;
        
        %=== Estimate C/No =====================================================
        [trackResults.CNo(idx),cno_state] = estCNo(cno_state, ...
                                                   trackResults.I_prompt(idx), ...
                                                   trackResults.Q_prompt(idx));
    end
    
    %--- Ensure that only real values of C/No are allowed ----------------------
    trackResults.CNo = real(trackResults.CNo);
    
    %--- Fill C/No values for early epochs -------------------------------------
    trackResults.CNo(1:navStartBit) = trackResults.CNo(navStartBit);
    
    %--- Fill C/No values for trailing epochs ----------------------------------
    trackResults.CNo(chunkStart:end) = trackResults.CNo(chunkStart);
    
    %--- Smooth C/No estimate across 'N' milliseconds --------------------------
    if cno_state.method == 0
        if (msToProcess >= N)
            temp = filter(1/N*ones(1,N), 1, ...
                          [repmat(trackResults.CNo(1),1,N-1), trackResults.CNo]);
            trackResults.CNo = temp(N:end);
        end
    end
    
    %--- Calculate the final value of C/No -------------------------------------
    trackResults.CNoFinal = ...
        mean(trackResults.CNo(min([max([end-1000 1000]) end]):end));
    % Also compute 1s averages
    trackResults.CNo1s = filter(1/1000*ones(1,1000), 1, ...
                                trackResults.CNo);
    trackResults.CNo1s = trackResults.CNo1s(1000:1000:end);
    %--- Calculate the final value of code-phase -------------------------------------
    trackResults.codePhaseFinal = ...
        mean(trackResults.codePhase(min([max([end-100 100]) end]):end));
    
    %=== Estimate the navigation data bit values ===============================
    trackResults.navDataBits = estNavDataBits(navStartBit, ...
                                              msPerDataBit, ...
                                              trackResults.I_prompt);
    
end % if (msToProcess > pullInTimeMs)

return
%===============================================================================