function value = ffvalue(s,meantype)
% FFVALUE takes a SAXS object and a "averaging type" and returns a value
% In it's present form the ffvalue program is used to evaluat a 2D
% floodfield image and come up with a decent number for what should be the
% normalisation number..in other words which pixel-value should be equal to 1.
% FFvalue is then a central routine in determining how to "normalize"
% floodfield images.
%
% In the present approach, the value is taken as the mean value of all the
% pixels whose pixel values are greater than 0.5xA and less than 3.0xA.
% A is calculated as the median value of the points in the one line in the
% center. 
% In this way A serves as a first guess for a good normalization value and
% mean then includes all "reasonable" pixel values.
persistent sold
%be sure that it is the saxsobj of a flatfield image.
global oldfffile oldffvalue oldmeantype
if ~isempty(s.flatfield_pixels)
    s.pixels=s.flatfield_pixels;
end
% Since the best meantype is 3 which is log (that takes a relatively long
% time. We save information on old calculated values and retrieve them if
% the file names are the same.
if strcmp(oldfffile,s.flatfield_filename) &&  ~isempty(oldffvalue) && oldmeantype==meantype
    value=oldffvalue;
    return
end

if nargin==1
    meantype=1;
end
projpix=sum(s.pixels);
imagecen=floor(sum(projpix.*(1:length(projpix)))/(sum(projpix)));
A=median(s.pixels(:,imagecen));
if A==0
     errordlg('There are too many 0-values in the flatfield','Error in flatfield data');
end
pixels=prepare_pixels(s.pixels,s); %remember to remove readout noise and zinger if asked to so
if meantype==1 % this indicates that value is to be calculated as mean of value
    value=mean(pixels(pixels>0.333*A & pixels<3*A));
elseif meantype==2 %else value is to be calculated as mean of 1/value (useful for flatfields with high level of noise
    value=1/mean(1./pixels(pixels>1/3*A & pixels<3*A));
else %finally value can be calculated as the average of the log values
    value=exp(mean(log(pixels((log(pixels)>log(1/3*A)) & (log(pixels)<log(3*A))))));
end
%saving the values for later application
oldffvalue=value;
oldfffile=s.flatfield_filename;
oldmeantype=meantype;

function pixelsout=prepare_pixels(pixelsin,si)
% this routine makes sure that the data to be operated on is corrected
% prior to later binning
if ~isempty(si.readoutnoise)   %this means that readoutnoise should be subtracted
    pixelsin=pixelsin-si.readoutnoise;
end
if ~isempty(si.zinger_removal)    %this means that data should be "zinger removed"
    pixelsin=zinger_removal(pixelsin,si.error_norm_fact);
end
pixelsout=pixelsin;