From 88e4b9108ba696a47b022f186269fc0fab74b7b7 Mon Sep 17 00:00:00 2001
From: Nicola Vigano <nicola.vigano@esrf.fr>
Date: Tue, 24 Feb 2015 19:18:54 +0100
Subject: [PATCH] Extended/Cluster: added support functions and moved
 segmentation output to reconstruction file

Signed-off-by: Nicola Vigano <nicola.vigano@esrf.fr>
---
 4_grains/GtThreshold.m             | 58 +++++++++++-------------------
 4_grains/gtLoadCluster.m           | 31 ++++++++++++++++
 4_grains/gtLoadClusterRec.m        | 31 ++++++++++++++++
 4_grains/gtLoadGrain.m             |  8 +++--
 4_grains/gtLoadGrainRec.m          |  8 +++--
 4_grains/gtSaveCluster.m           | 34 ++++++++++++++++++
 4_grains/gtSaveClusterRec.m        | 49 +++++++++++++++++++++++++
 4_grains/gtSaveGrainRec.m          |  9 +++--
 5_reconstruction/GtAssembleVol3D.m | 18 +++++-----
 9 files changed, 193 insertions(+), 53 deletions(-)
 create mode 100644 4_grains/gtLoadCluster.m
 create mode 100644 4_grains/gtLoadClusterRec.m
 create mode 100644 4_grains/gtSaveCluster.m
 create mode 100644 4_grains/gtSaveClusterRec.m

diff --git a/4_grains/GtThreshold.m b/4_grains/GtThreshold.m
index 9c750a2e..4bd2d5e3 100644
--- a/4_grains/GtThreshold.m
+++ b/4_grains/GtThreshold.m
@@ -119,7 +119,7 @@ classdef GtThreshold < handle
                     sample.phases{phaseID}.setBoundingBox(grainID, grain.segbb);
 
                     % Write to file
-                    obj.saveGrain(phaseID, grainID, grain);
+                    obj.saveGrain(phaseID, grainID, grain, sample);
                 catch mexc
                     gtPrintException(mexc, ...
                         'Segmenting grain %d in phase %d failed', grainID, phaseID);
@@ -171,7 +171,7 @@ classdef GtThreshold < handle
                 grain_seg.segbb = round([(size(grain_rec.vol) -1), (size(grain_rec.vol) +1)] /2);
             end
 
-            obj.saveGrain(phaseID, grainID, grain_seg);
+            obj.saveGrain(phaseID, grainID, grain_seg, sample);
             fprintf('Done.\n');
         end
 
@@ -200,7 +200,7 @@ classdef GtThreshold < handle
             end
             sample.phases{phaseID}.setBoundingBox(grainID, grain.segbb);
 
-            obj.saveGrain(phaseID, grainID, grain);
+            obj.saveGrain(phaseID, grainID, grain, sample);
             fprintf('\b\b: Done.\n');
 
             fprintf('Writing to sample.mat..')
@@ -263,65 +263,47 @@ classdef GtThreshold < handle
         % grain = loadGrain(obj, phaseID, grainID)
 
             grain_out = gtLoadGrain(phaseID, grainID, 'fields', {'id'});
-            grain_rec = gtLoadGrainRec(phaseID, grainID);
 
             is_6D = isfield(obj.param.rec, 'grains') ...
                 && strcmpi(obj.param.rec.grains.algorithm(1:2), '6D');
-            if (is_6D)
-                file_ext_rec_path = fullfile(obj.param.acq.dir, ...
-                    '4_grains', sprintf('phase_%02d', phaseID), ...
-                    sprintf('grain_extended_details_%04d.mat', grainID));
+            is_extended = sample.phases{phaseID}.getUseExtended(grainID);
 
-                if (sample.phases{phaseID}.getUseExtended(grainID))
-                    grain_rec = load(file_ext_rec_path, 'ODF6D');
-                end
+            grain_rec = gtLoadGrainRec(phaseID, grainID, ...
+                'is_extended', is_6D && is_extended);
 
+            if (is_6D)
                 grain_out.vol = grain_rec.ODF6D.intensity;
                 grain_out.shift = grain_rec.ODF6D.shift;
             else
                 grain_out.vol = grain_rec.VOL3D.intensity;
                 grain_out.shift = grain_rec.VOL3D.shift;
             end
-
-            if (~isfield(grain_out, 'vol') || isempty(grain_out.vol))
-                gtError('GtThreshold:wrong_argument', ...
-                    'Volume to segment is empty!')
-            end
         end
 
-        function saveGrain(~, phaseID, grainID, grain_seg)
+        function saveGrain(obj, phaseID, grainID, grain_seg, sample)
         % GTTHRESHOLD/SAVEGRAIN
         % saveGrain(obj, phaseID, grainID, grain)
 
-            seg_struct = struct('SEG', grain_seg);
-            gtSaveGrainRec(phaseID, grainID, seg_struct, 'fields', {'SEG'});
-        end
+            is_6D = isfield(obj.param.rec, 'grains') ...
+                && strcmpi(obj.param.rec.grains.algorithm(1:2), '6D');
+            is_extended = sample.phases{phaseID}.getUseExtended(grainID);
 
-        function cluster = loadCluster(obj, phase_id, grain_ids)
-            str_ids = sprintf('_%04d', grain_ids);
-            file_cluster_rec_path = fullfile(obj.param.acq.dir, ...
-                '4_grains', sprintf('phase_%02d', phase_id), ...
-                sprintf('grain_cluster_details%s.mat', str_ids));
-            cluster_rec = load(file_cluster_rec_path);
+            grain_rec = struct('SEG', grain_seg);
+            gtSaveGrainRec(phaseID, grainID, grain_rec, 'fields', {'SEG'}, ...
+                'is_extended', is_6D && is_extended);
+        end
 
+        function cluster = loadCluster(~, phase_id, grain_ids)
+            cluster_rec = gtLoadClusterRec(phase_id, grain_ids);
             cluster = struct( ...
                 'id', grain_ids(1), ...
                 'vol', cluster_rec.ODF6D.intensity, ...
                 'shift', cluster_rec.ODF6D.shift );
         end
 
-        function saveCluster(obj, phase_id, grain_ids, cluster)
-            str_ids = sprintf('_%04d', grain_ids);
-            file_cluster_rec_path = fullfile(obj.param.acq.dir, ...
-                '4_grains', sprintf('phase_%02d', phase_id), ...
-                sprintf('grain_cluster_details%s.mat', str_ids));
-            cluster_rec = load(file_cluster_rec_path);
-
-            cluster_rec.SEG = struct( ...
-                'seg', cluster.seg, 'segbb', cluster.segbb, ...
-                'threshold', cluster.threshold, 'Area', cluster.Area, ...
-                'seed', cluster.seed );
-            save(file_cluster_rec_path, '-struct', 'cluster_rec', '-v7.3');
+        function saveCluster(~, phase_id, grain_ids, cluster_seg)
+            cluster_rec = struct('SEG', cluster_seg);
+            gtSaveClusterRec(phase_id, grain_ids, cluster_rec, 'fields', {'SEG'});
         end
 
         function is_iterative = checkIsIterative(obj)
diff --git a/4_grains/gtLoadCluster.m b/4_grains/gtLoadCluster.m
new file mode 100644
index 00000000..c3b3af7d
--- /dev/null
+++ b/4_grains/gtLoadCluster.m
@@ -0,0 +1,31 @@
+function cluster = gtLoadCluster(phase_id, grain_ids, varargin)
+    conf = struct('fields', {{}}, 'parameters', {[]});
+    conf = parse_pv_pairs(conf, varargin);
+
+    if (isempty(conf.parameters))
+        phase_dir = fullfile('4_grains', sprintf('phase_%02d', phase_id));
+    else
+        phase_dir = fullfile(conf.parameters.acq.dir, '4_grains', sprintf('phase_%02d', phase_id));
+    end
+
+    grain_ids_sorted = sort(grain_ids);
+    grain_ids_unique = unique(grain_ids_sorted);
+
+    if (numel(grain_ids) ~= numel(grain_ids_unique))
+        warning('gtLoadCluster:wrong_argumet', ...
+            'Some redundant grain IDs were given: %s', sprintf(' %d', grain_ids));
+    end
+    if (any(grain_ids_sorted ~= grain_ids))
+        warning('gtLoadCluster:wrong_argumet', ...
+            'Some grain IDs were no sorted: %s', sprintf(' %d', grain_ids));
+    end
+
+    str_ids = sprintf('_%04d', grain_ids_unique);
+    cluster_file = fullfile(phase_dir, sprintf('grain_cluster%s.mat', str_ids));
+
+    if (isempty(conf.fields))
+        cluster = load(cluster_file);
+    else
+        cluster = load(cluster_file, conf.fields{:});
+    end
+end
diff --git a/4_grains/gtLoadClusterRec.m b/4_grains/gtLoadClusterRec.m
new file mode 100644
index 00000000..9d7b00b7
--- /dev/null
+++ b/4_grains/gtLoadClusterRec.m
@@ -0,0 +1,31 @@
+function cluster_rec = gtLoadClusterRec(phase_id, grain_ids, varargin)
+    conf = struct('fields', {{}}, 'parameters', {[]});
+    conf = parse_pv_pairs(conf, varargin);
+
+    if (isempty(conf.parameters))
+        phase_dir = fullfile('4_grains', sprintf('phase_%02d', phase_id));
+    else
+        phase_dir = fullfile(conf.parameters.acq.dir, '4_grains', sprintf('phase_%02d', phase_id));
+    end
+
+    grain_ids_sorted = sort(grain_ids);
+    grain_ids_unique = unique(grain_ids_sorted);
+
+    if (numel(grain_ids) ~= numel(grain_ids_unique))
+        warning('gtLoadCluster:wrong_argumet', ...
+            'Some redundant grain IDs were given: %s', sprintf(' %d', grain_ids));
+    end
+    if (any(grain_ids_sorted ~= grain_ids))
+        warning('gtLoadCluster:wrong_argumet', ...
+            'Some grain IDs were no sorted: %s', sprintf(' %d', grain_ids));
+    end
+
+    str_ids = sprintf('_%04d', grain_ids_unique);
+    cluster_file = fullfile(phase_dir, sprintf('grain_cluster_details%s.mat', str_ids));
+
+    if (isempty(conf.fields))
+        cluster_rec = load(cluster_file);
+    else
+        cluster_rec = load(cluster_file, conf.fields{:});
+    end
+end
diff --git a/4_grains/gtLoadGrain.m b/4_grains/gtLoadGrain.m
index 2e2a2dc2..a677ed91 100644
--- a/4_grains/gtLoadGrain.m
+++ b/4_grains/gtLoadGrain.m
@@ -1,5 +1,5 @@
 function grain = gtLoadGrain(phase_id, grain_id, varargin)
-    conf = struct('fields', {{}}, 'parameters', {[]});
+    conf = struct('fields', {{}}, 'parameters', {[]}, 'is_extended', {false});
     conf = parse_pv_pairs(conf, varargin);
 
     if (isempty(conf.parameters))
@@ -9,7 +9,11 @@ function grain = gtLoadGrain(phase_id, grain_id, varargin)
     end
 
     for ii = numel(grain_id):-1:1
-        grain_file = fullfile(phase_dir, sprintf('grain_%04d.mat', grain_id(ii)));
+        if (conf.is_extended)
+            grain_file = fullfile(phase_dir, sprintf('grain_extended_%04d.mat', grain_id(ii)));
+        else
+            grain_file = fullfile(phase_dir, sprintf('grain_%04d.mat', grain_id(ii)));
+        end
 
         if (isempty(conf.fields))
             grain(ii) = load(grain_file);
diff --git a/4_grains/gtLoadGrainRec.m b/4_grains/gtLoadGrainRec.m
index 9dfe5f40..317fa2dc 100644
--- a/4_grains/gtLoadGrainRec.m
+++ b/4_grains/gtLoadGrainRec.m
@@ -1,5 +1,5 @@
 function grain_det = gtLoadGrainRec(phase_id, grain_id, varargin)
-    conf = struct('fields', {{}}, 'parameters', {[]});
+    conf = struct('fields', {{}}, 'parameters', {[]}, 'is_extended', {false});
     conf = parse_pv_pairs(conf, varargin);
 
     if (isempty(conf.parameters))
@@ -9,7 +9,11 @@ function grain_det = gtLoadGrainRec(phase_id, grain_id, varargin)
     end
 
     for ii = numel(grain_id):-1:1
-        grain_file = fullfile(phase_dir, sprintf('grain_details_%04d.mat', grain_id(ii)));
+        if (conf.is_extended)
+            grain_file = fullfile(phase_dir, sprintf('grain_extended_details_%04d.mat', grain_id(ii)));
+        else
+            grain_file = fullfile(phase_dir, sprintf('grain_details_%04d.mat', grain_id(ii)));
+        end
 
         if (isempty(conf.fields))
             grain_det(ii) = load(grain_file);
diff --git a/4_grains/gtSaveCluster.m b/4_grains/gtSaveCluster.m
new file mode 100644
index 00000000..1f4206ed
--- /dev/null
+++ b/4_grains/gtSaveCluster.m
@@ -0,0 +1,34 @@
+function gtSaveCluster(phase_id, grain_ids, cluster, varargin)
+    conf = struct('fields', {{}}, 'parameters', {[]});
+    conf = parse_pv_pairs(conf, varargin);
+
+    if (isempty(conf.parameters))
+        phase_dir = fullfile('4_grains', sprintf('phase_%02d', phase_id));
+    else
+        phase_dir = fullfile(conf.parameters.acq.dir, '4_grains', sprintf('phase_%02d', phase_id));
+    end
+
+    grain_ids_sorted = sort(grain_ids);
+    grain_ids_unique = unique(grain_ids_sorted);
+
+    if (numel(grain_ids) ~= numel(grain_ids_unique))
+        warning('gtLoadCluster:wrong_argumet', ...
+            'Some redundant grain IDs were given: %s', sprintf(' %d', grain_ids));
+    end
+    if (any(grain_ids_sorted ~= grain_ids))
+        warning('gtLoadCluster:wrong_argumet', ...
+            'Some grain IDs were no sorted: %s', sprintf(' %d', grain_ids));
+    end
+
+    str_ids = sprintf('_%04d', grain_ids_unique);
+    grain_file = fullfile(phase_dir, sprintf('grain_cluster%s.mat', str_ids));
+
+    if (isempty(conf.fields))
+        save(grain_file, '-struct', 'grain', '-v7.3');
+    else
+        mat_grain_file = matfile(grain_file, 'Writable', true);
+        for ii_f = 1:numel(conf.fields)
+            mat_grain_file.(conf.fields{ii_f}) = cluster.(conf.fields{ii_f});
+        end
+    end
+end
diff --git a/4_grains/gtSaveClusterRec.m b/4_grains/gtSaveClusterRec.m
new file mode 100644
index 00000000..47c8a1ba
--- /dev/null
+++ b/4_grains/gtSaveClusterRec.m
@@ -0,0 +1,49 @@
+function gtSaveClusterRec(phase_id, grain_ids, cluster_rec_in, varargin)
+    details_fields = {'VOL3D', 'ODF6D', 'ODFw', 'ODFuvw', 'SEG'};
+    conf = struct( ...
+        'fields', {details_fields}, ...
+        'parameters', {[]}, ...
+        'clean', {false} );
+    conf = parse_pv_pairs(conf, varargin);
+
+    % Only allow for the possible fields
+    conf.fields = intersect(conf.fields, details_fields);
+
+    grain_ids_sorted = sort(grain_ids);
+    grain_ids_unique = unique(grain_ids_sorted);
+
+    if (numel(grain_ids) ~= numel(grain_ids_unique))
+        warning('gtLoadCluster:wrong_argumet', ...
+            'Some redundant grain IDs were given: %s', sprintf(' %d', grain_ids));
+    end
+    if (any(grain_ids_sorted ~= grain_ids))
+        warning('gtLoadCluster:wrong_argumet', ...
+            'Some grain IDs were no sorted: %s', sprintf(' %d', grain_ids));
+    end
+
+    if (isempty(conf.parameters))
+        phase_dir = fullfile('4_grains', sprintf('phase_%02d', phase_id));
+    else
+        phase_dir = fullfile(conf.parameters.acq.dir, '4_grains', sprintf('phase_%02d', phase_id));
+    end
+
+    str_ids = sprintf('_%04d', grain_ids_unique);
+    cluster_file = fullfile(phase_dir, sprintf('grain_cluster_details%s.mat', str_ids));
+
+    if (conf.clean)
+        if (exist(cluster_file, file))
+            cluster_rec_out = load(cluster_file);
+        else
+            cluster_rec_out = struct();
+        end
+        for ii_f = 1:numel(conf.fields)
+            cluster_rec_out.(conf.fields{ii_f}) = cluster_rec_in.(conf.fields{ii_f});
+        end
+        save(cluster_file, '-struct', 'gr_det', '-v7.3');
+    else
+        mat_cluster_rec_file = matfile(cluster_file, 'Writable', true);
+        for ii_f = 1:numel(conf.fields)
+            mat_cluster_rec_file.(conf.fields{ii_f}) = cluster_rec_in.(conf.fields{ii_f});
+        end
+    end
+end
diff --git a/4_grains/gtSaveGrainRec.m b/4_grains/gtSaveGrainRec.m
index 6b6363b0..e342be06 100644
--- a/4_grains/gtSaveGrainRec.m
+++ b/4_grains/gtSaveGrainRec.m
@@ -3,14 +3,19 @@ function gtSaveGrainRec(phase_id, grain_id, grain_det, varargin)
     conf = struct( ...
         'fields', {details_fields}, ...
         'parameters', {[]}, ...
-        'clean', false );
+        'is_extended', {false}, ...
+        'clean', {false} );
     conf = parse_pv_pairs(conf, varargin);
 
     % Only allow for the possible fields
     conf.fields = intersect(conf.fields, details_fields);
 
     phase_dir = fullfile('4_grains', sprintf('phase_%02d', phase_id));
-    grain_file = fullfile(phase_dir, sprintf('grain_details_%04d.mat', grain_id));
+    if (conf.is_extended)
+        grain_file = fullfile(phase_dir, sprintf('grain_extended_details_%04d.mat', grain_id));
+    else
+        grain_file = fullfile(phase_dir, sprintf('grain_details_%04d.mat', grain_id));
+    end
 
     if (conf.clean)
         if (exist(grain_file, file))
diff --git a/5_reconstruction/GtAssembleVol3D.m b/5_reconstruction/GtAssembleVol3D.m
index 0d2e992a..68aa88a0 100644
--- a/5_reconstruction/GtAssembleVol3D.m
+++ b/5_reconstruction/GtAssembleVol3D.m
@@ -528,16 +528,15 @@ classdef GtAssembleVol3D < handle
                 for ii = 1:clustersNum
                     str_ids = sprintf('_%04d', clusters(ii).included_ids);
                     try
-                        file_cluster_rec_path = fullfile(obj.parameters.acq.dir, ...
-                            '4_grains', sprintf('phase_%02d', phase_id), ...
-                            sprintf('grain_cluster_details%s.mat', str_ids));
-                        cluster_rec = load(file_cluster_rec_path);
+                        cluster_rec = gtLoadClusterRec( ...
+                            phase_id, clusters(ii).included_ids, ...
+                            'fields', {'SEG', 'ODF6D'});
 
                         if (rotate_vols)
-                            file_cluster_path = fullfile(obj.parameters.acq.dir, ...
-                                '4_grains', sprintf('phase_%02d', phase_id), ...
-                                sprintf('grain_cluster%s.mat', str_ids));
-                            cluster = load(file_cluster_path);
+                            cluster = gtLoadCluster( ...
+                                phase_id, clusters(ii).included_ids, ...
+                                'fields', {'proj'});
+
                             cluster.proj.centerpix = cluster.proj.centerpix * rot;
 
                             int_vol = gtRotateVolume(cluster_rec.ODF6D.intensity, rot);
@@ -610,11 +609,12 @@ classdef GtAssembleVol3D < handle
                     if (assemble_6D)
                         if (sample.phases{phase_id}.getUseExtended(grain_id))
                             vol6D = obj.localPar.cache.get('grain_ext_rec', {phase_id, grain_id}, 'ODF6D');
+                            gr_seg = obj.localPar.cache.get('grain_ext_rec', {phase_id, grain_id}, 'SEG');
                         else
                             vol6D = obj.localPar.cache.get('grain_rec', {phase_id, grain_id}, 'ODF6D');
+                            gr_seg = obj.localPar.cache.get('grain_rec', {phase_id, grain_id}, 'SEG');
                         end
                     end
-                    gr_seg = obj.localPar.cache.get('grain_rec', {phase_id, grain_id}, 'SEG');
 
                     if (rotate_vols)
                         gr_proj = obj.localPar.cache.get('grain', {phase_id, grain_id}, 'proj');
-- 
GitLab