function s2Database = build_s2_layer(c1Database,s2Eigvector,s2Mean,s2Dictionary,param)
% This function is to extract objecct level sparse feature maps with sparse
% representations.
% Input: c1Database   -- the database of mid-level features
%        s2Eigvector  -- the matrix of PCA eigen vectors, each column
%                        represents an eigvector
%        s2Mean       -- the mean of mid-level features, column vector
%        s2Dictionary -- the learned mid-level dictionary, each column
%                        represents a basis
%        param        -- see default settings below
% Output:s2Database   -- the database of object level sparse feature maps
% Written by Jimei Yang
% Oct. 28, 2009
if ~isfield(param,'beta')
    param.beta = 1e-3;
end
if ~isfield(param,'gamma')
    param.gamma = 0.15;
end

[bSize,nBases] = size(s2Dictionary);
nSmp = length(c1Database.path);
s2Database = c1Database;

% compute the sparse code for each local feature
A = s2Dictionary'*s2Dictionary + 2*param.beta*eye(nBases);

for i = 1:nSmp
    fprintf('--extract the s2 feature...');
    tic;
    fpath = c1Database.path{i};
    load(fpath);
    nFea = size(c1Fea.feaData,2);
    if param.pca>0
        pcaData = s2Eigvector'*(c1Fea.feaData-repmat(s2Mean,1,nFea));
        Q = -s2Dictionary'*pcaData;
        feaData = sparse(nBases,nFea);
    else
        Q = -s2Dictionary'*c1Fea.feaData;
        feaData = sparse(nBases,nFea);
    end
    for j = 1:nFea
        feaData(:,j) = L1QP_FeatureSign_yang(param.gamma, A, Q(:,j));
    end
    s2Fea.feaData = feaData;
    s2Fea.x =c1Fea.x;
    s2Fea.y = c1Fea.y;
    s2Fea.height = c1Fea.height;
    s2Fea.width = c1Fea.width;
    
    [pdir,fname] = fileparts(c1Database.path{i});
    seps = findstr(pdir,'\');
    fdir = ['data\s2_',pdir(seps(1)+1:end)];
    if ~isdir(fdir)
        mkdir(fdir);
    end
    fpath = fullfile(fdir,[fname,'.mat']);
    save(fpath,'s2Fea');
    s2Database.path{i} = fpath;
    disp([num2str(i),' in ',num2str(toc),' seconds;']);
end