function appConfig=nic_rsdd_preprocess(appConfig)
% preprocess of multiple-runs ICA and mask 
% Input:
%	appConfig - structure containing all parameters 
% Output:
%	appConfig: the structure of configuration after preprocessing
%-----------------------------------------------------------
%   Copyright (C) 2009
%   Neuroimage Computing Group, State Key Laboratory of
%   Cognitive Neuroscience and Learning, Beijing normal University
%	Written by Guiwen Chen
%	Version=1.0;
%	Release=20090720;
%-----------------------------------------------------------
%

cfgFile=fullfile(appConfig.outDir,[appConfig.outPrefix,'_mica_parameter_info.mat']);
if(exist(cfgFile,'file')>0)
    cfg=load(cfgFile);
    if(~isfield(cfg.moicacfg,'isInitialized'))
        appConfig.isInitialized=0;
    else
        appConfig.isInitialized=cfg.moicacfg.isInitialized;
    end
end

% automatical estimate the number of ICA
if(isfield(appConfig,'isAutomaticEstimate'))
    if(appConfig.isAutomaticEstimate==1 && appConfig.isInitialized==0)
        nic_waitbar(0,sprintf('Estimate the number of component...'), 'Multiple-runs ICA (Preprocessing)','Child');
        disp(' ');
        disp('------------------------------------------------------------------------------------');
        disp('Estimating the number of component');
        disp('------------------------------------------------------------------------------------');
        try
            estnum=nic_rsdd_estimateCompNum(appConfig);% estimating the number
            appConfig.compNum=estnum;
        catch
            appConfig.isAutomaticEstimate=0;
        end
        disp('Done estimating the number of component');
        disp('------------------------------------------------------------------------------------');
    end
end

if(~isfield(appConfig,'scatter'))
    appConfig.scatter.removeScatter=1;
    appConfig.scatter.scatterThreshold=0.7;
end

outPrefix=appConfig.outPrefix;
outDir=appConfig.outDir;

% read all generate the mask
if(isfield(appConfig,'dataReduction'))
    if(appConfig.dataReduction.samePCWithICA==1)
        for i=1:appConfig.dataReduction.pcaStepNum
            appConfig.dataReduction.pcsNum(i)=appConfig.compNum;
        end
    else
        appConfig.dataReduction.pcsNum(appConfig.dataReduction.pcaStepNum)=appConfig.compNum;
    end
    appConfig.maskType=appConfig.dataReduction.maskType;    
    if(appConfig.maskType==2) % read the specified mask 
        appConfig.maskName=appConfig.dataReduction.MaskFile;
        [maskData]=nic_ReadNiftiImage(appConfig.maskName);
        % determine whether to resample the mask
        
        imageOUT=fullfile(outDir,[outPrefix,'_mask.img']);
        imageREF=deblank(appConfig.AppFileList{1,3}.name(1,:));
        [da,HInfo]=nic_rsdd_loadData(imageREF);
        if(sum(size(da))~=sum(size(maskData)))%resample
            nic_ImageResample(appConfig.maskName,imageOUT,imageREF,1)
            [maskData]=nic_ReadNiftiImage(imageOUT);
            appConfig.maskName=imageOUT;
        end
        
        maskInd=find(maskData==1);
        appConfig.maskInd=maskInd;
    else
        if(exist(fullfile(outDir,[outPrefix,'_mask.mat']),'file')==0) % generating the mask using the first file of every sample
            appConfig.maskType=1;
            [da,HInfo]=nic_rsdd_loadData(deblank(appConfig.AppFileList{1,3}.name(1,:)));
            clear da;
            disp('------------------------------------------------------------------------------------');
            disp('Generating the default mask using the first file of every subject');
            complexInfoRead = struct('complex_file_naming',{'R_'  'I_'},'complexType','real&imaginary');
            nic_waitbar(0,sprintf('Creating mask...'), 'Multiple-runs ICA (Preprocessing)','Child');
            [mask_ind] = nic_icatb_createMask(appConfig.AppFileList(:,3), HInfo, ...
                    'real', 'default', complexInfoRead);
            
            appConfig.maskInd=mask_ind;
            appConfig.maskName=[];
            appConfig.dataReduction.MaskFile=[];
            outPrefix=appConfig.outPrefix;
            outDir=appConfig.outDir;
            save(fullfile(outDir,[outPrefix,'_mask.mat']),'mask_ind');
            % Read mask file
        else % load the exist mask 
            appConfig.maskType=1;

            t=load(fullfile(outDir,[outPrefix,'_mask.mat']));
            appConfig.maskInd=t.mask_ind;
            appConfig.maskName=[];
            appConfig.dataReduction.MaskFile=[];           
        end
    end
else
    error('Please configure the parameter of data reduction');    
end

% Set parameter of data reduction
%
reductionPara=struct();
reductionPara.numOfReductionSteps=appConfig.dataReduction.pcaStepNum;
AllSubjectNum=length(appConfig.AppSubjectLabels);
numOfSubject=AllSubjectNum;
numOfGroup=numOfSubject;
% reductionPara.cfg(1)=struct();

% caculate the parameter of data reduction 
for i=1:reductionPara.numOfReductionSteps
    reductionPara.cfg(i).numOfPCs=appConfig.dataReduction.pcsNum(i); % each dimmension reserved after every step
    
    if(i>1 && i<reductionPara.numOfReductionSteps)
        reductionPara.cfg(i).numSubjectInGroup=appConfig.dataReduction.groupSize(i-1); % the number of subject in every group
    else
        reductionPara.cfg(i).numSubjectInGroup=1;
    end
end

for i=1:reductionPara.numOfReductionSteps
     reductionPara.cfg(i).numOfGroupsAfterCAT=floor(numOfGroup/reductionPara.cfg(i).numSubjectInGroup);% the number of group after every step
     numOfGroup=reductionPara.cfg(i).numOfGroupsAfterCAT;
end

if(reductionPara.numOfReductionSteps>1)
    % the number of subjects in the last step is the left group after 2st
    % step
    reductionPara.cfg(reductionPara.numOfReductionSteps).numSubjectInGroup=reductionPara.cfg(reductionPara.numOfReductionSteps-1).numOfGroupsAfterCAT;
end



reductionPara.cfg(reductionPara.numOfReductionSteps).numOfGroupsAfterCAT=1;% the last group


for i=1:reductionPara.numOfReductionSteps
    numOfSubject=reductionPara.cfg(i).numSubjectInGroup;
    for j=1:reductionPara.cfg(i).numOfGroupsAfterCAT
         reductionPara.cfg(i).numStacked(j)=reductionPara.cfg(i).numSubjectInGroup;         
        if(i>1 && j*numOfSubject<reductionPara.cfg(i-1).numOfGroupsAfterCAT && (j+1)*numOfSubject>reductionPara.cfg(i-1).numOfGroupsAfterCAT)
            reductionPara.cfg(i).numStacked(j)=reductionPara.cfg(i-1).numOfGroupsAfterCAT-(j-1)*numOfSubject;% actual number of group after every step
        end
    end
end


outDir=appConfig.outDir;

runNum=appConfig.runTimes;


% make dir
if(~exist(fullfile(outDir,'mat'),'dir'))
    mkdir(fullfile(outDir,'mat'));
end


appConfig.reductionPara=reductionPara;
appConfig.isInitialized=1;

saveFile=fullfile(appConfig.outDir,[appConfig.outPrefix,'_mica_parameter_info.mat']);
moicacfg=appConfig;
save(saveFile,'moicacfg');

