function [S2Dictionary S2TNeighbors canonicalIndS2] = organizeS2Dictionary(S2DictPaths)

load Config
% load all S2 templates
indS2 = 1;
for iPartLoc = 1:length(S2DictPaths) % each .mat file contains transformed S2 templates 
    s2path = '.';
    for j = 1:length(S2DictPaths{iPartLoc})
        s2path = [s2path '/' S2DictPaths{iPartLoc}{j}];
    end
    load(s2path);
    
    % make 3 by n matrices
    for iT = 1:length(TransformedTemplate)
        SparseT = [];
        for iElement = 1:length(TransformedTemplate{iT}.selectedRow)
            oneElement = [TransformedTemplate{iT}.selectedRow(iElement);...
                TransformedTemplate{iT}.selectedCol(iElement); 
                TransformedTemplate{iT}.selectedOri(iElement)];
            SparseT = [SparseT, oneElement]; % concatenate column vector
        end
        S2Dictionary{indS2} = SparseT;
        indS2 = indS2 + 1;
    end

    % also: identify the canonical template (without template rotation)
    canonicalIndS2(iPartLoc) = indS2 - ceil(length(TransformedTemplate)/2); % this is very adhoc
                    % the template with zero rotation is the middle one
    
    
    % Also: make the Neighborhoods
    stepsize = 5;   % TODO: adhoc: this a parameter
    for iT = 1:length(TransformedTemplate) % add the same template at different transforms 
        SparseT = [];
        for Tshifted = 1:length(TransformedTemplate)
            for colshift = unique( [0 -partLocRange : stepsize : partLocRange] )
                for rowshift = unique( [0 -partLocRange : stepsize : partLocRange] )
                    oneElement = [ rowshift; colshift; indS2-length(TransformedTemplate)+Tshifted ];
                    SparseT = [SparseT, oneElement]; % concatenate column vector
                end
            end
        end
        S2TNeighbors{indS2-length(TransformedTemplate)+iT} = single(SparseT);
    end

end
