function mean_vals = gtCreateAbsLive(first_img, last_img, workingdirectory)
% GTCREATEABSLIVE  Flatfield correction, normalisation and 2D medianfiltering to the absorption part
%     mean_vals = gtCreateAbsLive(first_img, last_img, workingdirectory)
%     ------------------------------------------------------------------
%
%     When running it manually for a scan with, for example, 3600 images,
%     choose first_img=0 and last_img=3604 to process the extra few images
%     at the end of the scan.
%
%
%     Version 003 10-04-2014 by PReischig
%       Added capacity to process extra images at end of scan (for checks).
%
%     Version 002 10-11-2011 by LNervo
%       Add comments and clean syntax and warnings
%
%     Sub-functions:
%[sub]- sfPutbb
%[sub]- sfGetbb
%
%     Version 001
%       if the scan has been done as many, broken acquistions, it is easier to the
%       flat-fielding for each partial sequence using sequence_flatfield.  In this
%       case, add a field to parameters:  prep.prior_flatfield.
%       add the possibility to apply a horizontal shift to the images:
%           prep.ydrift
%       live! will wait for files to appear during the acquistion as a single
%       condor job
%
%       add test to wait for images to be translated by gtApplyDrifts before
%       continuing - in edf_wait_read
%       from prep.correct_drift
%
%

disp('gtCreateAbsLive.m')
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% get parameters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% special case for running interactively in current directory
if ~exist('workingdirectory','var')
    workingdirectory = pwd;
end
cd(workingdirectory);

parameters = gtLoadParameters();

acq  = parameters.acq;
prep = parameters.prep;
datadir = fullfile(acq.dir, '0_rawdata', acq.name);

if (isdeployed)
    global GT_DB %#ok<TLEV,NUSED>
    global GT_MATLAB_HOME %#ok<NUSED,TLEV>
    load('workspaceGlobal.mat');
    first_img = str2double(first_img);
    last_img  = str2double(last_img);
end

% do not wait for images to be shifted by gtApplyDrifts - shift them after
% flatfield correction has been performed
waitfortranslated = false;

% if strcmp(prep.correct_drift, 'required')
%     waitfortranslated=parameters.prep.correct_drift_iteration;
% end

%check if flatfielding is required
if (isfield(prep,'prior_flatfield') && prep.prior_flatfield == true)
    do_flatfield = false;
else
    do_flatfield = true;
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% do create abs
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% read the summed dark image and divide it by the number of frames
% we read in the boundingbox prep.bbox, which is slightly bigger than acq.bb
% the extra margin will be used for intensity normalisation of the images
% the saved absorption images will be of size acq.bb
if (do_flatfield)
    darkend_name = fullfile(datadir, 'darkend0000.edf');
    if (~exist(darkend_name, 'file'))
        dark_name = fullfile(datadir, 'dark.edf');
        dark = edf_wait_read(dark_name, prep.bbox, waitfortranslated);
    else
        dark = edf_wait_read(darkend_name, prep.bbox, waitfortranslated) / acq.ndark;
    end
end


refname2old = [];
refname1old = [];
int0 = [];

% required for fullbeam normalisation with parallel processing
if (strcmp(prep.normalisation, 'fullbeam') && (first_img ~= 0))
    % get the intensity of the first_img abs image
    if (do_flatfield)
        refname1 = fullfile(datadir, sprintf('refHST%04d.edf', 0) );
        ref = edf_wait_read(refname1, prep.bbox, waitfortranslated) - dark;
        name = fullfile(datadir, sprintf('%s%04d.edf', acq.name, 0) );
        im = edf_wait_read(name, prep.bbox, waitfortranslated) - dark;
        im = im ./ ref;
    else
        name = fullfile(datadir, sprintf('%sflat_%04d.edf', acq.name,0) );
        im = edf_wait_read(name, prep.bbox, waitfortranslated);
    end
    int0 = gtImgMeanValue(im);
end

% no. of images in dataset
if strcmpi(acq.type, '360degree')
    totproj = 2 * acq.nproj;
elseif strcmpi(acq.type, '180degree')
    totproj = acq.nproj;
else
    gtError('ACQ:invalid_parameter', ...
        'Unknown type of scan. Check parameters.acq.type!');
end

% now loop through all the images:  we do the following processing steps:
% - flatfield correction
% - normalization of the beam intensity outside the sample to be equal to
%   one:  allows to remove horizontal intensity variations in the images
% - we keep a record of the mean intensity in the image in the vector mean_vals(ii+1)

gtDBConnect();
for ii = first_img:last_img

    if (do_flatfield) % if doing the flatfield in this step
        % read image
        % !!! is this not a problem with interlaced scans??
        name = fullfile(datadir, sprintf('%s%04d.edf', acq.name, ii));

        [im, info] = edf_wait_read(name, prep.bbox, waitfortranslated);
        im = im - dark;

        % check if we need to update the reference images
        index1 = floor(ii / acq.refon) * acq.refon;
        refname1 = fullfile(datadir, sprintf('refHST%04d.edf', index1) );

        if (ii > (totproj-1))
            if ~strcmp(refname1, refname1old)
                ref = edf_wait_read(refname1, prep.bbox, waitfortranslated) - dark;
                refname1old = refname1;
            end
        else
            % if mono_tune = 3 and refon = 300, we have
            % 0000, 0300, 0600, 0899, 0900, 1200, 1500, 1799, 1800, .......
            if acq.mono_tune ~= 0
                check = mod(ceil(ii / acq.refon), acq.mono_tune) == 0;
                if check
                    index2 = ceil(ii / acq.refon) * acq.refon - 1;
                    index2 = max(0, index2);
                    refname2 = fullfile(datadir, sprintf('refHST%04d.edf', index2));
                elseif mod(ceil(ii / acq.refon) * acq.refon, acq.mono_tune) == 0
                    index2 = ceil(ii / acq.refon) * acq.refon;
                    refname2 = fullfile(datadir, sprintf('refHST%04d.edf', index2));
                end
            else
                index2 = ceil(ii / acq.refon) * acq.refon;
                refname2 = fullfile(datadir, sprintf('refHST%04d.edf', index2));
            end

            fprintf('%d %d %d\n',index1, index2, ii);

            if (~strcmp(refname1, refname1old) || ~strcmp(refname2, refname2old))
                ref1 = edf_wait_read(refname1, prep.bbox, waitfortranslated) - dark;
                ref2 = edf_wait_read(refname2, prep.bbox, waitfortranslated) - dark;
                refname1old = refname1;
                refname2old = refname2;
            end
            w   = mod(ii, acq.refon) / acq.refon;
            ref = (1 - w) .* ref1 + (w .* ref2);
        end

        % flatfield correction
        im  = im ./ ref;
    else
        %read flat fielded image
        name = fullfile(datadir, sprintf('%sflat_%04d.edf', acq.name, ii));
        [im, info] = edf_wait_read(name, prep.bbox, waitfortranslated);
    end %end of if do flat field

    %Now do further, special normalisation
    % keep a record of the mean intensity, nomralise image intensity
    switch (prep.normalisation)
        case 'margin'
            % standard way to do the normalisation
            % calculate the vertical mean intensity profile outside the sample
            % and renormalize this area to one
            margins = [1:prep.margin, (size(im, 2) - prep.margin + 1):size(im, 2)];
            mean_vals(ii + 1) = gtImgMeanValue( im(:, margins) );
            mim = mean(im(:, margins), 2);
            mim = repmat(mim, 1, size(im, 2));
            im  = im ./ mim;
        case 'fullbeam'
            % ak - mod to use central part of the image (within the sample) to normalise
            if ii == 0
                % Take the first image as the reference
                int0 = gtImgMeanValue(im);
            else
                inti = gtImgMeanValue(im);
                im   = (int0/inti)*im;
            end
            mean_vals(ii + 1) = gtImgMeanValue(im);
        case 'none'
            % do nothing - mean_vals(ii) is obsolete and will not be used any more
            mean_vals(ii + 1) = 1;
    end

    % apply a 2D median filter to reduce noise
    im = gtImgMedianFilter2(im, prep.filtsize);

    % we will adjust to the final size (acq.bb) after having shifted the images...
    dummy = zeros(acq.ydet, acq.xdet);
    im    = sfPutbb(dummy, prep.bbox, im);
    im    = sfGetbb(im, acq.bb);

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % write out the abs images
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    absname = fullfile(acq.dir, '1_preprocessing', 'abs', sprintf('abs%04d.edf', ii) );
    info.datatype = 'float32';
    edf_write(im, absname, info);
end

fname = fullfile(acq.dir, '1_preprocessing', 'mean.mat');
save(fname,'mean_vals');

end

%%%%%%%%%%%%%%%%%%%%%%%
% SUB-FUNCTIONS
%%%%%%%%%%%%%%%%%%%%%%%
% two little helper functions to put and get subimages defined by a
% gt_boundingbox from a bigger image

function a = sfGetbb(img, gtbb)
    a = img(gtbb(2):(gtbb(2) + gtbb(4) - 1), gtbb(1):(gtbb(1) + gtbb(3) - 1));
end

function b = sfPutbb(img, gtbb, roi)
    b = img;
    b(gtbb(2):(gtbb(2) + gtbb(4) - 1), gtbb(1):(gtbb(1) + gtbb(3) - 1)) = roi;
end