function generateProjections(pbeDef, targetDimension, caseNameBase, ...
    caseList, runNonlinear)
% generate projection and save it in local database folder
%
% saved data: ./database/<caseName>_<samplePointType>_<approxType>_<targetDim>.matx
% where data contains: dec, cdef, projectionMatrix

% get my location
myPath = fileparts(which(mfilename));

%% PCA projections for all sample data
for iCase = 1:length(caseList)
    % construct file names
    thisLoadFile = [myPath filesep 'data' filesep ...
        caseNameBase '_pointSet_' caseList{iCase} '.matx'];
    thisSaveFile = [myPath filesep 'database' filesep ...
        caseNameBase '_' num2str(targetDimension) '_PCA_' ...
          caseList{iCase} '.matx'];
      
    % cancel if the result was already generated
    if exist(thisSaveFile, 'file')
        continue
    end
    
    % load point set into variable: data
    load(thisLoadFile, '-mat');
    
    % approximation
    disp(['Generating approximation for: ' thisSaveFile]);
    heMatrix = mapToValidityCone(dataPointSet.hcMatrix, pbeDef.dec, 0);
    dataApprox = approximateDec(heMatrix, pbeDef.dec, ...
        'method', 'PCA', ...
        'targetDim', targetDimension);
    disp('..done (approximation).');
    
    % projection of decomposition
    disp(['Projecting decomposition for: ' thisSaveFile]);
    dec = projectDec(pbeDef.dec, dataApprox.mappingReducedToFull, ...
        'zerotol', 1e-7);
    disp('..done (projection).');
    
    % save new decomposition
    dataApprox.dec = dec;
    dataApprox.cdef = pbeDef.dec.cdef;
    save(thisSaveFile, '-mat', 'dataApprox');
end

%% Nonlinear projections
if exist('runNonlinear', 'var') && ~isempty(runNonlinear)
% runNonlinear{1} - name descriptor
% runNonlinear{2} - measureList
for iCase = 1:length(caseList)
    % construct file names
    thisLoadFile = [myPath filesep 'data' filesep ...
        caseNameBase '_pointSet_' caseList{iCase} '.matx'];
    thisSaveFile = [myPath filesep 'database' filesep ...
        caseNameBase '_' num2str(targetDimension) '_' ...
        runNonlinear{1} '_' ...
          caseList{iCase} '.matx'];
      
    % cancel if the result was already generated
    if exist(thisSaveFile, 'file')
        continue
    end
    
    % load point set into variable: data
    load(thisLoadFile, '-mat');
    
    % approximation
    disp(['Generating approximation for: ' thisSaveFile]);
    heMatrix = mapToValidityCone(dataPointSet.hcMatrix, pbeDef.dec, 0);
    dataApprox = approximateDec(heMatrix, pbeDef.dec, ...
        'method', 'nonlinear', ...
        'targetDim', targetDimension, ...
        'measureList', runNonlinear{2}, ...
        'errorType', 'relativeSquared');
    disp('..done (approximation).');
    
    % projection of decomposition
    disp(['Projecting decomposition for: ' thisSaveFile]);
    dec = projectDec(pbeDef.dec, dataApprox.mappingReducedToFull, ...
          'zerotol', 1e-8);
%     dec = addMeasureDataDec(dec, 'volume');
%     dec = addMeasureDataDec(dec, 'surface');
%     dec = addMeasureDataDec(dec, 'meanWidth');
    disp('..done (projection).');
    
    % save new decomposition
    dataApprox.dec = dec;
    dataApprox.cdef = pbeDef.dec.cdef;
    save(thisSaveFile, '-mat', 'dataApprox');
end
end