
%% Latex Cross-Validation
%
% Generates Latex code for presentation of error tables produced by 
% cross_validation.m.
%
%  ex. latex_cv('./error_analysis', 'rmse', 'xb3-38mm', './latex/', {'std','blind','alvarez'})

%% Input Arguments

% errPath - Parent directory of error table .mat files
%           type: String

% errType - Type of error metric
%           type: String {ex. 'rmse'}

% errFilter - Regular expression for filtering error files
%             type: String

% cvName - Name of cross-validation 
%          type: String

% latexPath - Parent directory of latex code 
%             type: String

% methodNames - Name of lens distortion correction methods (tags)
%               type: Nx1 cell

% scaleFactor - Scale factor of cross-validation error table.
%               type: positive integer


%% Output Arguments

% N/A
%

%% Latex Cross-Validation

function latex_cv(errPath, errType, errFilter, cvName, latexPath, methodNames, scaleFactor)

%check input parameters
assert(ischar(errPath));
assert(ischar(errType));
assert(ischar(errFilter));
assert(ischar(cvName));
assert(ischar(latexPath));
assert(isa(methodNames, 'cell'));
validateattributes(scaleFactor, {'numeric'}, {'scalar', 'positive', 'real', 'integer', 'nonnan', 'finite'});

%formatting constants/variables
cellSize = '\tableWidth';
precision = 4;
lowerFormatStr  = sprintf('\\\\textbf{%%1.%df}', precision);
higherFormatStr = sprintf('%%1.%df', precision);

% Find all supported files within directory
fprintf('\tSearching directory %s...\n', errPath);
suppFiles = {'mat'};
[fileNames, nFiles] = find_supported_files(errPath, suppFiles);
fprintf('\t\tFound %d line-point .mat files\n', nFiles);

% Select files 
errFileNames = select_files(fileNames, '^rmse_[a-zA-Z]+_(?<group>[a-zA-Z0-9-]+)');
nFiles = length(errFileNames);

%find all error-table files matching cross-validation tag/identifier    
nMethods = length(methodNames);
errFiles = cell(nMethods, nFiles);
nErrMethFiles = zeros(nMethods, 1);

for i = 1:nFiles,  
    
    comps = strsplit(errFileNames{i}, '_', 'DelimiterType', 'RegularExpression');
    
    if strcmp(comps{1}, errType) && any(strcmp(comps{2}, methodNames)) && ~isempty(regexp(errFileNames{i}, errFilter, 'once'))                        
        
        load(fullfile(errPath, errFileNames{i}), 'errTable'); 
        m = find(strcmp(comps{2}, methodNames));        
        errFiles{m, nErrMethFiles(m)+1} = errFileNames{i};        
        nErrMethFiles(m) = nErrMethFiles(m) + 1;
        
    end
    
end

if any(nErrMethFiles < 1)
    error('LatexCv:InsufficientData', 'Insufficient error files found');
elseif ~all(nErrMethFiles == nErrMethFiles(1))
    error('LatexCv:InconsistentData', 'Wrong number of entries in error-tables found');
end

%create output file
fid = fopen(fullfile(latexPath, strcat(cvName, '.txt')),'w');

nImgs = nErrMethFiles(1);
errTables = cell(nMethods);
for m = 1:nMethods,
        
    errTables{m} = nan(nImgs);
    
    for i = 1:nImgs,
            
        loadErrFileName = errFiles{m, i};
        load(fullfile(errPath, loadErrFileName), 'errTable');       
        errTables{m}(i,:) = errTable(:)';   
    
    end
    
end

minIndicator = false(nMethods, nImgs, nImgs);
for i = 1:nImgs,
    
    for j = 1:nImgs,
    
        minVal = NaN;
        for m = 1:nMethods,

            if isnan(minVal) || minVal > errTables{m}(i,j) 
                minModel = m;
                minVal = errTables{m}(i,j); 
            end

        end
    
        minIndicator(minModel,i,j) = true;
    
    end
    
end

aveErrTable = nan(nMethods, nImgs);
for i = 1:nImgs,
    for m = 1:nMethods,
        aveErrTable(m,i) = mean(errTables{m}(i,:));
    end
end
[~, minAveModel] = min(aveErrTable, [], 1);

fprintf(fid, '=========== Notes ===========\n\n');
for i = 1:nImgs,
    fprintf(fid,'HI:\\RN{%d} => %s\n', i, errFiles{1, i});
end

fprintf(fid, 'Scale Factor: %f\n\n', scaleFactor);

for m = 1:nMethods,   
    
    fprintf(fid, '=========== %s ===========\n\n', methodNames{m});
    
    for i = 1:nImgs, 
        
        fprintf(fid,'HI:\\RN{%d} \t\t & ',i);
        
        for j = 1:nImgs, 
        
            if minIndicator(m,i,j)
                fprintf(fid, lowerFormatStr, scaleFactor*errTables{m}(i,j));
            else
                fprintf(fid, higherFormatStr, scaleFactor*errTables{m}(i,j));
            end

            fprintf(fid, ' & ');    
            
        end
        
        if m == minAveModel(i),        
            fprintf(fid, lowerFormatStr, scaleFactor*aveErrTable(m,i));        
        else        
            fprintf(fid, higherFormatStr, scaleFactor*aveErrTable(m,i));        
        end

        fprintf(fid,'\\\\ \\hline\n');
        
    end  
    
    fprintf(fid,'\n\n\n\n\n');
    
end

fclose(fid);

end



