From d75db7c63f2d90a2c4f0bed58d9778376c212186 Mon Sep 17 00:00:00 2001
From: Ben Heasly <benjamin.heasly@gmail.com>
Date: Mon, 6 Feb 2017 11:39:22 -0500
Subject: [PATCH] refactor match renderings between folders to separate
 function

---
 Test/Interactive/rtbCompareManyRenderings.m   | 111 ++++++++++++++++++
 Test/Interactive/rtbCompareRenderings.m       |   1 +
 Test/Interactive/rtbFetchReferenceData.m      |  17 ++-
 Test/Interactive/rtbFindRenderings.m          |   1 +
 Test/Interactive/rtbPlotRenderingComparison.m |   6 +-
 5 files changed, 131 insertions(+), 5 deletions(-)
 create mode 100644 Test/Interactive/rtbCompareManyRenderings.m

diff --git a/Test/Interactive/rtbCompareManyRenderings.m b/Test/Interactive/rtbCompareManyRenderings.m
new file mode 100644
index 0000000..2052022
--- /dev/null
+++ b/Test/Interactive/rtbCompareManyRenderings.m
@@ -0,0 +1,111 @@
+function [comparisons, matchInfo] = rtbCompareManyRenderings(folderA, folderB, varargin)
+%% Compare paris of renderings across two folders.
+%
+% comparisons = rtbCompareManyRenderings(folderA, folderB) finds rendering
+% data files in the given folderA and folderB and attempts to match up
+% pairs of renderings that came from the same recipe and renderer.
+% For each pair, computes difference images and statistics.
+%
+% Returns a struct array of image comparisons, as returned from
+% rtbCompareRenderings().
+%
+% rtbCompareManyRenderings( ... 'fetchReferenceData', fetchReferenceData)
+% specify whether to use Remote Data Toolbox to fetch reference data for
+% comparison.  The default is true, fetch reference data when there is a
+% recipe in folderA that was not found in folderB, and cache the fetched
+% data in folderB.
+%
+%%% RenderToolbox4 Copyright (c) 2012-2017 The RenderToolbox Team.
+%%% About Us://github.com/RenderToolbox/RenderToolbox4/wiki/About-Us
+%%% RenderToolbox4 is released under the MIT License.  See LICENSE file.
+
+parser = inputParser();
+parser.KeepUnmatched = true;
+parser.addRequired('folderA', @ischar);
+parser.addRequired('folderB', @ischar);
+parser.addParameter('fetchReferenceData', true, @islogical);
+parser.parse(folderA, folderB, varargin{:});
+folderA = parser.Results.folderA;
+folderB = parser.Results.folderB;
+fetchReferenceData = parser.Results.fetchReferenceData;
+
+
+%% Identify renderings and recipes to compare.
+renderingsA = rtbFindRenderings(folderA, varargin{:});
+recipeNames = unique({renderingsA.recipeName});
+nRecipes = numel(recipeNames);
+
+renderingsB = rtbFindRenderings(folderB, varargin{:});
+
+%% Compare one recipe at a time, fetch data as necessary.
+comparisonsCell = cell(1, nRecipes);
+matchInfoCell = cell(1, nRecipes);
+for rr = 1:nRecipes
+    recipeName = recipeNames{rr};
+    fprintf('Comparing renderings for recipe <%s>.\n', recipeName);
+    
+    isRecipeA = strcmp({renderingsA.recipeName}, recipeName);
+    recipeRenderingsA = renderingsA(isRecipeA);
+    
+    % fetch missing recipe for B?
+    isRecipeB = strcmp({renderingsB.recipeName}, recipeName);
+    if any(isRecipeB)
+        recipeRenderingsB = renderingsB(isRecipeB);
+    elseif fetchReferenceData
+        recipeRenderingsB = rtbFetchReferenceData(recipeName, varargin{:});
+        if isempty(recipeRenderingsB)
+            fprintf('  Could not fetch reference data for set B, skipping this recipe.\n');
+            continue;
+        end
+    else
+        fprintf('  Could not find local data for set B.  Skipping this recipe.\n');
+        continue;
+    end
+    
+    % match pairs of renderings for recipes A and B
+    info = matchRenderingPairs(recipeRenderingsA, recipeRenderingsB);
+    fprintf('  Found %d matched pairs of renderings.\n', info.nPairs);
+    
+    % run a comparison for each matched pair
+    pairsCell = cell(1, info.nPairs);
+    for pp = 1:info.nPairs
+        fprintf('    %s.\n', info.matchedA(pp).identifier);
+        pairsCell{pp} = rtbCompareRenderings(info.matchedA(pp), info.matchedB(pp), varargin{:});
+    end
+    comparisonsCell{rr} = [pairsCell{:}];
+    matchInfoCell{rr} = info;
+    
+    % report on unmatched renderings
+    if ~isempty(info.unmatchedA)
+        nUnmatched = info.unmatchedA;
+        fprintf('  %d renderings in A were not matched in B:\n', nUnmatched);
+        for uu = 1:nUnmatched
+            fprintf('    %s\n', info.info.unmatchedA(uu).identifier);
+        end
+    end
+    
+    if ~isempty(info.unmatchedB)
+        nUnmatched = info.unmatchedB;
+        fprintf('  %d renderings in B were not matched in A:\n', nUnmatched);
+        for uu = 1:nUnmatched
+            fprintf('    %s\n', info.info.unmatchedB(uu).identifier);
+        end
+    end
+end
+comparisons = [comparisonsCell{:}];
+matchInfo = [matchInfoCell{:}];
+
+
+%% For pairs of comparable renderings from two sets.
+function info = matchRenderingPairs(renderingsA, renderingsB)
+identifiersA = {renderingsA.identifier};
+identifiersB = {renderingsB.identifier};
+[~, indexA, indexB] = intersect(identifiersA, identifiersB, 'stable');
+[~, unmatchedIndexA] = setdiff(identifiersA, identifiersB);
+[~, unmatchedIndexB] = setdiff(identifiersB, identifiersA);
+
+info.nPairs = numel(indexA);
+info.matchedA = renderingsA(indexA);
+info.matchedB = renderingsB(indexB);
+info.unmatchedA = renderingsA(unmatchedIndexA);
+info.unmatchedB = renderingsB(unmatchedIndexB);
diff --git a/Test/Interactive/rtbCompareRenderings.m b/Test/Interactive/rtbCompareRenderings.m
index d9e7a28..471a7fb 100644
--- a/Test/Interactive/rtbCompareRenderings.m
+++ b/Test/Interactive/rtbCompareRenderings.m
@@ -28,6 +28,7 @@ function comparison = rtbCompareRenderings(renderingA, renderingB, varargin)
 %%% RenderToolbox4 is released under the MIT License.  See LICENSE file.
 
 parser = inputParser();
+parser.KeepUnmatched = true;
 parser.addRequired('renderingA', @isstruct);
 parser.addRequired('renderingB', @isstruct);
 parser.addParameter('denominatorThreshold', 0.2, @isnumeric);
diff --git a/Test/Interactive/rtbFetchReferenceData.m b/Test/Interactive/rtbFetchReferenceData.m
index 8b400f6..adca969 100644
--- a/Test/Interactive/rtbFetchReferenceData.m
+++ b/Test/Interactive/rtbFetchReferenceData.m
@@ -30,6 +30,7 @@ function [renderings, referenceRoot, artifact] = rtbFetchReferenceData(recipeNam
 %%% RenderToolbox4 is released under the MIT License.  See LICENSE file.
 
 parser = inputParser();
+parser.KeepUnmatched = true;
 parser.addRequired('recipeName', @ischar);
 parser.addParameter('rdtConfig', 'render-toolbox');
 parser.addParameter('remotePath', 'reference-data', @ischar);
@@ -42,12 +43,17 @@ remotePath = parser.Results.remotePath;
 referenceVersion = parser.Results.referenceVersion;
 referenceRoot = parser.Results.referenceRoot;
 
-
 %% Get a whole recipe from the server.
 artifactPath = fullfile(remotePath, recipeName);
-[fileName, artifact] = rdtReadArtifact(rdtConfig, artifactPath, recipeName, ...
-    'version', referenceVersion, ...
-    'type', 'zip');
+try
+    [fileName, artifact] = rdtReadArtifact(rdtConfig, artifactPath, recipeName, ...
+        'version', referenceVersion, ...
+        'type', 'zip');
+catch err
+    renderings = [];
+    artifact = [];
+    return;
+end
 
 if isempty(fileName)
     renderings = [];
@@ -58,6 +64,9 @@ end
 
 %% Explode renderings it into the destination folder.
 destination = fullfile(referenceRoot, recipeName);
+if 7 ~= exist(destination, 'dir')
+    mkdir(destination);
+end
 unzip(fileName, destination);
 
 % scan for rendering records
diff --git a/Test/Interactive/rtbFindRenderings.m b/Test/Interactive/rtbFindRenderings.m
index cdde19c..d6b7b22 100644
--- a/Test/Interactive/rtbFindRenderings.m
+++ b/Test/Interactive/rtbFindRenderings.m
@@ -32,6 +32,7 @@ function renderings = rtbFindRenderings(rootFolder, varargin)
 %%% RenderToolbox4 is released under the MIT License.  See LICENSE file.
 
 parser = inputParser();
+parser.KeepUnmatched = true;
 parser.addRequired('rootFolder', @ischar);
 parser.addParameter('filter', '\.mat$', @ischar);
 parser.addParameter('renderingsFolderName', 'renderings', @ischar);
diff --git a/Test/Interactive/rtbPlotRenderingComparison.m b/Test/Interactive/rtbPlotRenderingComparison.m
index 60a8974..b5526fa 100644
--- a/Test/Interactive/rtbPlotRenderingComparison.m
+++ b/Test/Interactive/rtbPlotRenderingComparison.m
@@ -10,6 +10,7 @@ function fig = rtbPlotRenderingComparison(comparison, varargin)
 %%% RenderToolbox4 is released under the MIT License.  See LICENSE file.
 
 parser = inputParser();
+parser.KeepUnmatched = true;
 parser.addRequired('comparison', @isstruct);
 parser.addParameter('isScale', true, @islogical);
 parser.addParameter('toneMapFactor', 0, @isnumeric);
@@ -34,7 +35,10 @@ rgbBminusA = rtbMultispectralToSRGB(comparison.bMinusA, S, ...
 
 
 %% Make the plot.
-name = sprintf('RGB isScale %d toneMapFactor %.2f', isScale, toneMapFactor);
+name = sprintf('%s isScale %d toneMapFactor %.2f', ...
+    comparison.renderingA.identifier, ...
+    isScale, ...
+    toneMapFactor);
 set(fig, 'Name', name, ...
     'NumberTitle', 'off');
 
-- 
GitLab