function [memory_MB memory_GB]=nic_estimate_mem(appConfig)
% Estimate memory to run the analysis
%-------------------------------------------------------------------------
%   Copyright (C) 2009
%   Neuroimage Computing Group, State Key Laboratory of
%   Cognitive Neuroscience and Learning, Beijing normal University
%	Written by Guiwen Chen, modified by Han Zhang @2010/7/18
%	Version=1.0;
%	Release=20091010;
%------------------------------------------------------------------------

% clear all; clc;
% Calculate memory required for computing ICA.
% Input parameters 
if(~isfield(appConfig,'maskInd'))
    voxels=70000;
else
    voxels = length(appConfig.maskInd);
end

% Time points
time_points = appConfig.AppFileList{1,2};
% Number of subjects
numOfSub = length(appConfig.AppSubjectLabels);
% Number of sessions
numOfSess = 1;
% Data reduction steps
numDataReductionSteps =appConfig.dataReduction.pcaStepNum;
% Data reduction step numbers
numOfPC3=0;
numOfPC2=0;

numOfPC1 = appConfig.dataReduction.pcsNum(1);
if(numDataReductionSteps>=2)
    numOfPC2 = appConfig.dataReduction.pcsNum(2);
end
if(numDataReductionSteps>=3)
    numOfPC3 = appConfig.dataReduction.pcsNum(3);
end
% End for input parameters %


% Check for data reduction steps
if (numOfSub*numOfSess > 1 && numOfSub*numOfSess < 4)
    numDataReductionSteps = 2;
end

if (numOfSub*numOfSess > 10)
    numDataReductionSteps = 3;
end

if (numOfSub*numOfSess == 1)
    numDataReductionSteps = 1;
end

if (numDataReductionSteps > 3)
    numDataReductionSteps = 3;
end
% End for checking

disp(['Number of voxels: ', num2str(voxels)]);
disp(['Number of timepoints: ', num2str(time_points)]);
disp(['Number of subjects: ', num2str(numOfSub)]);
disp(['Number of sessions: ', num2str(numOfSess)]);
disp(['Number of data reduction steps: ', num2str(numDataReductionSteps)]);

% Account for temporary matrix when calculating covariance
num_bytes = voxels*time_points*2*8;
disp(['Number of PC1: ', num2str(numOfPC1)]);

if (numDataReductionSteps == 2)
    disp(['Number of PC2: ', num2str(numOfPC2)]);
    temp_bytes = numOfSub*numOfSess*numOfPC1*voxels*8*2;
    num_bytes = max([num_bytes, temp_bytes]);
elseif (numDataReductionSteps == 3)
    disp(['Number of PC2: ', num2str(numOfPC2)]);
    disp(['Number of PC3: ', num2str(numOfPC3)]);
    numGroups2 = ceil(numOfSub*numOfSess/4);

    % PC2
    temp_bytes = 4*numOfPC1*voxels*8*2;
    num_bytes = max([num_bytes, temp_bytes]);

    % PC3
    temp_bytes = numGroups2*numOfPC2*voxels*8*2;
    num_bytes = max([num_bytes, temp_bytes]);

end

% Convert to MB
memory_MB = num_bytes/1024/1024;

% Accounting for calculation of the final component (aggregate ICs for, e.g., 100 times)
memory_MB=memory_MB+0.6*appConfig.runTimes*numOfPC3+2*appConfig.runTimes;

% Accounting for basic memory consume
memory_MB=memory_MB+500;

% Convert to GB
memory_MB=memory_MB/1024;

fprintf('\n');
disp(['Memory required is ', num2str(memory_MB), ' GB']);

memory_GB=numOfSub*appConfig.compNum*0.5*appConfig.runTimes/1024;
disp(['Disk space required is ', num2str(memory_GB), ' GB']);

fprintf('\n');


