function s1Database = build_s1_layer(imgDatabase,s1Dictionary,param)
% This function is to extract low-level sparse feature maps with sparse
% representations.
% Input:   imgDatabase  -- the database of normalized images
%          s1Dictionary -- the learned low-level dictionary
%          param        -- see the default settings below
% Output:  s1Database   -- the database of low-level sparse feature maps
% Written by Jimei Yang
% Oct. 28, 2009
if ~isfield(param,'gridSpacing')
    param.gridSpacing = 1;
end
if ~isfield(param,'patchSize')
    param.patchSize = 8;
end
[bSize,nBases] = size(s1Dictionary);
nSmp = length(imgDatabase.path);
s1Database = imgDatabase;

% compute the sparse code for each local feature
A = s1Dictionary'*s1Dictionary + 2*param.beta*eye(nBases);
for i = 1:nSmp
    fprintf('--extract the s1 feature...');
    tic;
    fpath = imgDatabase.path{i};
    load(fpath);
    [im_h,im_w] = size(img);
    % make grid sampling appearance patches
    remX = mod(im_w-param.patchSize,param.gridSpacing);
    offsetX = floor(remX/2)+1;
    remY = mod(im_h-param.patchSize,param.gridSpacing);
    offsetY = floor(remY/2)+1;

    [gridX,gridY] = meshgrid(offsetX:param.gridSpacing:im_w-param.patchSize+1,...
        offsetY:param.gridSpacing:im_h-param.patchSize+1);
   	feaData = zeros(nBases,length(gridX)*length(gridY));
    pCount = 1;
    for j = offsetY:param.gridSpacing:im_h-param.patchSize+1
        for k = offsetX:param.gridSpacing:im_w-param.patchSize+1
            patch = img(j:j+param.patchSize-1,k:k+param.patchSize-1);
            pNorm = norm(patch(:));
            if pNorm > 0
                patch = patch(:)/pNorm; 
                q = -s1Dictionary'*patch;
                feaData(:,pCount) = L1QP_FeatureSign_yang(param.gamma, A, q);
            end
            pCount = pCount+1;
        end
    end
    s1Fea.feaData = sparse(feaData);
    s1Fea.x = gridX(:);
    s1Fea.y = gridY(:);
    s1Fea.height = im_h-param.patchSize+1;
    s1Fea.width = im_w-param.patchSize+1;
    
    [pdir,fname] = fileparts(imgDatabase.path{i});
    seps = findstr(pdir,'\');
    fdir = ['data\s1_',pdir(seps(1)+1:end)];
    if ~isdir(fdir)
        mkdir(fdir);
    end
    fpath = fullfile(fdir,[fname,'.mat']);
    save(fpath,'s1Fea');
    s1Database.path{i} = fpath;
    label(i) = s1Database.label(i);
    disp([num2str(i),' in ',num2str(toc),' seconds;']);
end