function appConfig=nic_rsdd_runAnalysis(appConfig,extParameters)
% Run multiple group-ICA analysis
% Input: 
%	appConfig - structure containing all parameters 
%-----------------------------------------------------------
%   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;
%-----------------------------------------------------------
%


 nic_rsdd_defaults;
 Rand_Mode={'Bootstrap','RandInit','RandOrder'};

 randorderType=appConfig.randMode{3};% order
 % rand mode: bootstap, init,order
 AllSubjectNum=length(appConfig.AppSubjectLabels);
 if(AllSubjectNum==1)
   randorderType=0;  
   appConfig.randMode{3}=randorderType;
 end
 
 cfgFile=fullfile(appConfig.outDir,[appConfig.outPrefix,'_mica_parameter_info.mat']);
if(exist(cfgFile,'file')>0)
    cfg=load(cfgFile);
    if(isfield(cfg.moicacfg,'status'))
        appConfig.status=cfg.moicacfg.status;
    end
end

 if(~isfield(appConfig,'status'))
    appConfig.status.isFinished=0;
    appConfig.status.MultipleRun=1;
    appConfig.status.DataReductionStep=1;
    appConfig.status.RunClustering=1;
    appConfig.status.RunAggregating=1;
    appConfig.status.RunClibration=1;
 else
    if(isfield(appConfig.status,'isFinished') && appConfig.status.isFinished==1)
        appConfig.status.isFinished=0;
        appConfig.status.MultipleRun=1;
        appConfig.status.DataReductionStep=1;
        appConfig.status.RunClustering=1;
        appConfig.status.RunAggregating=1;
        appConfig.status.RunClibration=1;
    else
        appConfig.status.isFinished=0;
    end
 end
 
 % configure the step
if(~exist('extParameters','var'))
    extParameters=struct('MultipleRun',appConfig.status.MultipleRun,'DataReductionStep',appConfig.status.DataReductionStep,...
                         'RunClustering',appConfig.status.RunClustering,'RunAggregating',appConfig.status.RunAggregating,...
                         'RunClibration',appConfig.status.RunClibration,'RunDeleteFolder',1);
else
    if(~isfield(extParameters,'MultipleRun'))
        extParameters.MultipleRun=appConfig.status.MultipleRun;
    end
    if(~isfield(extParameters,'DataReductionStep'))
        extParameters.DataReductionStep=appConfig.status.DataReductionStep;
    end
    if(~isfield(extParameters,'RunClustering'))
        extParameters.RunClustering=appConfig.status.RunClustering;
    end
    if(~isfield(extParameters,'RunAggregating'))
        extParameters.RunAggregating=appConfig.status.RunAggregating;
    end
    if(~isfield(extParameters,'RunClibration'))
        extParameters.RunClibration=appConfig.status.RunClibration;
    end
    if(~isfield(extParameters,'RunDeleteFolder'))
        extParameters.RunDeleteFolder=0;
    end
end

disp(['*****Start to run analysis at ',datestr(now,'yyyy-mm-dd HH:MM:SS'),'*****']);

nic_waitbar(0,sprintf('Multiple-runs constency ICA is running\nwait...'), 'Multiple-runs ICA','Parent');

appConfig=nic_rsdd_preprocess(appConfig);% 1: preprocessing
 
 nic_waitbar(5/100,sprintf('Multiple-runs constency ICA is running\nwait...'), 'Multiple-runs ICA','Parent');
 
 runs=appConfig.runTimes;
 outDir=appConfig.outDir; % directory of output
 
 disp(['*****Start to do data reduction and ICA at ',datestr(now,'yyyy-mm-dd HH:MM:SS'),'*****']);
 
if extParameters.MultipleRun % multiple runs
 for runno=1:runs
     prate=0.2;
     if(randorderType==1 && runno>1)% if randOrder or runTimes>1
         step=2; % do the 2nd step data reduction
     else
         step=extParameters.DataReductionStep; % start to reduce the data from the 1st step    
     end
     
      if(~exist(fullfile(outDir,sprintf('mat%03d',runno)),'dir'))
            mkdir(fullfile(outDir,sprintf('mat%03d',runno)));
      end
     
     datareductionOutDir=sprintf('mat%03d',runno);
     if(randorderType==0)
         datareductionOutDir='mat'; % not multiple order
     end
     
     nic_waitbar(0,sprintf('Data reduction using PCA...'), 'Multiple-runs ICA','Child');
     
     if(randorderType==1 || (runno==1)) % if using randmon order or runno==1
         [appConfig subjectOrder]=nic_rsdd_dataReduction(appConfig,step,randorderType,datareductionOutDir); % 2: data reduction using PCA
         if(step==1)
             prate=0.5;%the progress bar
         else
             prate=0.2;
         end
     end
     nic_waitbar(prate,sprintf('Data reduction using PCA...'), 'Multiple-runs ICA','Child');

     ICAOutDir=sprintf('mat%03d',runno); % the output directory 
     
     nic_waitbar(prate,sprintf('Calculate ICA...'), 'Multiple-runs ICA','Child');
     
     appConfig=nic_rsdd_calcICA(appConfig,datareductionOutDir,ICAOutDir,randorderType); % 3: ICA
     
     nic_waitbar(prate+(1-prate)/3,sprintf('Calculate ICA...'), 'Multiple-runs ICA','Child'); 

     nic_waitbar(prate+(1-prate)/3,sprintf('Back reconstruction...'), 'Multiple-runs ICA','Child'); 
     
     nic_rsdd_backReconstruct(appConfig,datareductionOutDir,ICAOutDir,subjectOrder); % 4: back reconstruction
     
     nic_waitbar(0.98,sprintf('Back reconstruction...'), 'Multiple-runs ICA','Child');
     
     nic_rsdd_deleteMat(appConfig,ICAOutDir); % delete the temporary mat
     
     nic_waitbar(runno/runs*0.7,sprintf('Multiple-runs constency ICA is running\nwait...'), 'Multiple-runs ICA','Parent');
 end
end

% finish the pca and ica
appConfig.status.MultipleRun=0;
saveFile=fullfile(appConfig.outDir,[appConfig.outPrefix,'_mica_parameter_info.mat']);
moicacfg=appConfig;
save(saveFile,'moicacfg');

 disp(['*****Start to do clustering and aggregating at ',datestr(now,'yyyy-mm-dd HH:MM:SS'),'*****']);
 if extParameters.RunClustering
     [labelResult]=nic_rsdd_clusterComponents(appConfig); % 5: clustering
     nic_waitbar(0.78,sprintf('Multiple-runs constency ICA is running\nAggreate components\nwait...'), 'Multiple-runs ICA','Parent');
 end
 
appConfig.status.RunClustering=0;
saveFile=fullfile(appConfig.outDir,[appConfig.outPrefix,'_mica_parameter_info.mat']);
moicacfg=appConfig;
save(saveFile,'moicacfg');

%  
 if extParameters.RunAggregating

     nic_rsdd_aggComp(appConfig);% 6: aggregate the components

     nic_waitbar(0.88,sprintf('Multiple-runs constency ICA is running\nDoing calibarion\nwait...'), 'Multiple-runs ICA','Parent');
 end
   
appConfig.status.RunAggregating=0;
saveFile=fullfile(appConfig.outDir,[appConfig.outPrefix,'_mica_parameter_info.mat']);
moicacfg=appConfig;
save(saveFile,'moicacfg');

%  nic_rsdd_showAggCompRanking(appConfig); % Show the ranking of component

%  view_gui(appConfig); % show component
% %  

if extParameters.RunDeleteFolder
    %  % delete all directories excpet 'mat'
    nic_rsdd_deleteMatDir(appConfig); % delete all directories with name 'mat???'
end

if(extParameters.RunClibration)
    nic_rsdd_calibration(appConfig); % 7: calibration
end

 nic_waitbar(0.95,sprintf('Multiple-runs constency ICA is running\nGroup statistics\nwait...'), 'Multiple-runs ICA','Parent');
 
 %% Output the worst result of a run
 global IsOutputWorstComp;
 if(IsOutputWorstComp)
   nic_rsdd_calibration_worst(appConfig); % 7: calibration
 end
 
 appConfig.status.RunClibration=0;
saveFile=fullfile(appConfig.outDir,[appConfig.outPrefix,'_mica_parameter_info.mat']);
moicacfg=appConfig;
save(saveFile,'moicacfg');

 nic_rsdd_groupStats(appConfig); % 8: group statistics
 nic_waitbar(1,sprintf('Multiple-runs constency ICA is running\nwait...'), 'Multiple-runs ICA','Parent');

 nic_rsdd_classifyGroup(appConfig);% classify the result 
 
%  rmdir(fullfile(appConfig.outDir,sprintf('mat')),'s'); % delete the
%  folder of 'mat'
nic_rsdd_deleteMat(appConfig,'mat'); % delete pca mat


 nic_waitbar; % delete the progress bar
 
 disp(['*****Finish the work at ',datestr(now,'yyyy-mm-dd HH:MM:SS'),'*****']);
 
 disp(['Finish the whole analysis, congragulations...']);
 
 diary off; % close the diary
 
appConfig.status.isFinished=1;
saveFile=fullfile(appConfig.outDir,[appConfig.outPrefix,'_mica_parameter_info.mat']);
moicacfg=appConfig;
save(saveFile,'moicacfg');

 
return;


function nic_rsdd_deleteMat(appConfig,outD)
% delete pca mat after every run    

 delete(fullfile(appConfig.outDir,outD,[appConfig.outPrefix,'_pca*']));
 delete(fullfile(appConfig.outDir,outD,[appConfig.outPrefix,'_ica_c*']));
    
return;


function nic_rsdd_deleteBrMat(appConfig,outD)
% delete back reconstruction mat after every run    

 delete(fullfile(appConfig.outDir,outD,[appConfig.outPrefix,'_ica_br*']));
 
return;

function nic_rsdd_deleteMatDir(appConfig)
% delete all mat*** folder except mat

runs=appConfig.runTimes;

 for runno=1:runs
     rmdir(fullfile(appConfig.outDir,sprintf('mat%03d',runno)),'s');% remove the directory
 end
    
return;

function nic_rsdd_classifyGroup(appConfig)
% Move files to each group
% output
%       --group1
%       --group2

outPrefix=appConfig.outPrefix;
outDir=appConfig.outDir;
labels=appConfig.AppSubjectLabels;
if(~exist(fullfile(outDir,'output'),'dir'))
    mkdir(fullfile(outDir,'output'));
end
ulabel=unique(labels);
if(length(ulabel)>1)
    for i=1:length(ulabel)
        mkdir(fullfile(outDir,'output',sprintf('group%d',i)));
    end
    for i=1:length(labels)
        j=find(ulabel==labels(i));
        str=sprintf([outPrefix,'_sub%03d_component_ica_s1_.zip'],i);
        movefile(fullfile(outDir,str),fullfile(outDir,'output',sprintf('group%d',j),str));
    end
    return;
end

for i=1:length(labels)
   str=sprintf([outPrefix,'_sub%03d_component_ica_s1_.zip'],i);
   movefile(fullfile(outDir,str),fullfile(outDir,'output',str));
end
   
return;


 