function fmri_pls_analysis(varargin)
%
%  USAGE: 
%          fmri_pls_analysis
%    or    fmri_pls_analysis(SessionProfiles,ContrastFile, ...
%                              num_perm,num_boot,grp_analysis_flg,output_file)
%
%    Apply PLS on the fMRI data based on the session information saved in
%    the "sessionFile".  Assume session information, and st_datamat have 
%    been created.
%
%
%  INPUT:
%    SessionProfiles - a cell array, one element per group.  Each element 
%               in the array is another cell array contains the names of 
%               session profiles for the group.
%    ContrastFile - the contrast file to be used to generate the design matrix.
%                   Helmert matrix will be specified using the string of
%                   'HELMERT'.  If contrast is empty, use deviation from 
%                   grand mean for the contrast.
%    num_perm - number of permutations to be performed.
%    num_boot - number of bootstrap resampling to be performed.
%    grp_analysis_flg - flag indicates group analysis.
%    output_file - (optional) the name of output file
%
%                  
%  OUTPUT FILE:
%         - file stores the information of the PLS result.
%
%  NOTE:
%    To create session information, use 'pls_input_session_info'.
%    To create st_datamat, use 'fmri_gen_datamat', 'fmri_combine_coords',
%       and 'fmri_gen_st_datamat'.
%
%  Script needed: fmri_perm_test.m, fmri_deviation_perm_test.m
%
%   -- Created July 2001 by Wilkin Chau, Rotman Research Institute
%

  if (nargin == 0),
     [SessionProfiles,ContrastFile,num_perm,group_analysis] = options_query;
  else
     SessionProfiles = varargin{1};
     ContrastFile = varargin{2};
     num_perm = varargin{3};
     num_boot = varargin{4};
     Clim = varargin{5};
     posthoc = varargin{6};
     save_datamat = varargin{7};
     group_analysis = varargin{8};
     cond_selection = varargin{9};
     behavname = varargin{10};
     behavdata = varargin{11};
     behavdata_lst = varargin{12};
     if (nargin > 12)
        output_file = varargin{13};
     end;
  end;

  session_files_timestamp = SessionProfiles;
  datamat_files_timestamp = SessionProfiles;

  for i = 1:length(SessionProfiles)
     for j = 1:length(SessionProfiles{i})
        tmp = dir(SessionProfiles{i}{j});
        session_files_timestamp{i}{j} = tmp.date;

        load(SessionProfiles{i}{j},'session_info');
        datamat_prefix = session_info.datamat_prefix;

        if findstr('BfMRIsession.mat', SessionProfiles{i}{j})
           datamat_file = [datamat_prefix,'_BfMRIdatamat.mat'];
        else
           datamat_file = [datamat_prefix,'_fMRIdatamat.mat'];
        end

        tmp = dir(datamat_file);
        datamat_files_timestamp{i}{j} = tmp.date;

        if datenum(session_files_timestamp{i}{j}) > datenum(datamat_files_timestamp{i}{j})
%           msg = ['Datamat file "', datamat_file, '" is older than session '];
%           msg = [msg, 'file "', SessionProfiles{i}{j}, '". So the datamat file '];
%           msg = [msg, 'needs to be re-generated.'];

%           uiwait(msgbox(msg, 'Error', 'modal'));

           msg1 = ['Datamat file "', datamat_file, '" is older than session '];
           msg1 = [msg1, 'file "', SessionProfiles{i}{j}, '".'];
           msg2 = 'If you believe that the session file is just touched (e.g. due to copy) but not modified, you can click "Proceed".';
           msg3 = 'Otherwise, please click "Stop", and re-generate the datamat file.';

           quest = questdlg({msg1 '' msg2 '' msg3 ''}, 'Choose','Proceed','Stop','Stop');

           if strcmp(quest,'Stop')
              return;
           end
        end
     end
  end

  %  save results
  %
  if exist('output_file','var') & ~isempty(output_file)
    resultFile = output_file;
  else

    fn = SessionProfiles{1}{1};
    load(fn,'session_info');
    datamat_prefix = session_info.datamat_prefix;

    if findstr('BfMRIsession.mat', fn)
       [result_file,result_path] = ...
		uiputfile([datamat_prefix,'_BfMRIresult.mat'],'Saving PLS Result');
    else
       [result_file,result_path] = ...
		uiputfile([datamat_prefix,'_fMRIresult.mat'],'Saving PLS Result');
    end

    if isequal(result_file,0)			% Cancel was clicked
%%       if findstr('BfMRIsession.mat', fn)
%%          resultFile = 'BfMRIresult.mat';
%%       else
%%          resultFile = 'fMRIresult.mat';
%%       end
%
%       msg1 = ['WARNING: No file is saved.'];
%       msgbox(msg1,'Uncompleted');
%       resultFile = [];
%       disp('ERROR: Result file is not saved.');
       return;
    else
       resultFile = fullfile(result_path,result_file);
    end;
  end;

  progress_hdl = ShowProgress('initialize');

  if isempty(ContrastFile),                         % none: use deviation
     ContrastMethod = 1;
  elseif strcmp('HELMERT',upper(ContrastFile))      % use Helmert matrix
     ContrastMethod = 2;
  elseif strcmp('BEHAV',upper(ContrastFile))        % behav
     ContrastMethod = 4;
  else
     ContrastMethod = 3;                            % design with contrast file
  end;

  if isempty(behavdata)
     [st_datamat,st_coords,st_dims,num_conditions,st_evt_list, ...
	st_win_size,st_voxel_size,st_origin,subj_group,behavdata,behavname, ...
		subj_name, cond_name, num_behav_subj, ...
		behavdata_lst, newdata_lst, num_subj_lst ] = ...
		concat_st_datamat(SessionProfiles,progress_hdl,ContrastMethod, ...
		posthoc, cond_selection, group_analysis);
  else
     [st_datamat,st_coords,st_dims,num_conditions,st_evt_list, ...
	st_win_size,st_voxel_size,st_origin,subj_group, ...
		subj_name, cond_name, num_behav_subj, ...
		newdata_lst, num_subj_lst ] = ...
		concat_st_datamat2(SessionProfiles,progress_hdl,ContrastMethod, ...
		posthoc, behavdata, cond_selection);
  end

  if (group_analysis == 0)
     subj_group = [];		% for nongroup analysis
  end;

  if isempty(st_datamat),
	return;
  end;

  %  get the contrast 
  %
  switch  (ContrastMethod) 
     case {1}
        USE_DEVIATION_PERM_TEST = 1;
	isbehav = 0;
        ContrastFile = 'NONE';
     case {2}
        USE_DEVIATION_PERM_TEST = 0;
	isbehav = 0;
        contrasts = rri_helmert_matrix(num_conditions);
     case {3}
        USE_DEVIATION_PERM_TEST = 0;
	isbehav = 0;
        contrasts = load(ContrastFile);
     case {4}
        USE_DEVIATION_PERM_TEST = 0;
	isbehav = 1;
        contrasts = behavdata;
  end;

  create_ver = plsgui_vernum;

  %  start permutation PLS ...
  %

  perm_result = [];
  boot_result = [];
  if (USE_DEVIATION_PERM_TEST)  	% Execute fmri_deviation_perm_test

     if (num_perm > 0) | (num_boot == 0),
        [brainlv,s,designlv,b_scores,d_scores,perm_result,lv_evt_list] = ...
           fmri_deviation_perm_test(st_datamat,num_conditions,st_evt_list, ...
                                   num_perm,subj_group);
     end;

     if (num_boot > 0),
        [brainlv,s,designlv,b_scores,d_scores,boot_result,lv_evt_list] = ...
           fmri_deviation_boot_test(st_datamat,num_conditions,st_evt_list, ...
                                   num_boot, subj_group);
     end;

     saved_info=['brainlv s designlv perm_result boot_result st_coords ', ...
  	         'st_dims lv_evt_list st_win_size st_voxel_size st_origin ', ...
		 'SessionProfiles ContrastFile b_scores d_scores ', ...
		 'subj_group num_conditions cond_name cond_selection ', ...
		 'num_subj_lst subj_name session_files_timestamp ', ...
		 'datamat_files_timestamp create_ver'];

     if save_datamat & ~isempty(brainlv)
        first = 1;
        last = 0;
        grp_datamat = [];
        for g = 1:length(num_subj_lst)
           last = last + num_conditions*num_subj_lst(g);
           [tmp idx] = sort(st_evt_list(first:last));
           tmp = st_datamat(first:last,:);
           grp_datamat = [grp_datamat; tmp(idx,:)];
           first = last + 1;
        end;
        
        st_datamat = grp_datamat;
        saved_info = [saved_info, ' st_datamat'];
     end

  else					% Execute fmri_perm_test

     if (isbehav)			% Behavior Analysis

        if (num_perm > 0) | (num_boot == 0),
           [brainlv,s,behavlv,brainscores,behavscores,lvcorrs, ...
		origpost,perm_result,behavdata,lv_evt_list,datamatcorrs_lst] = ...
			fmri_perm_behav(st_datamat,contrasts,st_evt_list, ...
			behavdata_lst, newdata_lst, num_subj_lst, ...
			num_perm,num_conditions,num_behav_subj,posthoc);
        end;

        if (num_boot > 0),
           if num_perm == 0, origpost = []; end;
           [brainlv,s,behavlv,brainscores,behavscores,lvcorrs, ...
		boot_result,behavdata,lv_evt_list,datamatcorrs_lst] = ...
			fmri_boot_behav(st_datamat,contrasts,st_evt_list, ...
			behavdata_lst, newdata_lst, num_subj_lst, ...
			num_boot,num_conditions,num_behav_subj,Clim);
        end;

        saved_info=['brainlv s behavlv brainscores behavscores lvcorrs ', ...
			'origpost perm_result boot_result st_coords ', ...
			'behavdata behavname datamatcorrs_lst ', ...
			'num_conditions subj_name cond_name cond_selection ', ...
			'st_dims lv_evt_list st_win_size st_voxel_size ', ...
			'subj_group behavdata_lst num_subj_lst ', ...
			'st_origin SessionProfiles ContrastFile ', ...
			'session_files_timestamp datamat_files_timestamp ', ...
			'create_ver'];

        if save_datamat & ~isempty(brainlv)
            first = 1;
            last = 0;
            grp_datamat = [];
            for g = 1:length(num_subj_lst)
               last = last + num_conditions*num_subj_lst(g);
               [tmp idx] = sort(st_evt_list(first:last));
               tmp = st_datamat(first:last,:);
               grp_datamat = [grp_datamat; tmp(idx,:)];
               first = last + 1;
            end;
        
            st_datamat = grp_datamat;
            saved_info = [saved_info, ' st_datamat'];
        end

     else

        [brainlv,s,designlv,b_scores,d_scores,lvintercorrs,design, ...
            perm_result,boot_result,lv_evt_list] = ...
		fmri_taskpls_norotate(st_datamat,contrasts,num_conditions,...
			st_evt_list,num_boot,num_perm,subj_group);

        saved_info=['brainlv s designlv perm_result boot_result st_coords ', ...
  	         'st_dims lv_evt_list st_win_size st_voxel_size st_origin ', ...
                 'SessionProfiles ContrastFile b_scores d_scores design ', ...
		 'subj_group num_conditions cond_name cond_selection ', ...
		 'num_subj_lst subj_name lvintercorrs design ', ...
		 'session_files_timestamp datamat_files_timestamp create_ver'];

        if save_datamat & ~isempty(brainlv)
            first = 1;
            last = 0;
            grp_datamat = [];
            for g = 1:length(num_subj_lst)
               last = last + num_conditions*num_subj_lst(g);
               [tmp idx] = sort(st_evt_list(first:last));
               tmp = st_datamat(first:last,:);
               grp_datamat = [grp_datamat; tmp(idx,:)];
               first = last + 1;
            end;
        
            st_datamat = grp_datamat;
            saved_info = [saved_info, ' st_datamat'];
        end

     end

  end;

  %  Requested by Nancy, because they no longer use "dp" or "dprob" to evaluate
  %  designlv
  %
  if ~isempty(perm_result) & ~isbehav
     perm_result = rmfield(perm_result, 'dp');
     perm_result = rmfield(perm_result, 'designlv_prob');
  end

  if exist('progress_hdl','var') & ishandle(progress_hdl)

     progress_bar = getappdata(gcf,'ProgressBar');
     set(progress_bar,'Position',[0 0 1 1],'Visible','on');

  end

  if isempty(brainlv)
     done = 1;
  else
     done = 0;
  end

  while ~done
    try
       eval(['save ' resultFile ' ' saved_info]);
       done = 1;
    catch
       if findstr('BfMRIsession.mat', fn)
          [result_file,result_path] = uiputfile('*BfMRIresult.mat', ...
			'Can not write file, please try again',350,150);
       else
          [result_file,result_path] = uiputfile('*fMRIresult.mat', ...
			'Can not write file, please try again',350,150);
       end

       if isequal(result_file,0)		% Cancel was clicked
          resultFile = [];
          msg1 = ['WARNING: No file is saved.'];
%          uiwait(msgbox(msg1,'Uncompleted','modal'));
          return;
       else
          resultFile = fullfile(result_path,result_file);
       end;
    end
  end

  return; 					% fmri_pls_analysis


%-------------------------------------------------------------------------
function contrasts = load_contrast_file(contrastFile)

  load(contrastFile);

  num_contrasts = length(pls_contrasts);
  num_conditions = length(pls_contrasts(1).value);

  contrasts = zeros(num_conditions,num_contrasts);
  for i=1:num_contrasts,
     contrasts(:,i) = pls_contrasts(i).value';
  end;

  return;					% get_contrast


%-------------------------------------------------------------------------
function  [SessionProfiles,ContrastFile,num_perm,single_subj] = options_query()

  %  get the session profiles
  %
  num_session = 0;
  not_done = 1;
  while (not_done)
     msg = [ '\nEnter the name of file contains the session information ', ...
             '(Press <Enter> when done): '];
     sessionFile = input(msg,'s');

     if (isempty(sessionFile))
        not_done = 0;
     else
        if sessionFile(1) ~= '/',
            sessionFile = sprintf('%s/%s',pwd,sessionFile);
        end;
        num_session = num_session + 1;
        SessionProfiles{num_session} = sessionFile;
     end;
  end;


  msg = ['\nEnter the contrast file: ', ...
         '\n   (Type "HELMERT" for Helmert matrix or ', ...
         '\n    press <Enter> to use deviation from grand mean) '];
  ContrastFile = input(msg,'s');

  %  get the number of iterations for the permutation test 
  %
  num_perm = input('\nNumber of permutations: ');


  %  single subject analysis ?
  %
  single_subj_ans=input('\nDoes the data come from single subject? [Y/N] ','s');
  if (upper(single_subj_ans) == 'Y')
     single_subj = 1;
  else
     single_subj = 0;
  end;

  return;					% options_query


%-------------------------------------------------------------------------
function hdl = ShowProgress(progress_hdl,info)

  %  'initialize' - return progress handle if any
  %
  if ischar(progress_hdl) & strcmp(lower(progress_hdl),'initialize'),
     if ~isempty(gcf) & isequal(get(gcf,'Tag'),'ProgressFigure'),
         hdl = gcf;
     else
         hdl = [];
     end;
     return;
  end;


  if ~isempty(progress_hdl)
     if ischar(info)
         rri_progress_status(progress_hdl,'Show_message',info);
     else
         rri_progress_status(progress_hdl,'Update_bar',info);
     end;
     return;
  end;

  if ischar(info),
     disp(info)
  end;

  return;					% ShowProgress


%-------------------------------------------------------------------------
function [new_st_datamat, new_st_coords, st_dims, num_conditions, new_evt_list, ...
	    win_size, voxel_size, origin, subj_group, ...
			subj_name, curr_conditions, num_behav_subj, ...
			newdata_lst, num_subj_lst ] = ...
    			concat_st_datamat2(SessionProfiles,progress_hdl,ContrastMethod, ...
			posthoc, behavdata, cond_selection)
%
%
  newdata_lst = {};
  num_subj_lst = [];

  new_st_datamat = [];			%  stacked datamat
  new_st_coords = [];
  st_dims = [];
  num_conditions = [];
  new_evt_list = [];
  new_evt_list_lst = {};
  win_size = [];
  voxel_size = [];
  origin = [];
  subj_group = [];
  subj_name = {};
  curr_conditions = {};
  num_behav_subj = [];
  num_behavdata_col = size(behavdata,2);

  msg = sprintf('Merging datamats ...');
  ShowProgress(progress_hdl,msg);

  num_groups = length(SessionProfiles);

  profile_list = [];
  session_group = zeros(1,num_groups);
  for i=1:num_groups,
     session_group(i) = length(SessionProfiles{i});
     profile_list = [profile_list; SessionProfiles{i}];
  end;
  num_profiles = length(profile_list);

  st_info = cell(1,num_profiles);

  %  get the coords ...
  %
  total_evts = 0;
  subj_group = zeros(1,num_groups);
  cnt = 0;

  fn = SessionProfiles{1}{1};

  for i=1:num_groups,
    for j=1:session_group(i),
       cnt = cnt+1;

       ShowProgress(progress_hdl,cnt/(num_profiles*10));
       msg = sprintf('Loading datamat: %d out of %d',cnt,num_profiles);
       ShowProgress(progress_hdl,msg);

       sessionFile = profile_list{cnt};
       load(sessionFile);
       curr_conditions = session_info.condition;

        %  get the st_datamat and st_evt_list 
        %
        datamat_prefix = session_info.datamat_prefix;

        if findstr('BfMRIsession.mat', fn)
           st_datamatFile = sprintf('%s_BfMRIdatamat.mat',datamat_prefix);
        else
           st_datamatFile = sprintf('%s_fMRIdatamat.mat',datamat_prefix);
        end

%        st_datamatFile = fullfile(session_info.pls_data_path,st_datamatFile);

        curr = pwd;
        if isempty(curr)
           curr = filesep;
        end

        st_datamatFile = fullfile(curr,st_datamatFile);
   
	try
           warning off;

           load(st_datamatFile,'st_coords','st_dims','st_evt_list', ...
			'st_win_size','st_voxel_size','st_origin');
           warning on;
	catch
	   disp(sprintf('ERROR: cannot open data file: %s',st_datamatFile));
	   new_st_datamat = [];
	   return;   
	end;

        st_info{cnt}.sessionFile = sessionFile;
        st_info{cnt}.datamatFile = st_datamatFile;
        st_info{cnt}.num_cond = session_info.num_conditions;
        st_info{cnt}.coords = st_coords;
        st_info{cnt}.dims = st_dims;
        st_info{cnt}.evt_list = st_evt_list;
        st_info{cnt}.win_size = st_win_size;
        st_info{cnt}.voxel_size = st_voxel_size;
        st_info{cnt}.origin = st_origin;

        num_evts = length(st_evt_list);
        total_evts = total_evts + num_evts;
        subj_group(i) = subj_group(i) + num_evts/length(curr_conditions);
   
        if (cnt > 1),	% make sure the st_datamat are compatible
           if (st_info{cnt-1}.dims ~= st_info{cnt}.dims),
              msg = 'The datamats have different volume dimension.';
              ShowProgress(progress_hdl,['ERROR: ', msg]);
disp(msg);
              return;
           end;
   
           if (st_info{cnt-1}.win_size ~= st_info{cnt}.win_size),
              msg = 'The datamats have different window size.';
              ShowProgress(progress_hdl,['ERROR: ', msg]);
disp(msg);
              return;
           end;

           if (st_info{cnt-1}.dims ~= st_info{cnt}.dims),
              msg = 'The datamats have different volume dimension.';
              ShowProgress(progress_hdl,['ERROR: ', msg]);
disp(msg);
              return;
           end;

           if (st_info{cnt-1}.voxel_size ~= st_info{cnt}.voxel_size),
              msg = 'The datamats have different voxel size.';
              ShowProgress(progress_hdl,['ERROR: ', msg]);
disp(msg);
              return;
           end;
   
           if ~isequal(curr_conditions,prev_conditions)
              msg='The datamats are created from different conditions.';
              ShowProgress(progress_hdl,['ERROR: ', msg]);
disp(msg);
              return;
           end;
        end;  % (cnt > 1)
   
        prev_conditions = curr_conditions;
   
    end;
  end;

  clear st_datamat;

  num_conditions = length(curr_conditions);  
  st_dims = st_info{1}.dims; 

  %  determine the common coords ...
  %
  m = zeros(1,prod(st_info{1}.dims));
  for i=1:num_profiles
     m(st_info{i}.coords) = m(st_info{i}.coords) + 1;
  end;
  new_st_coords = find(m == num_profiles);

  if isempty(new_st_coords)
     disp('ERROR: no common coords among datamats!');
     new_st_datamat = [];
     return;
  end

  %  stack the st_datamat together
  %
  win_size = st_info{1}.win_size;
  voxel_size = st_info{1}.voxel_size;

  if isempty(st_info{1}.origin) | isequal(st_info{1}.origin,[0 0 0]),
     origin = floor(st_dims([1 2 4])/2); 
  else
     origin = st_info{1}.origin;
  end;

  num_voxels = length(new_st_coords);
  new_st_datamat = zeros(total_evts,num_voxels*win_size);
  first_row = 1;

  first_cond_order = [];

  %  go through each subject, which is represented by each profile
  %
%  for i=1:num_profiles,

  tmp_new_st_datamat = [];
  cnt=0;

  for i=1:num_groups,

    grp_tmp_new_st_datamat = [];
    grp_tmp_new_evt_list = [];
    grp_tmp_new_evt_list = [];
    grp_first_cond_order = [];

    for j=1:session_group(i),
       cnt = cnt+1;

       ShowProgress(progress_hdl,cnt/(num_profiles*10)+1/10);

       load(st_info{cnt}.datamatFile);

       coord_idx = find( m(st_info{cnt}.coords) == num_profiles ); 
       nr = length(st_info{cnt}.evt_list);	% number of runs
       nc = length(st_info{cnt}.coords);
       last_row = nr + first_row - 1; 


if ContrastMethod == 4

       %  stack behavdata and get behavmask (re-order for each session file
       %  to make it 'each condition in each run (yes, reversed)'
       %
       behavmask = 1:size(st_datamat,1);

       %  nrr could be nr, depend on 'across run' or 'within run'
       %
       nrr = size(st_datamat,1) / num_conditions;

       behavmask = reshape(behavmask, [nrr, num_conditions]);
       behavmask = behavmask';
       behavmask = reshape(behavmask, [size(st_datamat,1),1]);

end


       this_subj_order = zeros(1, nr);
       first_cond = 1;
       jj = 1;

       %  get first_cond of each run
       %
       while first_cond <= nr
          this_subj_order(first_cond) = 1;
          first_cond = first_cond + num_conditions;

          subj_name = [subj_name, {['Subj', num2str(cnt), 'Run', num2str(jj)]}];

          jj = jj + 1;					% next run
       end
     
       first_cond_order = [first_cond_order, this_subj_order];
       grp_first_cond_order = [grp_first_cond_order, this_subj_order];	% for behavpls

% end


       %  stack datamat
       %
       tmp_datamat = reshape(st_datamat,[nr,win_size,nc]);
       tmp_new_st_datamat = ...
		reshape(tmp_datamat(:,:,coord_idx),[nr,win_size*num_voxels]);
       tmp_evt_list = st_info{cnt}.evt_list;

       %  intentionally reverse the order to each condition in each run, if behavpls
       %  because in behavpls, the whole thing will be then re-order again
       %
       if ContrastMethod == 4				% behavpls
          tmp_new_st_datamat = tmp_new_st_datamat(behavmask,:);
          tmp_evt_list = tmp_evt_list(behavmask);
       end

       grp_tmp_new_st_datamat = [grp_tmp_new_st_datamat; tmp_new_st_datamat];
       grp_tmp_new_evt_list = [grp_tmp_new_evt_list, tmp_evt_list];
       new_st_datamat(first_row:last_row,:) = tmp_new_st_datamat;	% stacked datamat

       clear st_datamat tmp_datamat;

       new_evt_list = [new_evt_list st_info{cnt}.evt_list];


       first_row = last_row + 1;

    end;				% session_group j

    if ContrastMethod == 4				% behavpls

       grp_subj_mask = [];

       for ii = 1:num_conditions
          grp_subj_mask = [grp_subj_mask, find(grp_first_cond_order)];
          grp_first_cond_order = [grp_first_cond_order(end), grp_first_cond_order(1:end-1)];
       end

       grp_tmp_new_st_datamat = grp_tmp_new_st_datamat(grp_subj_mask,:);
       grp_tmp_new_evt_list = grp_tmp_new_evt_list(grp_subj_mask);

       newdata_lst{i} = grp_tmp_new_st_datamat;
       num_subj_lst(i) = sum(grp_first_cond_order);
       new_evt_list_lst{i} = grp_tmp_new_evt_list;

    end

  end					% num_group i

  num_behav_subj = sum(first_cond_order);


  %  Deselect Conditions
  %
  num_conditions = sum(cond_selection);
  curr_conditions = curr_conditions(find(cond_selection));


  if ContrastMethod == 4				% behavpls

     for i = 1:length(new_evt_list_lst)

        tmp_new_evt_list = new_evt_list_lst{i};

        [mask, tmp_new_evt_list, evt_length] = ...
		fmri_mask_evt_list(tmp_new_evt_list, cond_selection);

        new_evt_list_lst{i} = tmp_new_evt_list;

        new_st_datamat = newdata_lst{i};
        newdata_lst{i} = new_st_datamat(mask,:);

     end


     new_st_datamat = [];
     new_evt_list = [];

     for i=1:num_groups,
        new_st_datamat = [new_st_datamat; newdata_lst{i}];
        new_evt_list = [new_evt_list new_evt_list_lst{i}];
     end

  else

     [mask, new_evt_list, evt_length] = ...
	fmri_mask_evt_list(new_evt_list, cond_selection);

     new_st_datamat = new_st_datamat(mask,:);

  end

  %  validate posthoc data
  %
  if ~isempty(posthoc)
     [r_posthoc,c_posthoc] = size(posthoc);
     if r_posthoc ~= num_behavdata_col * num_conditions * num_groups
        msg = sprintf('Rows in Posthoc data file do not match.');
        ShowProgress(progress_hdl,['ERROR: ', msg]);
        uiwait(msgbox(msg,'ERROR','modal'));
        new_st_datamat = [];
        return;
     end
  end

  return;					% concat_st_datamat2


%-------------------------------------------------------------------------
function [new_st_datamat, new_st_coords, st_dims, num_conditions, new_evt_list, ...
	    win_size, voxel_size, origin, subj_group, new_behavdata, behavname, ...
			subj_name, curr_conditions, num_behav_subj, ...
			behavdata_lst, newdata_lst, num_subj_lst ] = ...
    			concat_st_datamat(SessionProfiles,progress_hdl,ContrastMethod, ...
			posthoc,cond_selection,group_analysis)
%
%
  behavdata_lst = {};
  newdata_lst = {};
  num_subj_lst = [];

  new_st_datamat = [];			%  stacked datamat
  new_st_coords = [];
  st_dims = [];
  num_conditions = [];
  new_evt_list = [];
  new_evt_list_lst = {};
  win_size = [];
  voxel_size = [];
  origin = [];
  subj_group = [];
  new_behavdata = [];			%  stacked behavdata
  subj_name = {};
  curr_conditions = {};
  num_behav_subj = [];

  msg = sprintf('Merging datamats ...');
  ShowProgress(progress_hdl,msg);

  num_groups = length(SessionProfiles);

  profile_list = [];
  session_group = zeros(1,num_groups);
  for i=1:num_groups,
     session_group(i) = length(SessionProfiles{i});
     profile_list = [profile_list; SessionProfiles{i}];
  end;
  num_profiles = length(profile_list);

  st_info = cell(1,num_profiles);

  %  get the coords ...
  %
  total_evts = 0;
  subj_group = zeros(1,num_groups);
  cnt = 0;

  fn = SessionProfiles{1}{1};

  for i=1:num_groups,
      for j=1:session_group(i),
       cnt = cnt+1;

       ShowProgress(progress_hdl,cnt/(num_profiles*10));
       msg = sprintf('Loading datamat: %d out of %d',cnt,num_profiles);
       ShowProgress(progress_hdl,msg);

       sessionFile = profile_list{cnt};
       load(sessionFile);
       curr_conditions = session_info.condition;

        %  get the st_datamat and st_evt_list 
        %
        datamat_prefix = session_info.datamat_prefix;

        if findstr('BfMRIsession.mat', fn)
           st_datamatFile = sprintf('%s_BfMRIdatamat.mat',datamat_prefix);
        else
           st_datamatFile = sprintf('%s_fMRIdatamat.mat',datamat_prefix);
        end

%        st_datamatFile = fullfile(session_info.pls_data_path,st_datamatFile);

        curr = pwd;
        if isempty(curr)
           curr = filesep;
        end

        st_datamatFile = fullfile(curr,st_datamatFile);

	try
           clear('behavdata');
           warning off;

           load(st_datamatFile,'behavdata','st_coords','st_dims','st_evt_list', ...
			'behavname','st_win_size','st_voxel_size','st_origin');
           warning on;
	catch
	   disp(sprintf('ERROR: cannot open data file: %s',st_datamatFile));
	   new_st_datamat = [];
	   return;   
	end;
	   
        if ~exist('behavdata','var')
%           msg = 'ERROR: The datamats were generated in old version of the ';
%           msg = [msg 'program, you need to generate them again.'];
%           uiwait(msgbox(msg,'ERROR','modal'));
%           new_st_datamat = [];
%           return;
            behavdata = [];
        end

        if ~exist('behavname','var')
            behavname = {};
            for bcol=1:size(behavdata, 2)
               behavname = [behavname, {['behav', num2str(bcol)]}];
            end
        end

        if ContrastMethod == 4 & cnt > 1		% check behavcol among profiles

           if ~isequal(behavname, st_info{cnt-1}.behavname)
              msg = sprintf('behavior data names and columns should be same among datamats.');
              ShowProgress(progress_hdl,['ERROR: ', msg]);
              uiwait(msgbox(msg,'ERROR','modal'));
              new_st_datamat = [];
              return;
           end

        end

        st_info{cnt}.sessionFile = sessionFile;
        st_info{cnt}.datamatFile = st_datamatFile;
        st_info{cnt}.num_cond = session_info.num_conditions;
        st_info{cnt}.coords = st_coords;
        st_info{cnt}.dims = st_dims;
        st_info{cnt}.evt_list = st_evt_list;
        st_info{cnt}.win_size = st_win_size;
        st_info{cnt}.voxel_size = st_voxel_size;
        st_info{cnt}.origin = st_origin;
        st_info{cnt}.behavdata = behavdata;
        st_info{cnt}.behavname = behavname;

        if ContrastMethod == 4	& isempty(behavdata)	% check behavdataempty

            msg = ['ERROR: Behavior data is required'];
            ShowProgress(progress_hdl,['ERROR: ', msg]);
            uiwait(msgbox(msg,'ERROR','modal'));
            new_st_datamat = [];
            return;

        end

        num_evts = length(st_evt_list);
        total_evts = total_evts + num_evts;
        subj_group(i) = subj_group(i) + num_evts/length(curr_conditions);
   
        if (cnt > 1),	% make sure the st_datamat are compatible
           if (st_info{cnt-1}.dims ~= st_info{cnt}.dims),
              msg = 'The datamats have different volume dimension.';
              ShowProgress(progress_hdl,['ERROR: ', msg]);
disp(msg);
              return;
           end;
   
           if (st_info{cnt-1}.win_size ~= st_info{cnt}.win_size),
              msg = 'The datamats have different window size.';
              ShowProgress(progress_hdl,['ERROR: ', msg]);
disp(msg);
              return;
           end;

           if (st_info{cnt-1}.dims ~= st_info{cnt}.dims),
              msg = 'The datamats have different volume dimension.';
              ShowProgress(progress_hdl,['ERROR: ', msg]);
disp(msg);
              return;
           end;

           if (st_info{cnt-1}.voxel_size ~= st_info{cnt}.voxel_size),
              msg = 'The datamats have different voxel size.';
              ShowProgress(progress_hdl,['ERROR: ', msg]);
disp(msg);
              return;
           end;
   
           if ~isequal(curr_conditions,prev_conditions)
              msg='The datamats are created from different conditions.';
              ShowProgress(progress_hdl,['ERROR: ', msg]);
disp(msg);
              return;
           end;
        end;  % (cnt > 1)
   
        prev_conditions = curr_conditions;
   
    end;
  end;

  num_conditions = length(curr_conditions);  
  st_dims = st_info{1}.dims; 

  %  determine the common coords ...
  %
  m = zeros(1,prod(st_info{1}.dims));
  for i=1:num_profiles
     m(st_info{i}.coords) = m(st_info{i}.coords) + 1;
  end;
  new_st_coords = find(m == num_profiles);

  if isempty(new_st_coords)
     disp('ERROR: no common coords among datamats!');
     new_st_datamat = [];
     return;
  end

  %  stack the st_datamat together
  %
  win_size = st_info{1}.win_size;
  voxel_size = st_info{1}.voxel_size;

  if isempty(st_info{1}.origin) | isequal(st_info{1}.origin,[0 0 0]),
     origin = floor(st_dims([1 2 4])/2); 
  else
     origin = st_info{1}.origin;
  end;

  num_voxels = length(new_st_coords);
%  new_st_datamat = zeros(total_evts,num_voxels*win_size);
  new_evt_list = [];
  first_row = 1;

  first_cond_order = [];

  num_behavdata_col = size(st_info{1}.behavdata,2);

if(0)
  num_behavdata_col = 99999;

  for i=1:num_profiles,
     tmp_col = size(st_info{i}.behavdata,2);
     if tmp_col < num_behavdata_col
        num_behavdata_col = tmp_col;
     end
  end
end

  %  go through each subject, which is represented by each profile
  %
%  for i=1:num_profiles,

  tmp_new_st_datamat = [];
  tmp_new_behavdata = [];
  cnt=0;

  for i=1:num_groups,

    grp_tmp_new_st_datamat = [];
    grp_tmp_new_evt_list = [];
    grp_tmp_new_behavdata = [];
    grp_first_cond_order = [];

    for j=1:session_group(i),
       cnt = cnt+1;

       ShowProgress(progress_hdl,cnt/(num_profiles*10)+1/10);

       load(st_info{cnt}.datamatFile);

       coord_idx = find( m(st_info{cnt}.coords) == num_profiles ); 
       nr = length(st_info{cnt}.evt_list);	% number of runs
       nc = length(st_info{cnt}.coords);
       last_row = nr + first_row - 1; 


if ContrastMethod == 4

       %  stack behavdata and get behavmask (re-order for each session file
       %  to make it 'each condition in each run (yes, reversed)'
       %
       tmp_new_behavdata = st_info{cnt}.behavdata(:,1:num_behavdata_col);

       behavmask = 1:size(tmp_new_behavdata,1);

       %  nrr could be nr, depend on 'across run' or 'within run'
       %
       nrr = size(tmp_new_behavdata,1) / num_conditions;

       behavmask = reshape(behavmask, [nrr, num_conditions]);
       behavmask = behavmask';
       behavmask = reshape(behavmask, [size(tmp_new_behavdata,1),1]);

       tmp_new_behavdata = tmp_new_behavdata(behavmask,:);

       grp_tmp_new_behavdata = [grp_tmp_new_behavdata; tmp_new_behavdata];
       new_behavdata = [new_behavdata; tmp_new_behavdata];		% stacked behavdata

end


       %  get subj_name for designPLS
       %
       this_subj_order = zeros(1, nr);
       first_cond = 1;
       jj = 1;

       %  get first_cond of each run
       %
       while first_cond <= nr
          this_subj_order(first_cond) = 1;
          first_cond = first_cond + num_conditions;

          subj_name = [subj_name, {['Subj', num2str(cnt), 'Run', num2str(jj)]}];

          jj = jj + 1;					% next run
       end
     
       first_cond_order = [first_cond_order, this_subj_order];
       grp_first_cond_order = [grp_first_cond_order, this_subj_order];	% for behavpls

% end


       %  stack datamat
       %
       tmp_datamat = reshape(st_datamat,[nr,win_size,nc]);
       tmp_new_st_datamat = ...
		reshape(tmp_datamat(:,:,coord_idx),[nr,win_size*num_voxels]);
       tmp_evt_list = st_info{cnt}.evt_list;

       %  intentionally reverse the order to each condition in each run, if behavpls
       %  because in behavpls, the whole thing will be then re-order again
       %
       if ContrastMethod == 4				% behavpls
          tmp_new_st_datamat = tmp_new_st_datamat(behavmask,:);
          tmp_evt_list = tmp_evt_list(behavmask);
       end

       grp_tmp_new_st_datamat = [grp_tmp_new_st_datamat; tmp_new_st_datamat];
       grp_tmp_new_evt_list = [grp_tmp_new_evt_list, tmp_evt_list];
%       new_st_datamat(first_row:last_row,:) = tmp_new_st_datamat;	% stacked datamat

       clear st_datamat tmp_datamat;

%       new_evt_list = [new_evt_list st_info{cnt}.evt_list];

       first_row = last_row + 1;

    end;				% session_group j

    [grp_tmp_new_evt_list idx] = sort(grp_tmp_new_evt_list);
    
    new_evt_list = [new_evt_list, grp_tmp_new_evt_list];
    new_st_datamat = [new_st_datamat; grp_tmp_new_st_datamat(idx,:)];

    if ContrastMethod == 4				% behavpls

       grp_subj_mask = [];

       for ii = 1:num_conditions
          grp_subj_mask = [grp_subj_mask, find(grp_first_cond_order)];
          grp_first_cond_order = [grp_first_cond_order(end), grp_first_cond_order(1:end-1)];
       end

       grp_tmp_new_behavdata = grp_tmp_new_behavdata(grp_subj_mask,:);
       grp_tmp_new_st_datamat = grp_tmp_new_st_datamat(grp_subj_mask,:);
       grp_tmp_new_evt_list = grp_tmp_new_evt_list(grp_subj_mask);

       behavdata_lst{i} = grp_tmp_new_behavdata;
       newdata_lst{i} = grp_tmp_new_st_datamat;
       num_subj_lst(i) = sum(grp_first_cond_order);
       new_evt_list_lst{i} = grp_tmp_new_evt_list;

    end

  end					% num_group i

  num_behav_subj = sum(first_cond_order);


  %  Deselect Conditions
  %
  num_conditions = sum(cond_selection);
  curr_conditions = curr_conditions(find(cond_selection));


  if ContrastMethod == 4				% behavpls

     for i = 1:length(new_evt_list_lst)

        tmp_new_evt_list = new_evt_list_lst{i};

        [mask, tmp_new_evt_list, evt_length] = ...
		fmri_mask_evt_list(tmp_new_evt_list, cond_selection);

        new_evt_list_lst{i} = tmp_new_evt_list;

        new_behavdata = behavdata_lst{i};
        behavdata_lst{i} = new_behavdata(mask,:);

        new_st_datamat = newdata_lst{i};
        newdata_lst{i} = new_st_datamat(mask,:);

     end


     new_behavdata = [];
     new_st_datamat = [];
     new_evt_list = [];

     for i=1:num_groups,
        new_behavdata = [new_behavdata; behavdata_lst{i}];
        new_st_datamat = [new_st_datamat; newdata_lst{i}];
        new_evt_list = [new_evt_list new_evt_list_lst{i}];
     end

  else

     [mask, new_evt_list, evt_length] = ...
	fmri_mask_evt_list(new_evt_list, cond_selection);

     new_st_datamat = new_st_datamat(mask,:);

  end

  %  validate posthoc data
  %
%  if ~isempty(posthoc)
%     [r_posthoc,c_posthoc] = size(posthoc);
%     if r_posthoc ~= num_behavdata_col * num_conditions
%        msg = sprintf('Rows in Posthoc data file do not match.');
%        ShowProgress(progress_hdl,['ERROR: ', msg]);
%        uiwait(msgbox(msg,'ERROR','modal'));
%        new_st_datamat = [];
%        return;
%     end
%  end

%  if group_analysis
%     num_subj_lst = subj_group;
%  else
%     % num_subj_lst = ones(1,subj_group);
%     num_subj_lst = [];
%  end

  num_subj_lst = subj_group;

  return;					% concat_st_datamat

