function sesInfo = icatb_calibrateComponents(sesInfo, statusHandle)
% Calibrated image maps are computed using the individual image maps and
% time courses.
% Input: sesInfo - structure containing all parameters necessary for group
% ica analysis

if(~exist('sesInfo','var'))
    [P] = icatb_selectEntry('typeEntity', 'file', 'title', 'Select Parameter File', 'filter', '*param*.mat');
    if isempty(P)
        error('Parameter file is not selected for analysis');
    end
    [pathstr,fileName]=fileparts(P);
    outputDir = pathstr;
    % Make sure parameter file exists
    load(P);
    if ~exist('sesInfo', 'var')
        error(['The selected file ', P, ' does not contain the sesInfo variable']);
    end
else
    outputDir = sesInfo.outputDir;
end

if sesInfo.isInitialized == 0
    error('Parameter file has not been initialized');
end

if ~isfield(sesInfo, 'dataType')
    sesInfo.dataType = 'real';
end

if ~exist('statusHandle', 'var')
    statusHandle = [];
end


if ~isempty(statusHandle)

    % get the status handles
    statusData = get(statusHandle, 'userdata');
    statusData.perCompleted = statusData.perCompleted + statusData.unitPerCompleted;
    set(statusHandle, 'userdata', statusData);
    set(statusHandle, 'name', [num2str(round(statusData.perCompleted*100)), '% analysis done']); waitbar(statusData.perCompleted, statusHandle);

end


mask_ind = sesInfo.mask_ind;

[modalityType, dataTitle, compSetFields] = icatb_get_modality;

disp(' ');
disp('---------------------------------------------------------------------');
disp('STARTING TO SCALE COMPONENT SETS');
disp('---------------------------------------------------------------------');

%load defaults
icatb_defaults;
global MAX_SUBJECTS_IN_MEMORY;
global SUBJECT_ICA_INDEX;
global WRITE_COMPLEX_IMAGES;
global FUNCTIONAL_DATA_FILTER;
global SUBJECT_ICA_AN3_FILE;
global SESSION_POSTFIX;
global COMPONENT_NAMING;


inputPrefix = sesInfo.userInput.prefix;

if strcmpi(sesInfo.dataType, 'complex')
    % tag for identifying complex images
    WRITE_COMPLEX_IMAGES = sesInfo.write_complex_images;
end

maxSubjectsInMemory =MAX_SUBJECTS_IN_MEMORY;

%--load reference image
%---------------------------------------------------------
icain=sesInfo.ica_mat_file;
ref = load(fullfile(outputDir, [icain, '.mat']));
refImage = ref.icasig;
refImage = refImage';
clear ref;

if size(refImage, 1) == prod(sesInfo.HInfo.DIM(1:3))
    refImage = refImage(mask_ind, :);
end


%--scale components
%------------------------------------------------------------
fileCount =1;
subFile = [sesInfo.back_reconstruction_mat_file,num2str(fileCount), '.mat'];
load(fullfile(outputDir, subFile));
%load(subFile);
numSets = sesInfo.numOfDataSets;
ses = 1;

%%%%%%%% Test if the data sets have different number of time points %%%
% Count the number of files in each of the datasets
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if isfield(sesInfo, 'flagTimePoints')
    flagTimePoints = sesInfo.flagTimePoints; % get the flag for time points
    diffTimePoints = sesInfo.diffTimePoints;
else
    % get the count of the files
    [diffTimePoints] = icatb_get_countTimePoints(sesInfo.userInput.files);

    % check time points
    checkTimePoints = find(diffTimePoints ~= diffTimePoints(1));

    if ~isempty(checkTimePoints)
        flagTimePoints = 'different_time_points';
    else
        flagTimePoints = 'same_time_points';
    end
    sesInfo.diffTimePoints = diffTimePoints;
    sesInfo.flagTimePoints = flagTimePoints;
end
% end for checking time points

if ~isfield(sesInfo, 'zipContents')
    sesInfo.zipContents.zipFiles = {};
    sesInfo.zipContents.files_in_zip.name = {};
end

for i=1:numSets

    %keep track of session
    if(ses > sesInfo.numOfSess)
        ses = 1;
    end

    %keep track of subject
    subjectNumber = ceil(i/ sesInfo.numOfSess);

    disp(['--Subject ',num2str(subjectNumber),' Session ',num2str(ses),'''s Component Set']);

    % IC
    tempIC = getfield(compSet, compSetFields{1});
    % TC
    tempTC = getfield(compSet, compSetFields{2});

    clear compSet;

    % put components in proper orientation
    if (size(tempTC, 1) > size(tempTC, 2))
        tempTC = tempTC';
    end

    if (size(tempIC, 1) > size(tempIC, 2))
        tempIC = tempIC';
    end

    % get sign of correlation between subject components and reference
    % component
    for compNum = 1:sesInfo.numComp
        subjectImage = detrend(tempIC(compNum, :),0);
        if length(subjectImage) ~= size(refImage, 1)
            subjectImage = subjectImage(mask_ind);
        end
        corSign = sign(refImage(:, compNum)'*subjectImage');
        % check the sign function
        if sign(corSign) == -1
            string = ['  Difference in Sign Between Reference Image and Subject ', num2str(subjectNumber), ' Session ', num2str(ses), ...
                ' Component ', num2str(compNum)];
            disp([string,' -> Changing Sign of component and timecourse']);
            tempIC(compNum, :) = tempIC(compNum, :) * -1;
            tempTC(compNum, :) = tempTC(compNum, :) * -1;
        end
    end
    clear subjectImage;
    drawnow;


    clear compSet;
    [sesInfo, complexInfoRead] = icatb_name_complex_images(sesInfo, 'read');

    if size(tempIC, 2) == prod(sesInfo.HInfo.DIM(1:3))
        tempIC = tempIC(:, mask_ind);
    end

    %scale timecourses and components
    [tempIC, tempTC] = icatb_scaleICA(tempIC, tempTC, sesInfo.inputFiles(i).name, ...
        sesInfo.scaleType, sesInfo.dataType, complexInfoRead, mask_ind);

    % Get var names from compSetfields to store in calibration MAT files
    eval([compSetFields{1}, ' = tempIC;']);
    eval([compSetFields{2}, ' = tempTC;']);

    if ~isempty(statusHandle)

        % get the status handles
        statusData = get(statusHandle, 'userdata');
        statusData.perCompleted = statusData.perCompleted + (statusData.unitPerCompleted / numSets);
        set(statusHandle, 'userdata', statusData);
        set(statusHandle, 'name', [num2str(round(statusData.perCompleted*100)), '% analysis done']); waitbar(statusData.perCompleted, statusHandle);

    end

    if strcmpi(modalityType, 'fmri')

        %--- save data
        if strcmpi(FUNCTIONAL_DATA_FILTER(2:end), '.nii')
            dispStr = ['...saving scaled ica data for subject ', num2str(subjectNumber), ' session ', num2str(ses),...
                ' in nifti format and as matlab file'];
        else
            dispStr = ['...saving scaled ica data for subject ', num2str(subjectNumber), ' session ', num2str(ses),...
                ' in analyze format and as matlab file'];
        end

    else

        dispStr = ['...saving scaled ica data for subject ', num2str(subjectNumber), ' session ', num2str(ses),...
            ' as matlab file'];

    end

    disp(dispStr);

    % save data in matlab file
    subFileOut = [sesInfo.calibrate_components_mat_file, num2str(subjectNumber), '-', num2str(ses), '.mat'];
    subFileOut = fullfile(outputDir, subFileOut);
    drawnow;

    icatb_save(subFileOut, compSetFields{:});

    eval(['clear ', compSetFields{1}, ' ', compSetFields{2}]);

    subIndex = icatb_returnFileIndex(subjectNumber);
    sessIndex = num2str(ses);

    %save individual images in analyze file
    if(sesInfo.numOfSub ==1 & sesInfo.numOfSess == 1)
        outfile=sesInfo.icaOutputFiles(1).ses(ses).name(1,:);
    elseif(sesInfo.numOfSub ==1 & sesInfo.numOfSess > 1)
        %outfile = sesInfo.icaOutputFiles(2).ses(ses).name(1,:);
        outfile = [inputPrefix, SUBJECT_ICA_AN3_FILE, '01', COMPONENT_NAMING, SESSION_POSTFIX, sessIndex, '_'];
    else
        %outfile = sesInfo.icaOutputFiles(SUBJECT_ICA_INDEX+subjectNumber-1).ses(ses).name(1,:);
        outfile = [inputPrefix, SUBJECT_ICA_AN3_FILE, subIndex, COMPONENT_NAMING, SESSION_POSTFIX, sessIndex, '_'];
    end

    %outfile = strrep(outfile,'.img','');
    % naming of complex images
    [sesInfo, complexInfo] = icatb_name_complex_images(sesInfo, 'write');

    % global variable necessary for defining the real&imag or magnitude&phase
    WRITE_COMPLEX_IMAGES = sesInfo.userInput.write_complex_images;
    
    if strcmpi(modalityType, 'fmri')

        [fileNames, zipFileName, files_in_zip] = icatb_saveICAData(outfile, tempIC, tempTC, mask_ind, sesInfo.numComp, ...
            sesInfo.HInfo, sesInfo.dataType, complexInfo, outputDir);

        if ~isempty(sesInfo.zipContents.zipFiles)
            % store the zip filenames to a structure
            countZip = length(sesInfo.zipContents.zipFiles) + 1;
            sesInfo.zipContents.zipFiles{countZip} = zipFileName;
            sesInfo.zipContents.files_in_zip(countZip).name = files_in_zip;
        end

    end

    clear tempTC tempIC;

    %load next subject's file
    if(i ~= numSets)
        fileCount = fileCount + 1;
        subFile = [sesInfo.back_reconstruction_mat_file,num2str(fileCount), '.mat'];
        load(fullfile(outputDir, subFile));
    end

    %increment session number
    ses = ses + 1;

end


[pp, fileName] = fileparts(sesInfo.userInput.param_file);
drawnow;
icatb_save(fullfile(outputDir, [fileName, '.mat']), 'sesInfo');

disp('---------------------------------------------------------------------');
disp('DONE SCALING COMPONENTS');
disp('---------------------------------------------------------------------');
disp(' ');

if ~isempty(statusHandle)

    % get the status handles
    statusData = get(statusHandle, 'userdata');
    statusData.perCompleted = statusData.perCompleted + statusData.unitPerCompleted;
    set(statusHandle, 'userdata', statusData);
    set(statusHandle, 'name', [num2str(round(statusData.perCompleted*100)), '% analysis done']); waitbar(statusData.perCompleted, statusHandle);

end