function S = calibrate(Sin, kcal, pixelcal, koffset, wavelength, pixelsize, detector_dist, calib_type)
%SAXS/CALIBRATE Calculate calibration data and insert calibration into SAXS object
%   SCAL = CALIBRATE(S, KCAL, PIXELCAL, KOFFSET, WAVELENGTH, PIXELSIZE, DETECTOR_DIST) returns SAXS object S
%   calibrated to display K values rather than pixel offsets.  
%   KCAL is the K value of the calibration line in reciprocal angstroms.  
%   PIXELCAL is the pixel radius corresponding to the calibration line.  
%   KOFFSET is an %   offset in reciprocal angstroms to apply to K values, usually 0.
%   KOFFSET may be omitted from the argument list when its value is 0.
%   WAVELENGTH is the wavelength (in Angstroms) of the incoming x-ray
%   radiation
%   PIXELSIZE is the pixelsize in mm of the pixel in the image
%   DETECTOR_DIST is the distance between the sample and detector
%   CALIB_TYPE is the type of calibration either 'std' which is fitting a
%   line value or 'geom' which requires pixelsize, wavelenght and
%   detector_dist
%
%   See also:  SAXS; SAXS/UNCALIBRATE; SAXS/IMAGE.
%   

%   If caller sends us empty calibration data, don't do anything.

global wavelength_default

if isempty(wavelength), wavelength=wavelength_default;end
    
if isempty(kcal) && isempty(detector_dist)
    S = Sin;
    return;
end



% Remove any current calibration.
S = uncalibrate(Sin);

% if the caller sends us calibration with calib_type "geom" we use
% geometrical values...otherwise it will be calibration by standard.
if strcmp(calib_type,'geom')
   S.calibrationtype='geom';
   S.wavelength=wavelength;
   S.pixelsize=pixelsize;
   S.detector_dist=detector_dist;
   % the whole saxsgui project was built up around calibration with a standard
   % so in order to do calibration by geometry, we incorporate
   % a pseudo-line calibration which corresponds to the geometrical data.
   % so here goes:
   % we might as well let this pseudo calibration line be the AgBeh line.
   % We should also remember in the calibration we assume that we are in
   % the SAXS limit and make the appropriate corrections later on.
%    kcal=0.1076;
%    twothetaperpixel=asin(pixelsize/detector_dist); %angle represented by 1 pixel at the distance
%    thetaperpixel=twothetaperpixel/2;
%    qperpixel=4*pi*sin(thetaperpixel)/wavelength;
%    pixelcal=kcal./qperpixel; %the value kcal/pixelcal now yield the q-calibration at 0 angle
%    koffset=0;
   kcal=0.1076;
   twothetaperpixel=pixelsize/detector_dist; %angle represented by 1 pixel at the distance
   thetaperpixel=twothetaperpixel/2;
   qperpixel=4*pi*thetaperpixel/wavelength;
   pixelcal=kcal./qperpixel;
   koffset=0;
   %this has now established the pseudo standard parameters and we can
   %proceed as if it was a standards calibration
end

   
% Record calibration data.

S.kcal = kcal;
S.pixelcal = pixelcal;
if isempty(koffset)
    koffset = 0;
end
S.koffset = koffset;
S.wavelength = wavelength;


% Apply calibration data to axis ranges. This is only absolutely correct
% for SAXS data
p2k = (S.kcal - S.koffset) ./ S.pixelcal;
S.xaxis = S.xaxis .* p2k(1) + S.koffset;
if isequal(S.type, 'xy')
    S.yaxis = S.yaxis .* p2k(2) + S.koffset;
end

% Record history.

if strcmp(calib_type,'geom')
  S.calibrationtype='geom';
  entry = ['set q calibration: by geometry: wavelength', num2str(S.wavelength), '; pixel size', num2str(S.pixelsize), ...
        '; Detector Dist', num2str(S.detector_dist)];
else
    S.calibrationtype='std';
    entry = ['set q calibration:', num2str(S.kcal), '; ', num2str(S.pixelcal), ...
        '; ', num2str(S.koffset),'; ', num2str(S.wavelength)];
end

    S = history(S, entry);
