function hfig_out = plotx(S, varargin)
%SAXS/PLOTX Explore a plot of an averaged SAXS image.
%   PLOTX(S)
%   H = PLOTX(S)
%
%   
%   See also SAXS/PLOT.

% this version allows the possibility of saving all the plots,
% and of using the graph to start a batch session.

% If it's the wrong kind of SAXS image, SAXS/PLOT will notice.

hfig = figure;  % always in a new window
set(hfig,'MenuBar','none'); %no inherent need for a matlab menu
hplot = plot(S, varargin{:});  % using SAXS/PLOT
haxes = get(hplot, 'Parent');  % remember the axes object

displaymenu = uimenu('Label', 'Display');
linlinmenu=uimenu(displaymenu, 'Label', 'Lin-Lin Plot', 'Callback', ...
    {@linlinplot, haxes});
loglinmenu=uimenu(displaymenu, 'Label', 'Log-Lin Plot', 'Callback', ...
    {@loglinplot, haxes});
linlogmenu=uimenu(displaymenu, 'Label', 'Lin-Log Plot', 'Callback', ...
    {@linlogplot, haxes});
loglogmenu=uimenu(displaymenu, 'Label', 'Log-Log Plot', 'Callback', ...
    {@loglogplot, haxes});
switcherrorbarmenu=uimenu(displaymenu, 'Label', 'Toggle Errorbars', 'Separator','on','Callback', ...
    {@switcherrorbar, haxes});
zoommenu = uimenu(displaymenu,'Label', 'Zoom','separator','on');
uimenu(zoommenu, 'Label', 'Zoom x and y', 'Callback', 'zoom on')
uimenu(zoommenu, 'Label', 'Zoom x alone', 'Callback', 'zoom xon')
uimenu(zoommenu, 'Label', 'Zoom y alone', 'Callback', 'zoom yon')
uimenu(zoommenu, 'Label', 'Zoom off', 'Callback', 'zoom off')
uimenu(zoommenu, 'Label', 'How to zoom...', 'Callback', @howtozoom)
matlabmenuviewmenu=uimenu(displaymenu, 'Label', 'Matlab Menus', 'Separator','on','Callback', ...
    {@MenuViewMATLAB, haxes});
% the following lists of plots can be extended but each one needs a special
% plot function built on the frame of plot for SAXS objects.
plottypemenu = uimenu('Label', 'PlotType');
iqmenu=uimenu(plottypemenu, 'Label', 'I vs. q', 'Callback', ...
    {@iq, haxes});
lniq2menu=uimenu(plottypemenu, 'Label', 'Ln(I) vs. q^2','Separator','on','Callback', ...
    {@lniq2, haxes});
iq2menu=uimenu(plottypemenu, 'Label', 'I^-1 vs. q^2', 'Callback', ...
    {@im1q2, haxes});
iq4qmenu=uimenu(plottypemenu, 'Label', 'I*q^4 vs. q', 'Callback', ...
    {@iq4q, haxes});
iq2qmenu=uimenu(plottypemenu, 'Label', 'I*q^2 vs. q', 'Callback', ...
    {@iq2q, haxes});
guinierplotmenu=uimenu(plottypemenu, 'Label', 'Guinier Plot','Separator','on','Callback', ...
    {@guinier, haxes});
checktwothetamenu=uimenu(plottypemenu, 'Label', 'I vs. 2-theta', 'Separator','on','Callback', ...
    {@twotheta, haxes});

analysismenu = uimenu('Label', 'Analysis');
quikstatmenu=uimenu(analysismenu, 'Label', 'QuikStat', 'Callback', ...
    {@CalcQuikStat, haxes,0});
quikfitmenu=uimenu(analysismenu, 'Label', 'QuikFit');
quikfitpeakmenu=uimenu(quikfitmenu, 'Label', 'PeakFit');
quikfitporodmenu=uimenu(quikfitmenu, 'Label', 'PorodFit');
quikfitguiniermenu=uimenu(quikfitmenu, 'Label', 'GuinierFit');
quikfitfractalmenu=uimenu(quikfitmenu, 'Label', 'FractalFit');
quikfitothermenu=uimenu(quikfitmenu, 'Label', 'OtherFit');

quikpeakslopemenu=uimenu(quikfitpeakmenu, 'Label', 'Gauss-Peak + Slope Bckg', 'Callback', ...
    {@FitGaussPeakSlope, haxes,0});
quikpeaksplinemenu=uimenu(quikfitpeakmenu, 'Label', 'Gauss-Peak + Spline Bckg', 'Callback', ...
    {@FitGaussPeakSpline, haxes,0});
quiklpeakslopemenu=uimenu(quikfitpeakmenu, 'Label', 'Lorentz-Peak + Slope Bckg', 'Separator','on', 'Callback', ...
    {@FitLorentzPeakSlope, haxes,0});
quiklpeaksplinemenu=uimenu(quikfitpeakmenu, 'Label', 'Lorentz-Peak + Spline Bckg', 'Callback', ...
    {@FitLorentzPeakSpline, haxes,0});
quikpeakslopemenu=uimenu(quikfitpeakmenu, 'Label', 'PearsonVII-Peak + Slope Bckg',  'Separator','on','Callback', ...
    {@FitPearsonPeakSlope, haxes,0});
quikpeaksplinemenu=uimenu(quikfitpeakmenu, 'Label', 'PearsonVII-Peak + Spline Bckg', 'Callback', ...
    {@FitPearsonPeakSpline, haxes,0});
quikdoublepeakslopemenu=uimenu(quikfitpeakmenu, 'Label', 'Double PearsonVII-Peak + Slope Bckg', 'Callback', ...
    {@FitDoublePearsonPeakSlope, haxes,0});
quikdoublepeaksplinemenu=uimenu(quikfitpeakmenu, 'Label', 'Double PearsonVII-Peak + Spline Bckg', 'Callback', ...
    {@FitDoublePearsonPeakSpline, haxes,0});

quikporodmenu=uimenu(quikfitporodmenu, 'Label', 'Porod','Callback', ...
    {@FitPorod, haxes,0});
quikporodfluctmenu=uimenu(quikfitporodmenu, 'Label', 'Porod + Bckg-term', 'Callback', ...
    {@FitPorodFluct, haxes,0});
quikfractmenu=uimenu(quikfitfractalmenu, 'Label', 'Fractal Dimension ', 'Callback', ...
    {@FitFract, haxes,0});
quikfractbackgmenu=uimenu(quikfitfractalmenu, 'Label', 'Fractal Dimension + const. Bckg', 'Callback', ...
    {@FitFractBackg, haxes,0});
quikguiniermenu=uimenu(quikfitguiniermenu, 'Label', 'Guinier','Callback', ...
    {@FitGuinier, haxes,0});
%quikdebyemenu=uimenu(quikfitothermenu, 'Label', 'Debye','Callback', ...
%    {@FitDebye, haxes,0});
quikguinierporodmenu=uimenu(quikfitothermenu, 'Label', 'Guinier-Porod', 'Separator','on','Callback', ...
    {@FitGuinierPorod, haxes,0});
quikguinierporodconstmenu=uimenu(quikfitothermenu, 'Label','Guinier-Porod-Const', 'Callback', ...
    {@FitGuinierPorodConst, haxes,0});


startfitmenu=uimenu(analysismenu, 'Label', 'FullFit', 'Callback', ...
    {@FullFit, haxes,0});
startiftmenu=uimenu(analysismenu, 'Label', 'Bayesian IFT', 'Callback', ...
    {@BayesianIFT, haxes,0});


exportmenu = uimenu('Label', 'Export');
exportdatamenu=uimenu(exportmenu, 'Label', 'As comma-separated text');
exportonedatamenu=uimenu(exportdatamenu, 'Label', 'One curve', 'Callback', ...
    {@exportone, haxes});
%exportalldatamenu=uimenu(exportdatamenu, 'Label', 'All curves in separate files', 'Callback', ...
%    {@exportall, haxes});
exportphdmenu=uimenu(exportmenu, 'Label', 'As PDH file (Glatter format)');
exportonephdmenu=uimenu(exportphdmenu, 'Label', 'One curve', 'Callback', ...
    {@exportonephd, haxes});
exportradmenu=uimenu(exportmenu, 'Label', 'As RAD file (Risoe format)');
exportoneradmenu=uimenu(exportradmenu, 'Label', 'One curve', 'Callback', ...
    {@exportonerad, haxes});
exportslmenu=uimenu(exportmenu, 'Label', 'As GRAD file (Saxslab format)', 'Callback', ...
    {@exportgrad, haxes});

batchprocessmenu = uimenu('Label', 'Batch Processing');
%APbatchmenu=uimenu(batchmenu, 'Label', 'Batch by AP-file');
APfilewritemenu=uimenu(batchprocessmenu, 'Label', 'Save template AP-file', 'Callback', ...
    {@WriteAPFile, haxes});
guibatchmenu=uimenu(batchprocessmenu, 'Label', 'Batch by GUI');
timeseriesguimenu=uimenu(guibatchmenu, 'Label', 'Time Series', 'Callback', ...
    {@TimeSeries, haxes});
timeseriesguimenu=uimenu(guibatchmenu, 'Label', 'XY Grid', 'Callback', ...
    {@XYGrid, haxes});

% dirbatchrunmenu=uimenu(batchmenu, 'Label', 'Do same reduction to all files in one directory...', 'Callback', ...
%     {@dirbatchrun, haxes});

%Not quite ready for Batch fitting yet.
% batchanalysismenu = uimenu('Label', 'Batch Fitting','Separator','on');
% 
% batchquikstatmenu=uimenu(batchanalysismenu, 'Label', 'Batch QuikStat', 'Callback', ...
%     {@CalcQuikStat, haxes});
% batchquikfitmenu=uimenu(batchanalysismenu, 'Label', 'Batch QuikFit');
% batchquikfitpeakmenu=uimenu(batchquikfitmenu, 'Label', 'Batch PeakFit');
% batchquikfitporodmenu=uimenu(batchquikfitmenu, 'Label', 'Batch PorodFit');
% batchquikfitguiniermenu=uimenu(batchquikfitmenu, 'Label', 'Batch GuinierFit');
% batchquikfitfractalmenu=uimenu(batchquikfitmenu, 'Label', 'Batch FractalFit');
% batchquikfitothermenu=uimenu(batchquikfitmenu, 'Label', 'Batch OtherFit');
% 
% batchquikpeakslopemenu=uimenu(batchquikfitpeakmenu, 'Label', 'Gauss-Peak + Slope Bckg', 'Callback', ...
%     {@FitGaussPeakSlope, haxes,1});
% batchquikpeaksplinemenu=uimenu(batchquikfitpeakmenu, 'Label', 'Gauss-Peak + Spline Bckg', 'Callback', ...
%     {@FitGaussPeakSpline, haxes,1});
% batchquiklpeakslopemenu=uimenu(batchquikfitpeakmenu, 'Label', 'Lorentz-Peak + Slope Bckg', 'Separator','on', 'Callback', ...
%     {@FitLorentzPeakSlope, haxes,1});
% batchquiklpeaksplinemenu=uimenu(batchquikfitpeakmenu, 'Label', 'Lorentz-Peak + Spline Bckg', 'Callback', ...
%     {@FitLorentzPeakSpline, haxes,1});
% batchquikpeakslopemenu=uimenu(batchquikfitpeakmenu, 'Label', 'PearsonVII-Peak + Slope Bckg',  'Separator','on','Callback', ...
%     {@FitPearsonPeakSlope, haxes,1});
% batchquikpeaksplinemenu=uimenu(batchquikfitpeakmenu, 'Label', 'PearsonVII-Peak + Spline Bckg', 'Callback', ...
%     {@FitPearsonPeakSpline, haxes,1});
% batchquikdoublepeakslopemenu=uimenu(batchquikfitpeakmenu, 'Label', 'Double PearsonVII-Peak + Slope Bckg', 'Callback', ...
%     {@FitDoublePearsonPeakSlope, haxes,1});
% batchquikdoublepeaksplinemenu=uimenu(batchquikfitpeakmenu, 'Label', 'Double PearsonVII-Peak + Spline Bckg', 'Callback', ...
%     {@FitDoublePearsonPeakSpline, haxes,1});
% 
% batchquikporodmenu=uimenu(batchquikfitporodmenu, 'Label', 'Porod','Callback', ...
%     {@FitPorod, haxes,1});
% batchquikporodfluctmenu=uimenu(batchquikfitporodmenu, 'Label', 'Porod + Bckg-term', 'Callback', ...
%     {@FitPorodFluct, haxes,1});
% batchquikfractmenu=uimenu(batchquikfitfractalmenu, 'Label', 'Fractal Dimension ', 'Callback', ...
%     {@FitFract, haxes,1});
% batchquikfractbackgmenu=uimenu(batchquikfitfractalmenu, 'Label', 'Fractal Dimension + const. Bckg', 'Callback', ...
%     {@FitFractBackg, haxes,1});
% batchquikguiniermenu=uimenu(batchquikfitguiniermenu, 'Label', 'Guinier','Callback', ...
%     {@FitGuinier, haxes,1});
% 
% batchquikguinierporodmenu=uimenu(batchquikfitothermenu, 'Label', 'Guinier-Porod', 'Separator','on','Callback', ...
%     {@FitGuinierPorod, haxes,1});
% batchquikguinierporodconstmenu=uimenu(batchquikfitothermenu, 'Label','Guinier-Porod-Const', 'Callback', ...
%     {@FitGuinierPorodConst, haxes,1});

if (strcmp(S.type,'r-ave'))
    set(get(displaymenu,'Children'),'Checked','off');
    set(get(plottypemenu,'Children'),'Checked','off');
    %if sum(S.pixels<=0)>0
    %  set(linlinmenu,'Checked','on');
    %else
    %  set(linlogmenu,'Checked','on');
    %end
    change_axes_checking(loglogmenu)
    set_checked_axis(loglogmenu,haxes)
    set(haxes,'Tag','1Dplot');
    %set(loglogmenu,'Checked','on');
    %set(iqmenu,'Checked','on');
else
    set(startiftmenu,'Visible','off');
    set(get(displaymenu,'Children'),'Visible','off');
    set(get(plottypemenu,'Children'),'Visible','off');
    set(iqmenu,'Visible','on');
    set(iqmenu,'Checked','on');
    set(switcherrorbarmenu,'Visible','on')
    %quikfits turned off if azimuthal plot
    set(quikfitguiniermenu,'Visible','off');
    set(quikfitfractalmenu,'Visible','off');
    set(quikfitporodmenu,'Visible','off');
    set(quikfitothermenu,'Visible','off');
    set(linlinmenu,'Visible','on');
    set(linlogmenu,'Visible','on');
    set(haxes,'Tag','1Dplot');
end

set(hfig, 'WindowButtonMotionFcn', {@mousemove, haxes})  
% install pointer tracking


if nargout
    hfig_out = hfig;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function change_axes_checking(hmenu)
displaymenu=get(hmenu,'Parent');
displaymenuchildren=get(displaymenu,'Children');
set(displaymenuchildren(end-3:end),'Checked','off');
set(hmenu,'Checked','on');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function change_plottype_checking(hmenu)
plottypemenu=get(hmenu,'Parent');
set(get(plottypemenu,'Children'),'Checked','off');
set(hmenu,'Checked','on');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function errorbarstatus=set_errorbar_visibility(hmenu)
%errorbar should only be visible in the I vs. q mode. This may change
%later. But for now we locate the errorbarmenu and then make it visible or
%not visible depending on plot type.
plottypemenu=get(hmenu,'Parent');
topmenu=get(plottypemenu,'Parent');
displaymenu=findobj(topmenu,'Label','Display');
errorbarmenu=findobj(topmenu,'Label','Toggle Errorbars');

isIvsq=strcmp(get(hmenu,'Label'),'I vs. q');
if isIvsq
    set(errorbarmenu,'Visible','on')
else
    set(errorbarmenu,'Visible','off')
end
errorbarstatus=get(errorbarmenu,'Checked');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function set_checked_axis(hmenu,haxes)
plottypemenu=get(hmenu,'Parent');
topmenu=get(plottypemenu,'Parent');
displaymenu=findobj(topmenu,'Label','Display');
displaymenuchildren=get(displaymenu,'Children');
if strcmp(get(findobj(displaymenuchildren,'Label','Lin-Lin Plot'),'Checked'),'on');
    set(haxes,'Xscale','lin')
    set(haxes,'Yscale','lin')
else if strcmp(get(findobj(displaymenuchildren,'Label','Log-Lin Plot'),'Checked'),'on');
        set(haxes,'Xscale','log')
        set(haxes,'Yscale','lin')
    else if strcmp(get(findobj(displaymenuchildren,'Label','Lin-Log Plot'),'Checked'),'on');
            set(haxes,'Xscale','lin')
            set(haxes,'Yscale','log')
        else if strcmp(get(findobj(displaymenuchildren,'Label','Log-Log Plot'),'Checked'),'on');
                set(haxes,'Xscale','log')
                set(haxes,'Yscale','log')
            else
                set(haxes,'Xscale','lin')
                set(haxes,'Yscale','lin')
            end
        end
    end
end
h=reduction_text(haxes);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function iq(hmenu, eventdata, haxes)

change_plottype_checking(hmenu) ;
errorbarstatus=set_errorbar_visibility(hmenu);
hdatalines=findlines(haxes);
for ii=1:length(hdatalines)
    Sall{ii}=get(hdatalines(ii),'UserData');
end
set(haxes, 'NextPlot', 'replace')
colororder=get(haxes,'ColorOrder');

if (strcmp('on',errorbarstatus))
    hplot=errorplot(Sall{1},'Color',colororder(1,:));
    for ii=2:length(hdatalines)
        hold on
        color = colororder(mod(ii-1,7)+1 , :);
        errorplot(Sall{ii},'Color',color)
    end
else
    hplot=plot(Sall{1},'Color',colororder(1,:));
    for ii=2:length(hdatalines)
        hold on
        color = colororder(mod(ii-1,7)+1 , :);
        iqplot(Sall{ii},'Color',color)
    end
end

hold off
set_checked_axis(hmenu,haxes)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function lniq2(hmenu, eventdata, haxes)

change_plottype_checking(hmenu) ;
set_errorbar_visibility(hmenu);
hdatalines=findlines(haxes);

for ii=1:length(hdatalines)
    Sall{ii}=get(hdatalines(ii),'UserData');
end
set(haxes, 'NextPlot', 'replace')
colororder=get(haxes,'ColorOrder');
hplot=lniq2plot(Sall{1},'Color',colororder(1,:));
for ii=2:length(hdatalines)
    hold on
    color = colororder(mod(ii-1,7)+1 , :);
    lniq2plot(Sall{ii},'Color',color)
end
hold off
set_checked_axis(hmenu,haxes)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function im1q2(hmenu, eventdata, haxes)

change_plottype_checking(hmenu) ;
set_errorbar_visibility(hmenu);
hdatalines=findlines(haxes);

for ii=1:length(hdatalines)
    Sall{ii}=get(hdatalines(ii),'UserData');
end
set(haxes, 'NextPlot', 'replace')
colororder=get(haxes,'ColorOrder');
hplot=im1q2plot(Sall{1},'Color',colororder(1,:));
for ii=2:length(hdatalines)
    hold on
    color = colororder(mod(ii-1,7)+1 , :);
    im1q2plot(Sall{ii},'Color',color)
end
hold off
set_checked_axis(hmenu,haxes)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function iq4q(hmenu, eventdata, haxes)

change_plottype_checking(hmenu);
set_errorbar_visibility(hmenu);
hdatalines=findlines(haxes);

for ii=1:length(hdatalines)
    Sall{ii}=get(hdatalines(ii),'UserData');
end
set(haxes, 'NextPlot', 'replace')
colororder=get(haxes,'ColorOrder');
hplot=iq4qplot(Sall{1},'Color',colororder(1,:));
for ii=2:length(hdatalines)
    hold on
    color = colororder(mod(ii-1,7)+1 , :);
    iq4qplot(Sall{ii},'Color',color)
end
hold off
set_checked_axis(hmenu,haxes)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function iq2q(hmenu, eventdata, haxes)

change_plottype_checking(hmenu);
set_errorbar_visibility(hmenu);
hdatalines=findlines(haxes);

for ii=1:length(hdatalines)
    Sall{ii}=get(hdatalines(ii),'UserData');
end
set(haxes, 'NextPlot', 'replace')
colororder=get(haxes,'ColorOrder');
hplot=iq2qplot(Sall{1},'Color',colororder(1,:));
for ii=2:length(hdatalines)
    hold on
    color = colororder(mod(ii-1,7)+1 , :);
    iq2qplot(Sall{ii},'Color',color)
end
hold off
set_checked_axis(hmenu,haxes)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function guinier(hmenu, eventdata, haxes)

lniq2menu=findobj(get(get(hmenu,'Parent'),'Children'),'Label','Ln(I) vs. q^2');
linlinmenu=findobj(get(get(get(hmenu,'Parent'),'Parent'),'Children'),'Label','Lin-Lin Plot');
%change to Gunier Plot :ln(I) vs. q^2 and to log-log
change_plottype_checking(lniq2menu);
set_errorbar_visibility(lniq2menu);
change_axes_checking(linlinmenu)
hdatalines=findlines(haxes);

for ii=1:length(hdatalines)
    Sall{ii}=get(hdatalines(ii),'UserData');
end
set(haxes, 'NextPlot', 'replace')
colororder=get(haxes,'ColorOrder');
hplot=lniq2plot(Sall{1},'Color',colororder(1,:));
for ii=2:length(hdatalines)
    hold on
    color = colororder(mod(ii-1,7)+1 , :);
    lniq2plot(Sall{ii},'Color',color)
end
hold off
set_checked_axis(linlinmenu,haxes)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function twotheta(hmenu, eventdata, haxes)

change_plottype_checking(hmenu);
set_errorbar_visibility(hmenu);
hdatalines=findlines(haxes);

for ii=1:length(hdatalines)
    Sall{ii}=get(hdatalines(ii),'UserData');
end
set(haxes, 'NextPlot', 'replace')
colororder=get(haxes,'ColorOrder');
hplot=i2thetaplot(Sall{1},'Color',colororder(1,:));
for ii=2:length(hdatalines)
    hold on
    color = colororder(mod(ii-1,7)+1 , :);
    twothetaplot(Sall{ii},'Color',color)
end
hold off
set_checked_axis(hmenu,haxes)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function linlinplot(hmenu, eventdata, haxes)
change_axes_checking(hmenu)
set_checked_axis(hmenu,haxes)


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function linlogplot(hmenu, eventdata, haxes)
change_axes_checking(hmenu)
set_checked_axis(hmenu,haxes)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function loglinplot(hmenu, eventdata, haxes)
change_axes_checking(hmenu)
set_checked_axis(hmenu,haxes)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function loglogplot(hmenu, eventdata, haxes)
change_axes_checking(hmenu)
set_checked_axis(hmenu,haxes)



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function switcherrorbar(hmenu, eventdata, haxes)
Xscalesetting=get(haxes,'Xscale');
Yscalesetting=get(haxes,'Yscale');
Xlim=get(haxes,'XLim');
Ylim=get(haxes,'YLim');
if (strcmp('off',get(hmenu,'Checked')))
    set(hmenu,'Checked','on')
    hdatalines=findlines(haxes);
    
    for ii=1:length(hdatalines)
        Sall{ii}=get(hdatalines(ii),'UserData');
    end
    set(haxes, 'NextPlot', 'replace')
    colororder=get(haxes,'ColorOrder');
    hplot=errorplot(Sall{1},'Color',colororder(1,:));
    for ii=2:length(hdatalines)
        hold on
        color = colororder(mod(ii-1,7)+1 , :);
        errorplot(Sall{ii},'Color',color)
    end
    hold off
else
    set(hmenu,'Checked','off')
    hdatalines=findlines(haxes);
    
    for ii=1:length(hdatalines)
        Sall{ii}=get(hdatalines(ii),'UserData');
    end
    set(haxes, 'NextPlot', 'replace')
    colororder=get(haxes,'ColorOrder');
    hplot=plot(Sall{1},'Color',colororder(1,:));
    for ii=2:length(hdatalines)
        hold on
        color = colororder(mod(ii-1,7)+1 , :);
        plot(Sall{ii},'Color',color)
    end
    hold off
end

set(haxes,'Xscale',Xscalesetting)
set(haxes,'Yscale',Yscalesetting)
set_checked_axis(hmenu,haxes)
set(haxes,'XLim',Xlim);
set(haxes,'YLim',Ylim);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function hdatalines=findlines(haxes)

lines = findobj(haxes, 'Type', 'line'); % find all lines
hdatalines=(findobj(lines,'Tag','Data')); % find all lines with Data tag
hdatalines=fliplr(flipud(hdatalines));


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function mousemove(hfig, eventdata, haxes)
% If pointer is over axes, label data points at the pointer's x position.
% I think when the pointer is not over the axes, the labels should
% disappear.
coords = get(haxes, 'CurrentPoint');  % pointer position in axes coords
x = coords(1, 1);
y = coords(1, 2);
xlim = get(haxes, 'XLim');  % x axis limits
ylim = get(haxes, 'YLim');  % y axis limits
outside = x < xlim(1) || x > xlim(2) || y < ylim(1) || y > ylim(2);
% is pointer outside axes?

% Show x coordinate as labelled vertical line.
cursor = findobj(haxes, 'Tag', 'cursor');

if isempty(cursor)
    cursor = line([x x], ylim, 'Tag', 'cursor', 'LineStyle', ':', ...
        'Color', 'black', 'EraseMode', 'xor');
    cursorlabel = text(x, ylim(2), '', 'EraseMode', 'xor', ...
        'VerticalAlignment', 'bottom', 'Tag', 'cursor-label');
    setappdata(cursor, 'label', cursorlabel)
else
    cursorlabel = getappdata(cursor, 'label');
end
if outside
    set([cursor, cursorlabel], 'Visible', 'off')
else
    try
        dataline=findobj(haxes,'Tag','Data');
        S=get(dataline(1),'UserData');
        if strcmp(S.type,'r-ave') && ~isempty(S.kcal) ...
                && strcmp(get(get(haxes,'Xlabel'),'String'),'momentum transfer, q (A^-^1)')
            txtstring=['q = ',num2str(x,4),' : d = ',num2str(2*pi/x,4),' : 2theta = ', num2str(180/pi*2*asin(x*S.wavelength/4/pi),4),'deg'];
        else
            txtstring=num2str(x,4);
        end
    catch
        txtstring=num2str(x,4);
    end
    set(cursor, 'Visible', 'on', 'XData', [x x], 'YData', ylim,'Color',[0 0 0])
    set(cursorlabel, 'Visible', 'on', 'Position', [x ylim(2)], ...
        'String',txtstring,'Color',[0 0 0])
end

% Label each plot line.
lines = findobj(haxes, 'Type', 'line');  % find all lines
% in row vector?  'for' treats a column at a time
ii=0;
for li = lines'  % treat each line
    if li == cursor  % our cursor line
        continue  % skip to next line
    end
    ii=ii+1;
    if isappdata(li, 'ptrlabel')  % label already on this line
        label = getappdata(li, 'ptrlabel');
    else  % make a new label
        label = text(x, y, '', 'EraseMode', 'xor', ...
            'Tag', 'cursor-label');  % new label
        setappdata(li, 'ptrlabel', label)  % attach handle to line object
    end
    if ishandle(label)
        if outside  % pointer outside axes, make label invisible
            try
                set(label, 'Visible', 'off')
            catch
                li=li;
            end
        else
            set(label, 'Visible', 'on')
            % Look up y value.
            % Even though the pointer is within the axes, it may not be
            % within the range of a particular plotted line.
            xvals = get(li, 'XData');
            yvals = get(li, 'YData');
            if x < xvals(1) || x > xvals(end)  % outside this line's range
                set(label, 'Visible', 'off')
            else  % update the label
                try % something was not working properly when close to the x-axis so here the "hack"
                    ix = find(xvals >= x); ix = ix(1);  % index of nearest point
                    yli = yvals(ix);  % y value at this point
                    if strcmp(get(get(label,'Parent'),'YScale'),'log')
                        range=ylim(2)/ylim(1);
                        ylipos=y*exp(log(range)*((length(lines)-ii)*0.05));
                    else
                        range=ylim(2)-ylim(1);
                        ylipos=y+range*((length(lines)-ii)*0.05);
                        
                    end
                    set(label, 'Position', [x, ylipos, 0], 'String', ...
                        [num2str(yli)],'Color',get(li,'Color'))
                catch
                    set(label, 'Visible', 'off')
                end
            end
        end
    end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function howtozoom(hmenu, eventdata)
% Menu callback. Tell user how to zoom.
msgbox(['Using the Zoom menu, you can turn zoom on for the x axis, y axis, ', ...
        'or both.  ', ...
        'With zoom turned on, point in the graph and click the left mouse ', ...
        'button to zoom in, the right mouse button to zoom out.  ', ...
        'Double-click to zoom all the way out.  Turn zoom off to display ', ...
        'the coordinate cursor again.' ...
    ], 'How to zoom', 'help')

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function exportone(hmenu, eventdata, haxes)
% Menu callback.  Guide user through exporting data as text.

% Select line.
hline = whichline(haxes);
if isempty(hline)
    return
end
% Name file.
[file dir] = uiputfile('*.csv', 'Export to text file');
if ~isempty(file) && ~strcmp('.csv',file(end-3:end)) %program did not put .csv at the end (this is a bug in matlab 6.5..we'll force it)
    file=[file,'.csv'];
end
% Write file.
if file
    csvwriteline(hline, [dir file])
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function exportonephd(hmenu, eventdata, haxes)
% Menu callback.  Guide user through exporting data as text.

% Select line.
hline = whichline(haxes);
if isempty(hline)
    return
end
% Name file.
[file dir] = uiputfile('*.phd', 'Export to text file');
if ~isempty(file) && ~strcmp('.phd',file(end-3:end)) %program did not put .phd at the end (this is a bug in matlab 6.5..we'll force it)
    file=[file,'.phd'];
end
% Write file.
if file
    phdwriteline(hline, [dir file])
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function exportonerad(hmenu, eventdata, haxes)
% Menu callback.  Guide user through exporting data as text.

% Select line.
hline = whichline(haxes);
if isempty(hline)
    return
end
% Name file.
[file dir] = uiputfile('*.rad', 'Export to text file');
if ~isempty(file) && ~strcmp('.rad',file(end-3:end)) %program did not put .rad at the end (this is a bug in matlab 6.5..we'll force it)
    file=[file,'.rad'];
end
% Write file.
if file
    radwriteline(hline, [dir file])
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function exportgrad(hmenu, eventdata, haxes)
% Menu callback.  Guide user through exporting data as text.

% find all lines 
hlines = findobj(haxes, 'Tag', 'Data');  % all lines in the axes
if isempty(hlines)
    return
end
% Name file.
[file dir] = uiputfile('*.grad', 'Provide name of desired export file');
if ~isempty(file) && ~strcmp('.grad',file(end-4:end)) %program did not put .rad at the end (this is a bug in matlab 6.5..we'll force it)
    file=[file,'.rrad'];
end
% Write file.
if file
    lines2grad(hlines, [dir file])
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function exportall(hmenu, eventdata, haxes)
% Menu callback.  Guide user through exporting data in all curves as text.

hfig = get(haxes, 'Parent');  % parent figure window
hlines = findobj(haxes, 'Tag', 'Data');  % all lines in the axes
if isempty(hlines)  % no lines?
    h_out = [];  % return empty
    return
end

% files will be saved in the q,I,delta(I) format using comma-separated-values format
% all 1D files will be given their original (2D) data file name with a tag
% added at the end ...the extension will be csv
% So first get a tag to append to the file names
str2(1) = {'The data (X,I,delta(I)) will be saved using '};
str2(2) = {'comma-separated-values format.   '};
str2(3) = {'The name of the new file will be, '};
str2(4) = {'ORIGINAL-NAME_tag.CSV'};
str2(5) = {'                     '};
helpdlg(str2,'Instruction for saving multiple files')
uiwait
prompt={'Plese enter the "tag" you want'};
def={'1D'};
dlgTitle='Input "tag" to append to saved file names';
lineNo=1;
answer=inputdlg(prompt,dlgTitle,lineNo,def);
tag=answer{1};

% now we need to allow the user to put them in an appropriate directory
path=uigetdir(pwd,'Pick a directory for the saved files');
if path==0, path=pwd; end
path=[path filesep];

%finally we create the appropriate filename for each and save them
num_hlines=length(hlines);
for ii=1:num_hlines
    s=get(hlines(ii),'UserData');
    [pathstr,name,ext] = fileparts(s.raw_filename);
    file=[name,'_',tag,'.csv'];
    csvwriteline(hlines(ii), [path file])
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function BayesianIFT(hmenu, eventdata, haxes,batch)
% Menu callback.  Guide user through exporting data as text.

[S,X,Y,E,Xdisp,Ydisp]=getdatafromaxes(haxes);
% Select line.

%removing data where Y=NaN
X = X(~isnan(Y));
Y = Y(~isnan(Y));
E = E(~isnan(Y));
if length(Y)==length(E)         
    data = [X(:), Y(:), E(:)];  
    [results,biftfig]=biftfull(data,1,0);
    plotbiftresults(results,biftfig);
else                            
    errordlg('Error: The data does not have errorbars. This is needed for IFT calculation');
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function FullFit(hmenu, eventdata, haxes,batch)
% Menu callback.  Invokes the FullFit program interface
[S,X,Y,E,Xdisp,Ydisp]=getdatafromaxes(haxes);
% % Select line.
% hline = whichline(haxes);
% if isempty(hline)
%     return
% end
% 
% S = get(hline, 'UserData'); 
% S.pixels = get(hline, 'YData');              
if length(S.xaxisfull)==length(S.relerr)         
    results=Fitting1D(S);
else                            
    errordlg('Error: The data does not have errorbars. This is needed for FullFit');
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function TimeSeries(hmenu, eventdata, haxes)
% Menu callback.  Start doing equivalent reduction on other files..
% The results are saved.

% Select line.
hline = whichline(haxes);
if isempty(hline)
    return
end
drawnow
S_template = get(hline, 'UserData'); 
%since the pixel data has been stripped we need to put it back:
hstatus = figstatus('Preparing Data',get(haxes,'Parent'));  % tell user what to do in a status bar
if str2num(S_template.reduction_state(12))==1 % if the beamstop mask is to be used
    a=add_beamstopmask(S_template);
    warning off MATLAB:divideByZero
    S_template.bsmask_pixels=double(a.bsmask_pixels)./double(a.bsmask_pixels); % this transforms it into 1's and NaN's
    warning on MATLAB:divideByZero
end
if str2num(S_template.reduction_state(8))==1 % if the mask is to be used
    a=load(S_template.mask_filename); %mask file contains 1's and 0's
    warning off MATLAB:divideByZero
    S_template.mask_pixels=double(a.mask)./double(a.mask); % this transforms it into 1's and NaN's
    warning on MATLAB:divideByZero
end
if str2num(S_template.reduction_state(7))==1 || str2num(S_template.reduction_state(6))==1 %if either flatfield correction average is to be used.
    stemp=getsaxs(S_template.flatfield_filename);
    S_template.flatfield_pixels=stemp.pixels;
end
if str2num(S_template.reduction_state(11))==1 % if solvet+holder subtraction is to be used.
    stemp=getsaxs(S_template.solvent_filename);
    S_template.solvent_pixels=stemp.pixels;
end
if str2num(S_template.reduction_state(4))==1 % if empty holder subtraction is to be used.
    stemp=getsaxs(S_template.empty_filename);
    S_template.empty_pixels=stemp.pixels;
end
if str2num(S_template.reduction_state(3))==1 % if darkcurrent correction average is to be used.
    stemp=getsaxs(S_template.darkcurrent_filename);
    S_template.darkcurrent_pixels=stemp.pixels;
end
delete(hstatus)
% now ready for parameter window
batch_timeseries(S_template)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function XYGrid(hmenu, eventdata, haxes)
% Menu callback.  Start doing equivalent reduction on other files from
% a grid scan
% The results are saved.

% Select line.
hline = whichline(haxes);
if isempty(hline)
    return
end
drawnow
S_template = get(hline, 'UserData'); 
%since the pixel data has been stripped we need to put it back:
hstatus = figstatus('Preparing Data',get(haxes,'Parent'));  % tell user what to do in a status bar
if str2num(S_template.reduction_state(12))==1 % if the beamstop mask is to be used
    a=add_beamstopmask(S_template);
    warning off MATLAB:divideByZero
    S_template.bsmask_pixels=double(a.bsmask_pixels)./double(a.bsmask_pixels); % this transforms it into 1's and NaN's
    warning on MATLAB:divideByZero
end
if str2num(S_template.reduction_state(8))==1 % if the mask is to be used
    a=load(S_template.mask_filename); %mask file contains 1's and 0's
    S_template.mask_pixels=double(a.mask)./double(a.mask); % this transforms it into 1's and NaN's
end
if str2num(S_template.reduction_state(7))==1 || str2num(S_template.reduction_state(6))==1 %if either flatfield correction average is to be used.
    stemp=getsaxs(S_template.flatfield_filename);
    S_template.flatfield_pixels=stemp.pixels;
end
if str2num(S_template.reduction_state(11))==1 % if solvet+holder subtraction is to be used.
    stemp=getsaxs(S_template.solvent_filename);
    S_template.solvent_pixels=stemp.pixels;
end
if str2num(S_template.reduction_state(4))==1 % if empty holder subtraction is to be used.
    stemp=getsaxs(S_template.empty_filename);
    S_template.empty_pixels=stemp.pixels;
end
if str2num(S_template.reduction_state(3))==1 % if darkcurrent correction average is to be used.
    stemp=getsaxs(S_template.darkcurrent_filename);
    S_template.darkcurrent_pixels=stemp.pixels;
end
delete(hstatus)
% now ready for parameter window
batch_xygrid(S_template)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function WriteAPFile(hmenu, eventdata, haxes)
% Menu callback.  Start doing equivalent reduction on other files..
% The results are saved.

str2(1) = {'You are about to save a AP file which can be used as a template'};
str2(2) = {'for later Automatic Processing. It will be formatted so that '};
str2(3) = {'the data is reduced in the same way as the data in this plot'};
str2(4) = {' '};
str2(5) = {'First you must choose the curve, whose reduction you want to be the template.'};
str2(6) = {'Second you must choose an appropriate saved center file.'};
str2(7) = {'Thirdly you must choose an appropriate q-calibration file.'};
str2(8) = {'Lastly you must choose a location and filename for your new AP-template.'};
str2(9) = {' '};
str2(10) = {'Proceed by clicking "OK"'};
helpdlg(str2,'Instructions for Saving an MP-file reduction')
uiwait

% Select line.
hline = whichline(haxes);
if isempty(hline)
    return
end
drawnow
S_template = get(hline, 'UserData'); 

% now to actually construct the file
ap_1Dwrite(S_template)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function filebatchrun(hmenu, eventdata, haxes)
% Menu callback.  Start doing equivalent reduction on other files..
% The results are saved.
str2(1) = {'You are about to reduce a number of files'};
str2(2) = {'in exactly the same way you have reduced'};
str2(3) = {'the data in this plot'};
str2(4) = {' '};
str2(5) = {'The reduced data will be saved in text files,'};
str2(6) = {'whose names will be very similar to the original names.'};
str2(7) = {' '};
str2(8) = {'First you must choose the curve whose reduction you want to apply to the other files'};
if ispc && version('-release')>10 
    str2(9) = {'Second you must choose the files that will be reduced'};
else
    str2(9) = {'Second you must choose a directory containing exclusively the files you want to be reduced.'};
end
str2(10) = {'Third you must choose the additional tag that you want the new files to be given.'};
str2(11) = {'Lastly you must choose the directory that you want the new files to be placed in.'};
str2(12) = {' '};
str2(13) = {'Proceed by clicking "OK"'};

helpdlg(str2,'Instructions for batch reduction')
uiwait

% Select line.
hline = whichline(haxes);
if isempty(hline)
    return
end
drawnow
S_template = get(hline, 'UserData'); 
%since the pixel data has been striped we need to put it back:
hstatus = figstatus('Preparing Data',get(haxes,'Parent'));  % tell user what to do in a status bar
if str2num(S_template.reduction_state(8))==1 % if the mask is to be used
    a=load(S_template.mask_filename); %mask file contains 1's and 0's
    warning off MATLAB:divideByZero
    S_template.mask_pixels=double(a.mask)./double(a.mask); % this transforms it into 1's and NaN's
    warning on MATLAB:divideByZero
end
if str2num(S_template.reduction_state(12))==1 % if the beamstop mask is to be used
    a=add_beamstopmask(S_template);
    warning off MATLAB:divideByZero
    S_template.bsmask_pixels=double(a.bsmask_pixels)./double(a.bsmask_pixels); % this transforms it into 1's and NaN's
    warning on MATLAB:divideByZero
end
if str2num(S_template.reduction_state(7))==1 || str2num(S_template.reduction_state(6))==1 %if either flatfield correction average is to be used.
    stemp=getsaxs(S_template.flatfield_filename);
    S_template.flatfield_pixels=stemp.pixels;
end
if str2num(S_template.reduction_state(11))==1 % if solvet+holder subtraction is to be used.
    stemp=getsaxs(S_template.solvent_filename);
    S_template.solvent_pixels=stemp.pixels;
end
if str2num(S_template.reduction_state(4))==1 % if empty holder subtraction is to be used.
    stemp=getsaxs(S_template.empty_filename);
    S_template.empty_pixels=stemp.pixels;
end
if str2num(S_template.reduction_state(3))==1 % if darkcurrent correction average is to be used.
    stemp=getsaxs(S_template.darkcurrent_filename);
    S_template.darkcurrent_pixels=stemp.pixels;
end
delete(hstatus)

% here we choose the files to reduce
[path,files]=getfiles('Choose the files you want to reduce');


% now we need the tag
prompt={'Plese enter the "tag" you want to append to the filenames'};
def={'1D'};
dlgTitle='Input "tag" to append to reduced file names';
lineNo=1;
answer=inputdlg(prompt,dlgTitle,lineNo,def);
tag=answer{1};

% now we need to allow the user to put them in an appropriate directory
outputpath=uigetdir(pwd,'Pick a directory for the output files');
if outputpath==0, outputpath=pwd; end
outputpath=[outputpath,filesep];

%if sample transmission and sample thickness are entered then we need to
%figure out how to get these in here.
%first solution is manual entry:

if str2num(S_template.reduction_state(2))==0 % if absolute intensity is to be used
    S_template.abs_int_fact=1;
end

if str2num(S_template.reduction_state(5))==0 % if sample transmission is not to be used
    manual_transfact_entry=0;
else
    prompt={'Do you want to: 0) have different transmission for all files, 1) have same transmission for all files ?'};
    def={'1'};
    dlgTitle='Same or varying transmissions';
    lineNo=1;
    answer=inputdlg(prompt,dlgTitle,lineNo,def);
    if str2num(answer{1})==0
        manual_transfact_entry=1;
    else
        manual_transfact_entry=2;
        prompt={'What transmission do you want for all files?'};
        def={num2str(S_template.transfact)};
        dlgTitle='Input transmission for all files';
        lineNo=1;
        answer=inputdlg(prompt,dlgTitle,lineNo,def);
        transmission=str2num(answer{1});
    end
end

if str2num(S_template.reduction_state(1))==0 % if sample thickness is to not to be used
    manual_sample_thickness_entry=0;
else
    manual_sample_thickness_entry=1;
end

ButtonName=questdlg('Do you want to plot the results','Question');
if strcmp(ButtonName,'Yes')
    plot_results=1;
    outputfigure=figure;
else
    plot_results=0;
end

NumberOfOutputColumns=questdlg('What output do you want ','Question','q I','q I Isig','q I Isig');

for ii=1:length(files)
    filename=[path files{ii}];    
    if manual_transfact_entry==0
        transmission=1;
    elseif manual_transfact_entry==1
        answer=inputdlg(['Enter transmission for: ',files{ii}],'Sample Transmision',1,{'1.00'});
        transmission=str2num(answer{1});  
    end
    if manual_sample_thickness_entry==0
        samplethickness=1;
    else
        answer=inputdlg(['Enter sample thickness (cm) for: ',files{ii}],'Sample thickness ',1,{'0.10'});
        samplethickness=str2num(answer{1});
    end
    hstatus = figstatus(['Reducing: ',files{ii}],get(haxes,'Parent'));  % tell user what to do in a status bar
    [S_xy,S]=reduce_templatewise(filename,S_template,transmission,samplethickness);
    delete(hstatus)
    
    [pathstr,name,ext] = fileparts(S.raw_filename);
    file=[outputpath,name,'_',tag,'.csv'];
    X = S.xaxisfull;
    Y = S.pixels/S.livetime; 
    E=S.relerr.*Y; 
    hold on
    figure(outputfigure)
    loglog(X,Y)
    drawnow
    hold off
    switch NumberOfOutputColumns,
        case 'q I'
                data = [X(:), Y(:)];
        case('q I Isig')
            if length(Y)==length(E)
                data = [X(:), Y(:), E(:)];
            else
                data = [X(:), Y(:)];
            end
    end
    dlmwrite(file, data, ',')
end



% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 
% function ErrorFigCreate(hmenu, eventdata, haxes,S)
% % Menu callback.  Guide user through exporting data to errorbarplot.
% 
% % Select line.
% hline = whichline(haxes);
% if isempty(hline)
%     return
% end
% 
% a=errorgraph(hline,S);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function hline = whichline(haxes)
% Choose a line, any line.  Except the cursor line.  May return empty.
zoom off  % get this nasty thing out of the way
hfig = get(haxes, 'Parent');  % figure window
move_callback = get(hfig, 'WindowButtonMotionFcn');  % save mouse move callback
set(hfig, 'WindowButtonMotionFcn', [])  % suspend mouse move callback
% Hide the cursor and its labels.  The mouse move callback will unhide
% them once we wake it up.
cursor = findobj(haxes, 'Tag', 'cursor');  % find cursor
set(cursor, 'Visible', 'off')  % hide cursor
cursorlabels = findobj(haxes, 'Tag', 'cursor-label');  % find cursor labels
set(cursorlabels, 'Visible', 'off')  % hide labels
% Now select a line by pointin' and clickin'.
hline = selectline(haxes);
% Reinstall mouse move callback.
set(hfig, 'WindowButtonMotionFcn', move_callback)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function MenuViewMATLAB(hmenu, eventdata, haxes)
global separator  % between our menus and MATLAB menus
togglemenu(hmenu)
if ischecked(hmenu)
    separator = uimenu('Label', '|', 'Enable', 'off');
    set(get(haxes,'Parent'), 'MenuBar', 'figure')
else
    set(get(haxes,'Parent'), 'MenuBar', 'none')
    delete(separator)
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function togglemenu(menu)
switch get(menu, 'Checked');
    case 'on'
        checked = 'off';
    case 'off'
        checked = 'on';
end
set(menu, 'Checked', checked)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function checked = ischecked(menu)
% True if menu item is checked.
checked = isequal(get(menu, 'Checked'), 'on');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%   Beginning of files needed for fitting functions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function handles=create_quikfitplots(txt,plottype,ii,batch)
if ii==0 && batch==0
    h=figure;
else
    h=findobj(get(0,'Children'),'Tag','QuikFitPlot');
    fittext=findobj(get(0,'Children'),'Tag','FitText');
    delete(fittext)
end
if isempty(h)
    h=figure;
end
set(h,'Name',txt)
set(h,'Tag','QuikFitPlot')
handles.figure=h;
handles.fit=subplot(2,2,1);
switch plottype
    case 'linlin'
        set(handles.fit,'XScale','linear','YScale','linear')
    case 'loglin'
        set(handles.fit,'XScale','log','YScale','linear')
    case 'linlog'
        set(handles.fit,'XScale','lin','YScale','log')
    case 'loglog'
        set(handles.fit,'XScale','log','YScale','log')
    case 'guinier'
        set(handles.fit,'XScale','lin','YScale','lin')
end
handles.residuals=subplot(2,2,3);
switch plottype
    case 'linlin'
        set(handles.residuals,'XScale','linear')
    case 'loglin'
        set(handles.residuals,'XScale','log')
    case 'linlog'
        set(handles.residuals,'XScale','lin')
    case 'loglog'
        set(handles.residuals,'XScale','log')
    case 'guinier'
        set(handles.residuals,'XScale','lin')
end
handles.text=subplot(2,2,[2 4]);
set(gca,'Xlim',[0 1])
set(gca,'Ylim',[0 1])
title('Fitted parameters')
axis off
drawnow
%define save_fitting parameters values as a txt file
savefitmenu = uimenu('Label', 'Save Fit ');
fit2textfilemenu=uimenu(savefitmenu, 'Label', 'Save to txt file', 'Callback', ...
    {@fit2textfile, handles});

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function handles=fit2textfile(hmenu, eventdata, handles)
persistent olddir
if isempty(olddir) 
    olddir=pwd;
end
newdir=pwd;
cd(olddir);

[filename, pathname]=uiputfile('*.txt','Save the fit information as...');
fitfile=fullfile(pathname,filename);
fid=fopen(fitfile,'w');
strcell=get(handles.fit,'UserData');
for ii=1:length(strcell)
    fprintf(fid,'%s \n',char(strcell(ii)));
end
fclose(fid);
[directorystr,namestr]=fileparts(fitfile);
olddir=directorystr;
cd(newdir);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function nearestindex=enter_clickpoints(haxes,helptext,Xdisp)
num_inputs=length(helptext);
for ii=1:num_inputs
    hstatus=figstatus(helptext{ii},get(haxes,'Parent'));
    clickpoints(ii,:)=ginput(1);
    ix = find(Xdisp >= clickpoints(ii,1)); % index of nearest larger point
    if ~isempty(ix)
        nearestindex(ii) = ix(1);
    else
        nearestindex(ii) = length(Xdisp);
    end
    delete(hstatus)
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [S,X,Y,E,Xdisp,Ydisp]=getdatafromaxes(haxes)

% Select line.
hline = whichline(haxes);
if isempty(hline)
    return
end
S = get(hline, 'UserData');
S.pixels=S.pixels/S.livetime;
Xdisp = get(hline, 'XData'); 
Ydisp = get(hline, 'YData'); 
X = S.xaxisfull;
Y = S.pixels;
E=S.relerr.*Y*2;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%   Beginning of Statistics functions
%   contributed by Karsten Joensen
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function fitsuccess = CalcQuikStat(hmenu, eventdata,haxes,batch)
[S,X,Y,E,Xdisp,Ydisp]=getdatafromaxes(haxes);

fittext='Fitting Gauss Peak with Background Slope';
if (strcmp(S.type,'r-ave'))
    helptext={'#1/2: Click on minimum q to consider' '#2/2: Click on maximum q to consider' };
else
    helptext={'#1/2: Click on minimum angle to consider' '#2/2: Click on maximum anglet to consider' };
end
point_indices=enter_clickpoints(haxes,helptext,Xdisp);
pleft=[X(point_indices(1)) Y(point_indices(1))];
pright=[X(point_indices(2)) Y(point_indices(2))];
if pleft(1)>pright(1);
    temp=pright;
    pright=pleft;
    pleft=temp;
end
result.maximumI=max(Y((X>=pleft(1)) & (X<=pright(1))));
result.minimumI=min(Y((X>=pleft(1)) & (X<=pright(1))));
result.maximumq=max(X((X>=pleft(1)) & (X<=pright(1))));
result.minimumq=min(X((X>=pleft(1)) & (X<=pright(1))));

%Calculating Area:  
X_TMP=(X>pleft(1))& (X<pright(1));
X_ROI=X(X_TMP);
Y_ROI=Y(X_TMP);
result.IntegI=sum(gradient(X_ROI).*(Y_ROI));
if (strcmp(S.type,'r-ave'))
    statmsg=msgbox({...
        ['q-min: ',num2str(result.minimumq)]...
        ['q-max: ',num2str(result.maximumq)]...
        ['I-min: ',num2str(result.minimumI)]...
        ['I-max: ',num2str(result.maximumI)]...
        ['Area: ',num2str(result.IntegI)]}, 'QuikStat results');
else
    statmsg=msgbox({...
        ['angle-min: ',num2str(result.minimumq)]...
        ['angle-max: ',num2str(result.maximumq)]...
        ['I-min: ',num2str(result.minimumI)]...
        ['I-max: ',num2str(result.maximumI)]...
        ['Area: ',num2str(result.IntegI)]}, 'QuikStat results');
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%   Beginning of fitting functions
%   Most of them contributed by Brian Pauw 
%   and to a lesser degree Karsten Joensen
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function fitsuccess = FitGaussPeakSlope(hmenu, eventdata,haxes,batch)
global fitpar
% first get some information from the data in the plot window
[S_orig,X,Y,E,Xdisp,Ydisp]=getdatafromaxes(haxes);
[pathstr,namestr]=fileparts(S_orig.raw_filename);
fittext='Fitting Gauss Peak with Background Slope';

% then if this is batch-mode, we need additional information
if batch==1,
    [S_template,fitfilespath,fitfiles,outputpath,outputfile,tag]=batchfitprepare(hmenu, eventdata, haxes);
    %S_template has the same raw information as S_orig...but has all of the data
    %added (masks, empty etc)
else
    fitfiles={namestr};
    fitfilespath=pathstr;
    outputfile='tmp';
    S_template=S_orig;
end
if isempty(fitfiles) || isempty(outputfile)
    errordlg('Batch fitting has been aborted since some of the parameters entered, could not be resolved (perhaps cancel button was pressed')
    return
end

% now get information for the fit
if (strcmp(S_orig.type,'r-ave'))
    helptext={'#1/3: Click on minimum q to fit' '#2/3: Click on maximum q to fit' '#3/3: Click on peak value'};
else
    helptext={'#1/3: Click on minimum angle to fit' '#2/3: Click on maximum angle to fit' '#3/3: Click on peak value'};
end
point_indices=enter_clickpoints(haxes,helptext,Xdisp);

% now begin to cycle the files to fit
for ii=0:length(fitfiles)-1
    namestr=fitfiles{ii+1};
    [S,X,Y]=get_create_SXY(S_orig,S_template,fitfilespath,fitfiles{ii+1},batch,X,Y);
    
    pleft=[X(point_indices(1)) Y(point_indices(1))];
    pright=[X(point_indices(2)) Y(point_indices(2))];
    if pleft(1)>pright(1)
        temp=pright;
        pright=pleft;
        pleft=temp;
    end
    peak=[X(point_indices(3)) Y(point_indices(3))];

    %peakwidth=abs((X(point_indices(4))-peak(1))/2.35*2)
    peakpos=peak(1);
    backslope=(pleft(2)-pright(2))/(pleft(1)-pright(1));
    peakback=backslope*(peakpos-pleft(1))+pleft(2);
    peakamp=peak(2)-peakback;

    FWHM=max((max(X(Y>(peakamp/2+peakback)))-min(X(Y>(peakamp/2+peakback)))),X(2)-X(1));
    peakwidth=FWHM/2.35;

    %first fit only the peak:
    fitpar.name='GaussPeakSlope.m';
    fitpar.binning=1;
    fitpar.fit=[1 1 1 0 0];
    fitpar.numiter=5000;
    fitpar.tol=0.0001;
    fitpar.graphics=1;
    fitpar.start=[peakpos peakamp peakwidth peakback backslope];
    fitpar.ll=[0 0 0 0 -Inf];
    fitpar.ul=[Inf Inf Inf Inf Inf];

    handles=create_quikfitplots(fittext,'linlog',ii,batch);

    bounds=[pleft(1) pright(1)];
    hstatus=figstatus('Fitting peak...',handles.figure);

    [Fitparam,Fitval,Info] = fitsaxs1D(S,bounds,handles);
    delete(hstatus)
    %then use values and fit only the background
    fitpar.binning=1;
    fitpar.fit=[0 0 0 1 1];
    fitpar.numiter=5000;
    fitpar.tol=0.0001;
    fitpar.graphics=1;
    fitpar.start=[Fitparam(1) Fitparam(2) Fitparam(3) peakback backslope];
    fitpar.ll=[0 0 0 0 -Inf];
    fitpar.ul=[Inf Inf Inf Inf Inf];
    hstatus=figstatus('Fitting background...',handles.figure);

    [Fitparam,Fitval,Info] = fitsaxs1D(S,bounds,handles);
    delete(hstatus)
    %then use the values and fit everything
    fitpar.binning=1;
    fitpar.fit=[1 1 1 1 1];
    fitpar.numiter=5000;
    fitpar.tol=0.0001;
    fitpar.graphics=1;
    fitpar.start=Fitparam;
    fitpar.ll=[0 0 0 0 -Inf];
    fitpar.ul=[Inf Inf Inf Inf Inf];
    hstatus=figstatus('Refining Fit...',handles.figure);
    [Fitparam,Fitval,Info] = fitsaxs1D(S,bounds,handles);
    delete(hstatus)


    %Calculating Area in Peak:  Measured Intensity minus calculated background
    %First calculated background:
    X_TMP=(X>pleft(1))& (X<pright(1));
    X_ROI=X(X_TMP);
    Y_ROI=Y(X_TMP);
    calc_back=GaussPeakSlope(X_ROI,X_ROI,[Fitparam(1),0,Fitparam(3),Fitparam(4),Fitparam(5)]);
    peak_area=sum(gradient(X_ROI).*(Y_ROI-calc_back));
    axes(handles.text);
    if (strcmp(S.type,'r-ave'))
        outtext={['Function: ',fitpar.name],...
            ['Data    : ',namestr],...
            ['----------'],...
            ['Center ): ',num2str(Fitparam(1))],...
            ['D-spacing [A]: ',num2str(2*pi/Fitparam(1))],...
            ['Amplitude: ', num2str(Fitparam(2))],...
            ['Width(sigma):', num2str(Fitparam(3))],...
            ['Width(FWHM):', num2str(Fitparam(3)*2.35)],...
            ['Background at peak: ', num2str(Fitparam(4))],...
            ['Slope of Background :',num2str(Fitparam(5))],...
            ['----------------'],...
            ['Meas. Area in Peak :',num2str(peak_area)],...
            ['Theor. Area in Peak :',num2str(Fitparam(2)*Fitparam(3)*sqrt(2*pi))]};
    else
        outtext={['Function: ',fitpar.name],...
            ['Data    : ',namestr],...
            ['----------'],...
            ['Center [deg]): ',num2str(Fitparam(1))],...
            ['Amplitude: ', num2str(Fitparam(2))],...
            ['Width(sigma)[deg]:', num2str(Fitparam(3))],...
            ['Width(FWHM)[deg]:', num2str(Fitparam(3)*2.35)],...
            ['Background at peak: ', num2str(Fitparam(4))],...
            ['Slope of Background :',num2str(Fitparam(5))],...
            ['----------------'],...
            ['Meas. Area in Peak :',num2str(peak_area)],...
            ['Theor. Area in Peak :',num2str(Fitparam(2)*Fitparam(3)*sqrt(2*pi))]};
    end
    fittexthandle=text(0.1,0.5,outtext);
    set(handles.fit,'UserData',outtext)
    set(fittexthandle,'Tag','FitText')
    %now put something that outputs the image and the data to a file if we are
    %in batch mode
    if batch>0
        batchquikfitoutput(handles,fitfilespath,fitfiles{ii+1},outputpath,outputfile,tag)
    end
    
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function fitsuccess = FitGaussPeakSpline(hmenu, eventdata,haxes,batch)
global fitpar

%this function adds a background function according to eqn 8 in Koberstein,
%Morra and Stein, J. App. Cryst. 1980 13, 34--45

% first get some information from the data in the plot window
[S_orig,X,Y,E,Xdisp,Ydisp]=getdatafromaxes(haxes);
[pathstr,namestr]=fileparts(S_orig.raw_filename);
fittext='Fitting Gauss Peak with Background spline';
% then if this is batch-mode, we need additional information
if batch==1,
    [S_template,fitfilespath,fitfiles,outputpath,outputfile,tag]=batchfitprepare(hmenu, eventdata, haxes);
    %S_template has the same raw information as S_orig...but has all of the data
    %added (masks, empty etc)
else
    fitfiles={namestr};
    fitfilespath=pathstr;
    outputfile='tmp';
    S_template=S_orig;
end
if isempty(fitfiles) || isempty(outputfile)
    errordlg('Batch fitting has been aborted since some of the parameters entered, could not be resolved (perhaps cancel button was pressed')
    return
end

% now get information for the fit
if (strcmp(S_orig.type,'r-ave'))
    helptext={'#1/3: Click on minimum q to fit' '#2/3: Click on maximum q to fit' '#3/3: Click on peak value'};
else
    helptext={'#1/3: Click on minimum angle to fit' '#2/3: Click on maximum angle to fit' '#3/3: Click on peak value'};
end

point_indices=enter_clickpoints(haxes,helptext,Xdisp);

% now begin to cycle the files to fit
for ii=0:length(fitfiles)-1
    namestr=fitfiles{ii+1};
    [S,X,Y]=get_create_SXY(S_orig,S_template,fitfilespath,fitfiles{ii+1},batch,X,Y);

    pleft=[X(point_indices(1)) Y(point_indices(1))];
    pright=[X(point_indices(2)) Y(point_indices(2))];
    if pleft(1)>pright(1);
        temp=pright;
        pright=pleft;
        pleft=temp;
    end
    peak=[X(point_indices(3)) Y(point_indices(3))];


    %peakwidth=abs((X(point_indices(4))-peak(1))/2.35*2)
    peakpos=peak(1);

    backexp=log(pleft(2)/pright(2))/(pleft(1)^2-pright(1)^2);
    backinten=pright(2)/exp(backexp*pright(1)^2);
    peakamp=peak(2)-backinten*exp(backexp*((pright(1)+pleft(1))/2)^2);

    FWHM=0.25*(pright(1)-pleft(1)); %a little rough, but functional
    peakwidth=FWHM/2.35;

    fitpar.name='GaussPeakSpline.m';
    fitpar.binning=1;
    fitpar.fit=[1 1 1 1 1];
    fitpar.numiter=500;
    fitpar.tol=0.001;
    fitpar.graphics=1;
    fitpar.start=[peakpos peakamp peakwidth backinten backexp];
    fitpar.ll=[0 0 0 0 -Inf];
    fitpar.ul=[Inf Inf Inf Inf Inf];

    handles=create_quikfitplots(fittext,'linlog',ii,batch);

    bounds=[pleft(1) pright(1)];
    hstatus=figstatus('Fitting...',handles.figure);

    [Fitparam,Fitval,Info] = fitsaxs1D(S,bounds,handles);
    delete(hstatus)

    %Calculating Area in Peak:  Measured Intensity minus calculated background
    %First calculated background:
    X_TMP=(X>pleft(1))& (X<pright(1));
    X_ROI=X(X_TMP);
    Y_ROI=Y(X_TMP);
    calc_back=GaussPeakSpline(X_ROI,X_ROI,[Fitparam(1),0,Fitparam(3),Fitparam(4),Fitparam(5)]);
    peak_area=sum(gradient(X_ROI).*(Y_ROI-calc_back));
    twopoints=[Fitparam(1),Fitparam(1)+X_ROI(2)-X_ROI(1)];
    back_near_peak=GaussPeakSpline(twopoints,twopoints,[Fitparam(1),0,Fitparam(3),Fitparam(4),Fitparam(5)]);
    slope_near_peak=(back_near_peak(2)-back_near_peak(1))/(X_ROI(2)-X_ROI(1));
    %now for output
    axes(handles.text);
    if (strcmp(S.type,'r-ave'))
        outtext={['Function: ',fitpar.name],...
            ['Data    : ',namestr],...
            ['----------'],...
            ['Center: ',num2str(Fitparam(1))],...
            ['D-spacing [A]: ',num2str(2*pi/Fitparam(1))],...
            ['Amplitude: ', num2str(Fitparam(2))],...
            ['Width(sigma) :', num2str(Fitparam(3))],...
            ['Width(FWHM) :', num2str(Fitparam(3)*2.35)],...
            ['Background Parameter 1: ', num2str(Fitparam(4))],...
            ['Background Parameter 2:',num2str(Fitparam(5))],...
            ['----------------'],...
            ['Background at peak: ', num2str(back_near_peak(1))],...
            ['Slope of Background :',num2str(slope_near_peak)],...
            ['Meas. Area in Peak :',num2str(peak_area)],...
            ['Theor. Area in Peak :',num2str(Fitparam(2)*Fitparam(3)*sqrt(2*pi))]};
    else
        outtext={['Function: ',fitpar.name],...
            ['Data    : ',namestr],...
            ['----------'],...
            ['Center: ',num2str(Fitparam(1))],...
            ['Amplitude: ', num2str(Fitparam(2))],...
            ['Width(sigma) :', num2str(Fitparam(3))],...
            ['Width(FWHM) :', num2str(Fitparam(3)*2.35)],...
            ['Background Parameter 1: ', num2str(Fitparam(4))],...
            ['Background Parameter 2:',num2str(Fitparam(5))],...
            ['----------------'],...
            ['Background at peak: ', num2str(back_near_peak(1))],...
            ['Slope of Background :',num2str(slope_near_peak)],...
            ['Meas. Area in Peak :',num2str(peak_area)],...
            ['Theor. Area in Peak :',num2str(Fitparam(2)*Fitparam(3)*sqrt(2*pi))]};
    end
    fittexthandle=text(0.1,0.5,outtext);
    set(handles.fit,'UserData',outtext)
    set(fittexthandle,'Tag','FitText')
    %now put something that outputs the image and the data to a file if we are
    %in batch mode
    if batch>0
        batchquikfitoutput(handles,fitfilespath,fitfiles{ii+1},outputpath,outputfile,tag)
    end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function fitsuccess = FitLorentzPeakSlope(hmenu, eventdata,haxes,batch)
global fitpar

% first get some information from the data in the plot window
[S_orig,X,Y,E,Xdisp,Ydisp]=getdatafromaxes(haxes);
[pathstr,namestr]=fileparts(S_orig.raw_filename);
fittext='Fitting Lorentzian Peak with Background Slope';
% then if this is batch-mode, we need additional information
if batch==1,
    [S_template,fitfilespath,fitfiles,outputpath,outputfile,tag]=batchfitprepare(hmenu, eventdata, haxes);
    %S_template has the same raw information as S_orig...but has all of the data
    %added (masks, empty etc)
else
    fitfiles={namestr};
    fitfilespath=pathstr;
    outputfile='tmp';
    S_template=S_orig;
end
if isempty(fitfiles) || isempty(outputfile)
    errordlg('Batch fitting has been aborted since some of the parameters entered, could not be resolved (perhaps cancel button was pressed')
    return
end

% now get information for the fit
if (strcmp(S_orig.type,'r-ave'))
    helptext={'#1/3: Click on minimum q to fit' '#2/3: Click on maximum q to fit' '#3/3: Click on peak value'};
else
    helptext={'#1/3: Click on minimum angle to fit' '#2/3: Click on maximum angle to fit' '#3/3: Click on peak value'};
end
point_indices=enter_clickpoints(haxes,helptext,Xdisp);
% now begin to cycle the files to fit
for ii=0:length(fitfiles)-1
    namestr=fitfiles{ii+1};
    [S,X,Y]=get_create_SXY(S_orig,S_template,fitfilespath,fitfiles{ii+1},batch,X,Y);
    pleft=[X(point_indices(1)) Y(point_indices(1))];
    pright=[X(point_indices(2)) Y(point_indices(2))];
    if pleft(1)>pright(1);
        temp=pright;
        pright=pleft;
        pleft=temp;
    end
    peak=[X(point_indices(3)) Y(point_indices(3))];

    %peakwidth=abs((X(point_indices(4))-peak(1))/2.35*2)
    peakpos=peak(1);
    backslope=(pleft(2)-pright(2))/(pleft(1)-pright(1));
    peakback=backslope*(peakpos-pleft(1))+pleft(2);
    peakamp=peak(2)-peakback; %l=2/pi*width

    FWHM=0.25*(pright(1)-pleft(1)); %a little rough, but functional;
    peakwidth=FWHM;

    fitpar.name='LorentzPeakSlope.m';
    fitpar.binning=1;
    fitpar.fit=[1 1 1 1 1];
    fitpar.numiter=500;
    fitpar.tol=0.001;
    fitpar.graphics=1;
    fitpar.start=[peakpos peakamp peakwidth peakback backslope];
    fitpar.ll=[0 0 0 0 -Inf];
    fitpar.ul=[Inf Inf Inf Inf Inf];

    handles=create_quikfitplots(fittext,'linlog',ii,batch);

    bounds=[pleft(1) pright(1)];
    hstatus=figstatus('Fitting...',handles.figure);

    [Fitparam,Fitval,Info] = fitsaxs1D(S,bounds,handles);
    delete(hstatus)

    %Calculating Area in Peak:  Measured Intensity minus calculated background
    %First calculated background:
    X_TMP=(X>pleft(1))& (X<pright(1));
    X_ROI=X(X_TMP);
    Y_ROI=Y(X_TMP);
    calc_back=LorentzPeakSlope(X_ROI,X_ROI,[Fitparam(1),0,Fitparam(3),Fitparam(4),Fitparam(5)]);
    peak_area=sum(gradient(X_ROI).*(Y_ROI-calc_back));
    %now for output


    axes(handles.text);
    if (strcmp(S.type,'r-ave'))

        outtext={['Function: ',fitpar.name],...
            ['Data    : ',namestr],...
            ['----------'],...
            ['Center: ',num2str(Fitparam(1))],...
            ['D-spacing [A]: ',num2str(2*pi/Fitparam(1))],...
            ['Peak Amplitude: ', num2str(Fitparam(2))],...
            ['Width(FWHM) :', num2str(Fitparam(3))],...
            ['Background at peak: ', num2str(Fitparam(4))],...
            ['Slope of Background :',num2str(Fitparam(5))],...
            ['----------------'],...
            ['Meas. Area in Peak :',num2str(peak_area)],...
            ['Theor. Area in Peak :',num2str(Fitparam(2)*Fitparam(3)/2*pi)]};
    else
        outtext={['Function: ',fitpar.name],...
            ['Data    : ',namestr],...
            ['----------'],...
            ['Center: ',num2str(Fitparam(1))],...
            ['Peak Amplitude: ', num2str(Fitparam(2))],...
            ['Width(FWHM) :', num2str(Fitparam(3))],...
            ['Background at peak: ', num2str(Fitparam(4))],...
            ['Slope of Background :',num2str(Fitparam(5))],...
            ['----------------'],...
            ['Meas. Area in Peak :',num2str(peak_area)],...
            ['Theor. Area in Peak :',num2str(Fitparam(2)*Fitparam(3)/2*pi)]};
    end
    fittexthandle=text(0.1,0.5,outtext);
    set(handles.fit,'UserData',outtext)
    set(fittexthandle,'Tag','FitText')
    %now put something that outputs the image and the data to a file if we are
    %in batch mode
    if batch>0
        batchquikfitoutput(handles,fitfilespath,fitfiles{ii+1},outputpath,outputfile,tag)
    end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function fitsuccess = FitLorentzPeakSpline(hmenu, eventdata,haxes,batch)
global fitpar

%this function adds a background function according to eqn 8 in Koberstein,
%Morra and Stein, J. App. Cryst. 1980 13, 34--45

% first get some information from the data in the plot window
[S_orig,X,Y,E,Xdisp,Ydisp]=getdatafromaxes(haxes);
[pathstr,namestr]=fileparts(S_orig.raw_filename);

fittext='Fitting Lorentz Peak with Background spline';
% then if this is batch-mode, we need additional information
if batch==1,
    [S_template,fitfilespath,fitfiles,outputpath,outputfile,tag]=batchfitprepare(hmenu, eventdata, haxes);
    %S_template has the same raw information as S_orig...but has all of the data
    %added (masks, empty etc)
else
    fitfiles={namestr};
    fitfilespath=pathstr;
    outputfile='tmp';
    S_template=S_orig;
end
if isempty(fitfiles) || isempty(outputfile)
    errordlg('Batch fitting has been aborted since some of the parameters entered, could not be resolved (perhaps cancel button was pressed')
    return
end

% now get information for the fit
if (strcmp(S_orig.type,'r-ave'))
    helptext={'#1/3: Click on minimum q to fit' '#2/3: Click on maximum q to fit' '#3/3: Click on peak value'};
else
    helptext={'#1/3: Click on minimum angle to fit' '#2/3: Click on maximum angle to fit' '#3/3: Click on peak value'};
end
point_indices=enter_clickpoints(haxes,helptext,Xdisp);
% now begin to cycle the files to fit
for ii=0:length(fitfiles)-1
    namestr=fitfiles{ii+1};
    [S,X,Y]=get_create_SXY(S_orig,S_template,fitfilespath,fitfiles{ii+1},batch,X,Y);

    pleft=[X(point_indices(1)) Y(point_indices(1))];
    pright=[X(point_indices(2)) Y(point_indices(2))];
    if pleft(1)>pright(1);
        temp=pright;
        pright=pleft;
        pleft=temp;
    end
    peak=[X(point_indices(3)) Y(point_indices(3))];


    peakpos=peak(1);

    backexp=log(pleft(2)/pright(2))/(pleft(1)^2-pright(1)^2);
    backinten=pright(2)/exp(backexp*pright(1)^2);
    peakamp=peak(2)-backinten*exp(backexp*((pright(1)+pleft(1))/2)^2);

    FWHM=0.25*(pright(1)-pleft(1)); %a little rough, but functional
    peakwidth=FWHM;


    %first fit only the peak:
    fitpar.name='LorentzPeakSpline.m';
    fitpar.binning=1;
    fitpar.fit=[1 1 1 0 0];
    fitpar.numiter=500;
    fitpar.tol=0.001;
    fitpar.graphics=1;
    fitpar.start=[peakpos peakamp peakwidth backinten backexp];
    fitpar.ll=[0 0 0 0 -Inf];
    fitpar.ul=[Inf Inf Inf Inf Inf];

    handles=create_quikfitplots(fittext,'linlog',ii,batch);

    bounds=[pleft(1) pright(1)];
    hstatus=figstatus('Fitting...',handles.figure);

    [Fitparam,Fitval,Info] = fitsaxs1D(S,bounds,handles);
    delete(hstatus)
    %then use values and fit only the background
    fitpar.binning=1;
    fitpar.fit=[0 0 0 1 1];
    fitpar.numiter=5000;
    fitpar.tol=0.0001;
    fitpar.graphics=1;
    fitpar.start=[Fitparam(1) Fitparam(2) Fitparam(3) backinten backexp];
    fitpar.ll=[0 0 0 0 -Inf];
    fitpar.ul=[Inf Inf Inf Inf Inf];
    hstatus=figstatus('Fitting background...',handles.figure);

    [Fitparam,Fitval,Info] = fitsaxs1D(S,bounds,handles);
    delete(hstatus)

    %then use the values and fit everything
    fitpar.binning=1;
    fitpar.fit=[1 1 1 1 1];
    fitpar.numiter=5000;
    fitpar.tol=0.0001;
    fitpar.graphics=1;
    fitpar.start=Fitparam;
    fitpar.ll=[0 0 0 0 -Inf];
    fitpar.ul=[Inf Inf Inf Inf Inf];
    hstatus=figstatus('Refining Fit...',handles.figure);
    [Fitparam,Fitval,Info] = fitsaxs1D(S,bounds,handles);
    delete(hstatus)

    %Calculating Area in Peak:  Measured Intensity minus calculated background
    %First calculated background:
    X_TMP=(X>pleft(1))& (X<pright(1));
    X_ROI=X(X_TMP);
    Y_ROI=Y(X_TMP);
    calc_back=LorentzPeakSpline(X_ROI,X_ROI,[Fitparam(1),0,Fitparam(3),Fitparam(4),Fitparam(5)]);
    peak_area=sum(gradient(X_ROI).*(Y_ROI-calc_back));
    twopoints=[Fitparam(1),Fitparam(1)+X_ROI(2)-X_ROI(1)];
    back_near_peak=LorentzPeakSpline(twopoints,twopoints,[Fitparam(1),0,Fitparam(3),Fitparam(4),Fitparam(5)]);

    %now for output

    axes(handles.text);
    if (strcmp(S.type,'r-ave'))

        outtext={['Function: ',fitpar.name],...
            ['Data    : ',namestr],...
            ['----------'],...
            ['Center: ',num2str(Fitparam(1))],...
            ['D-spacing [A]: ',num2str(2*pi/Fitparam(1))],...
            ['Peak Amplitude: ', num2str(Fitparam(2))],...
            ['Width(FWHM) :', num2str(Fitparam(3))],...
            ['Background Parameter 1: ', num2str(Fitparam(4))],...
            ['Background Parameter 2:',num2str(Fitparam(5))],...
            ['----------------'],...
            ['Background at peak: ', num2str(back_near_peak(1))],...
            ['Meas. Area in Peak :',num2str(peak_area)],...
            ['Theor. Area in Peak :',num2str(Fitparam(2)*Fitparam(3)/2*pi)]};
    else
        outtext={['Function: ',fitpar.name],...
            ['Data    : ',namestr],...
            ['----------'],...
            ['Center: ',num2str(Fitparam(1))],...
            ['Peak Amplitude: ', num2str(Fitparam(2))],...
            ['Width(FWHM) :', num2str(Fitparam(3))],...
            ['Background Parameter 1: ', num2str(Fitparam(4))],...
            ['Background Parameter 2:',num2str(Fitparam(5))],...
            ['----------------'],...
            ['Background at peak: ', num2str(back_near_peak(1))],...
            ['Meas. Area in Peak :',num2str(peak_area)],...
            ['Theor. Area in Peak :',num2str(Fitparam(2)*Fitparam(3)/2*pi)]};
    end
    fittexthandle=text(0.1,0.5,outtext);
    set(handles.fit,'UserData',outtext)
    set(fittexthandle,'Tag','FitText')
    %now put something that outputs the image and the data to a file if we are
    %in batch mode
    if batch>0
        batchquikfitoutput(handles,fitfilespath,fitfiles{ii+1},outputpath,outputfile,tag)
    end

end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function fitsuccess = FitPearsonPeakSlope(hmenu, eventdata,haxes,batch)
global fitpar

% first get some information from the data in the plot window
[S_orig,X,Y,E,Xdisp,Ydisp]=getdatafromaxes(haxes);
[pathstr,namestr]=fileparts(S_orig.raw_filename);
fittext='Fitting Pearson Peak with Background Slope';

% then if this is batch-mode, we need additional information
if batch==1,
    [S_template,fitfilespath,fitfiles,outputpath,outputfile,tag]=batchfitprepare(hmenu, eventdata, haxes);
    %S_template has the same raw information as S_orig...but has all of the data
    %added (masks, empty etc)
else
    fitfiles={namestr};
    fitfilespath=pathstr;
    outputfile='tmp';
    S_template=S_orig;
end
if isempty(fitfiles) || isempty(outputfile)
    errordlg('Batch fitting has been aborted since some of the parameters entered, could not be resolved (perhaps cancel button was pressed')
    return
end

% now get information for the fit
if (strcmp(S_orig.type,'r-ave'))
    helptext={'#1/3: Click on minimum q to fit' '#2/3: Click on maximum q to fit' '#3/3: Click on peak value'};
else
    helptext={'#1/3: Click on minimum angle to fit' '#2/3: Click on maximum angle to fit' '#3/3: Click on peak value'};
end
point_indices=enter_clickpoints(haxes,helptext,Xdisp);

% now begin to cycle the files to fit
for ii=0:length(fitfiles)-1
    namestr=fitfiles{ii+1};
    [S,X,Y]=get_create_SXY(S_orig,S_template,fitfilespath,fitfiles{ii+1},batch,X,Y);
    pleft=[X(point_indices(1)) Y(point_indices(1))];
    pright=[X(point_indices(2)) Y(point_indices(2))];
    if pleft(1)>pright(1);
        temp=pright;
        pright=pleft;
        pleft=temp;
    end
    peak=[X(point_indices(3)) Y(point_indices(3))];


    peakpos=peak(1);
    backslope=(pleft(2)-pright(2))/(pleft(1)-pright(1));
    peakback=backslope*(peakpos-pleft(1))+pleft(2);
    peakamp=peak(2)-peakback; %l=2/pi*width

    FWHM=0.25*(pright(1)-pleft(1)); %a little rough, but functional;
    peakwidth=FWHM;

    peaktail=2;%start with Lorentzian type tailing

    fitpar.name='PearsonPeakSlope.m';
    fitpar.binning=1;
    fitpar.fit=[1 1 1 1 1 1];
    fitpar.numiter=500;
    fitpar.tol=0.001;
    fitpar.graphics=1;
    fitpar.start=[peakpos peakamp peakwidth peaktail peakback backslope];
    fitpar.ll=[0 0 0 0 0 -Inf];
    fitpar.ul=[Inf Inf Inf Inf Inf Inf];

    handles=create_quikfitplots(fittext,'linlog',ii,batch);

    bounds=[pleft(1) pright(1)];
    hstatus=figstatus('Fitting...',handles.figure);

    [Fitparam,Fitval,Info] = fitsaxs1D(S,bounds,handles);
    delete(hstatus)

    if Fitparam(4)<0.75
        peaktype='pointy';
    elseif Fitparam(4)>=0.75 && Fitparam(4)<2
        peaktype='Lorentzian';
    else
        peaktype='Gaussian';
    end
    %Calculating Area in Peak:  Measured Intensity minus calculated background
    %First calculated background:
    X_TMP=(X>pleft(1))& (X<pright(1));
    X_ROI=X(X_TMP);
    Y_ROI=Y(X_TMP);
    calc_back=PearsonPeakSlope(X_ROI,X_ROI,[Fitparam(1),0,Fitparam(3),Fitparam(4),Fitparam(5),Fitparam(6)]);
    peak_area=sum(gradient(X_ROI).*(Y_ROI-calc_back));
    %now for output

    axes(handles.text);

    if (strcmp(S.type,'r-ave'))
        outtext={['Function: ',fitpar.name],...
            ['Data    : ',namestr],...
            ['----------'],...
            ['Center: ',num2str(Fitparam(1))],...
            ['D-spacing [A]: ',num2str(2*pi/Fitparam(1))],...
            ['FWHM :', num2str(Fitparam(3))],...
            ['Tailing(M): ', num2str(Fitparam(4))],...
            ['Approx. peak type: ',peaktype],...
            ['Background at peak: ', num2str(Fitparam(5))],...
            ['Slope of Background :',num2str(Fitparam(6))],...
            ['----------------'],...
            ['Meas. Area in Peak :',num2str(peak_area)]};
    else
        outtext={['Function: ',fitpar.name],...
            ['Data    : ',namestr],...
            ['----------'],...
            ['Center: ',num2str(Fitparam(1))],...
            ['FWHM :', num2str(Fitparam(3))],...
            ['Tailing(M): ', num2str(Fitparam(4))],...
            ['Approx. peak type: ',peaktype],...
            ['Background at peak: ', num2str(Fitparam(5))],...
            ['Slope of Background :',num2str(Fitparam(6))],...
            ['----------------'],...
            ['Meas. Area in Peak :',num2str(peak_area)]};
    end
    fittexthandle=text(0.1,0.5,outtext);
    set(handles.fit,'UserData',outtext)
    set(fittexthandle,'Tag','FitText')
    %now put something that outputs the image and the data to a file if we are
    %in batch mode
    if batch>0
        batchquikfitoutput(handles,fitfilespath,fitfiles{ii+1},outputpath,outputfile,tag)
    end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function fitsuccess = FitPearsonPeakSpline(hmenu, eventdata,haxes,batch)
global fitpar

%this function adds a background function according to eqn 8 in Koberstein,
%Morra and Stein, J. App. Cryst. 1980 13, 34--45

% first get some information from the data in the plot window
[S_orig,X,Y,E,Xdisp,Ydisp]=getdatafromaxes(haxes);
[pathstr,namestr]=fileparts(S_orig.raw_filename);
fittext='Fitting Pearson Peak with Background spline';

% then if this is batch-mode, we need additional information
if batch==1,
    [S_template,fitfilespath,fitfiles,outputpath,outputfile,tag]=batchfitprepare(hmenu, eventdata, haxes);
    %S_template has the same raw information as S_orig...but has all of the data
    %added (masks, empty etc)
else
    fitfiles={namestr};
    fitfilespath=pathstr;
    outputfile='tmp';
    S_template=S_orig;
end
if isempty(fitfiles) || isempty(outputfile)
    errordlg('Batch fitting has been aborted since some of the parameters entered, could not be resolved (perhaps cancel button was pressed')
    return
end

% now get information for the fit
if (strcmp(S_orig.type,'r-ave'))
    helptext={'#1/3: Click on minimum q to fit' '#2/3: Click on maximum q to fit' '#3/3: Click on peak value'};
else
    helptext={'#1/3: Click on minimum angle to fit' '#2/3: Click on maximum angle to fit' '#3/3: Click on peak value'};
end
point_indices=enter_clickpoints(haxes,helptext,Xdisp);
% now begin to cycle the files to fit
for ii=0:length(fitfiles)-1
    namestr=fitfiles{ii+1};
    [S,X,Y]=get_create_SXY(S_orig,S_template,fitfilespath,fitfiles{ii+1},batch,X,Y);
    pleft=[X(point_indices(1)) Y(point_indices(1))];
    pright=[X(point_indices(2)) Y(point_indices(2))];
    if pleft(1)>pright(1);
        temp=pright;
        pright=pleft;
        pleft=temp;
    end
    peak=[X(point_indices(3)) Y(point_indices(3))];

    peakpos=peak(1);

    backexp=log(pleft(2)/pright(2))/(pleft(1)^2-pright(1)^2);
    backinten=pright(2)/exp(backexp*pright(1)^2);
    peakamp=peak(2)-backinten*exp(backexp*((pright(1)+pleft(1))/2)^2);

    FWHM=0.25*(pright(1)-pleft(1)); %a little rough, but functional
    peakwidth=FWHM;

    peaktail=2; % start with Lorentzian-type peak tailing
    fitpar.name='PearsonPeakSpline.m';
    fitpar.binning=1;
    fitpar.fit=[1 1 1 1 1 1];
    fitpar.numiter=500;
    fitpar.tol=0.001;
    fitpar.graphics=1;
    fitpar.start=[peakpos peakamp peakwidth peaktail backinten backexp];
    fitpar.ll=[0 0 0 0 0 -Inf];
    fitpar.ul=[Inf Inf Inf Inf Inf Inf];

    handles=create_quikfitplots(fittext,'linlog',ii,batch);

    bounds=[pleft(1) pright(1)];
    hstatus=figstatus('Fitting...',handles.figure);

    [Fitparam,Fitval,Info] = fitsaxs1D(S,bounds,handles);
    delete(hstatus)

    if Fitparam(4)<0.75
        peaktype='pointy';
    elseif Fitparam(4)>=0.75 && Fitparam(4)<2
        peaktype='Lorentzian';
    else
        peaktype='Gaussian';
    end
    %Calculating Area in Peak:  Measured Intensity minus calculated background
    %First calculated background:
    X_TMP=(X>pleft(1))& (X<pright(1));
    X_ROI=X(X_TMP);
    Y_ROI=Y(X_TMP);
    calc_back=PearsonPeakSpline(X_ROI,X_ROI,[Fitparam(1),0,Fitparam(3),Fitparam(4),Fitparam(5),Fitparam(6)]);
    peak_area=sum(gradient(X_ROI).*(Y_ROI-calc_back));
    twopoints=[Fitparam(1),Fitparam(1)+X_ROI(2)-X_ROI(1)];
    back_near_peak=PearsonPeakSpline(twopoints,twopoints,[Fitparam(1),0,Fitparam(3),Fitparam(4),Fitparam(5),Fitparam(6)]);
    %now for output

    axes(handles.text);
    if (strcmp(S.type,'r-ave'))
        outtext={['Function: ',fitpar.name],...
            ['Data    : ',namestr],...
            ['----------'],...
            ['Center: ',num2str(Fitparam(1))],...
            ['D-spacing [A]: ',num2str(2*pi/Fitparam(1))],...
            ['FWHM (W) :', num2str(Fitparam(3))],...
            ['Tailing(M): ', num2str(Fitparam(4))],...
            ['Approx. peak type: ',peaktype],...
            ['Background Parameter 1: ', num2str(Fitparam(5))],...
            ['Background Parameter 2:',num2str(Fitparam(6))],...
            ['----------------'],...
            ['Background at peak: ', num2str(back_near_peak(1))],...
            ['Meas. Area in Peak :',num2str(peak_area)]};
    else
        outtext={['Function: ',fitpar.name],...
            ['Data    : ',namestr],...
            ['----------'],...
            ['Center: ',num2str(Fitparam(1))],...
            ['FWHM (W) :', num2str(Fitparam(3))],...
            ['Tailing(M): ', num2str(Fitparam(4))],...
            ['Approx. peak type: ',peaktype],...
            ['Background Parameter 1: ', num2str(Fitparam(5))],...
            ['Background Parameter 2:',num2str(Fitparam(6))],...
            ['----------------'],...
            ['Background at peak: ', num2str(back_near_peak(1))],...
            ['Meas. Area in Peak :',num2str(peak_area)]};
    end
    fittexthandle=text(0.1,0.5,outtext);
    set(handles.fit,'UserData',outtext)
    set(fittexthandle,'Tag','FitText')
    %now put something that outputs the image and the data to a file if we are
    %in batch mode
    if batch>0
        batchquikfitoutput(handles,fitfilespath,fitfiles{ii+1},outputpath,outputfile,tag)
    end

end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function fitsuccess = FitDoublePearsonPeakSlope(hmenu, eventdata,haxes,batch)
global fitpar

% first get some information from the data in the plot window
[S_orig,X,Y,E,Xdisp,Ydisp]=getdatafromaxes(haxes);
[pathstr,namestr]=fileparts(S_orig.raw_filename);

fittext='Fitting Double Pearson Peak with Background Slope';
% then if this is batch-mode, we need additional information
if batch==1,
    [S_template,fitfilespath,fitfiles,outputpath,outputfile,tag]=batchfitprepare(hmenu, eventdata, haxes);
    %S_template has the same raw information as S_orig...but has all of the data
    %added (masks, empty etc)
else
    fitfiles={namestr};
    fitfilespath=pathstr;
    outputfile='tmp';
    S_template=S_orig;
end
if isempty(fitfiles) || isempty(outputfile)
    errordlg('Batch fitting has been aborted since some of the parameters entered, could not be resolved (perhaps cancel button was pressed')
    return
end

% now get information for the fit
if (strcmp(S_orig.type,'r-ave'))
    helptext={'#1/4: Click on minimum q to fit' '#2/4: Click on maximum q to fit' '#3/4: Click on main peak center' '#4/4: Click on subsidiary peak center'};
else
    helptext={'#1/4: Click on minimum angle to fit' '#2/4: Click on maximum angle to fit' '#3/4: Click on main peak center' '#4/4: Click on subsidiary peak center'};

end
point_indices=enter_clickpoints(haxes,helptext,Xdisp);
% now begin to cycle the files to fit
for ii=0:length(fitfiles)-1
    namestr=fitfiles{ii+1};
    [S,X,Y]=get_create_SXY(S_orig,S_template,fitfilespath,fitfiles{ii+1},batch,X,Y);


    pleft=[X(point_indices(1)) Y(point_indices(1))];
    pright=[X(point_indices(2)) Y(point_indices(2))];
    if pleft(1)>pright(1);
        temp=pright;
        pright=pleft;
        pleft=temp;
    end
    mainpeak=[X(point_indices(3)) Y(point_indices(3))];
    sidepeak=[X(point_indices(4)) Y(point_indices(4))];

    mainpeakpos=mainpeak(1);
    sidepeakpos=sidepeak(1);
    backslope=(pleft(2)-pright(2))/(pleft(1)-pright(1));
    peakback=backslope*(mainpeakpos-pleft(1))+pleft(2);
    mainpeakamp=mainpeak(2)-peakback; %l=2/pi*width
    sidepeakamp=sidepeak(2)-peakback;

    FWHM=0.25*(pright(1)-pleft(1)); %a little rough, but functional;
    peakwidth=FWHM;
    %sidepeakwidth=FWHM;

    peaktail=2;%start with Lorentzian type tailing
    %sidepeaktail=2;

    %first only fit de tailing and widths, not the centers or background
    fitpar.name='DoublePearsonPeakSlope.m';
    fitpar.binning=1;
    fitpar.fit=[0 0 1 1 0 0  0 0];
    fitpar.numiter=500;
    fitpar.tol=0.001;
    fitpar.graphics=1;
    fitpar.start=[mainpeakpos mainpeakamp peakwidth peaktail sidepeakpos sidepeakamp peakback backslope];
    fitpar.ll=[0 0 0 0 0 0 0 -Inf];
    fitpar.ul=[Inf Inf Inf Inf Inf Inf Inf Inf];

    handles=create_quikfitplots(fittext,'linlog',ii,batch);

    bounds=[pleft(1) pright(1)];
    hstatus=figstatus('Fitting tails and widths...',handles.figure);

    [Fitparam,Fitval,Info] = fitsaxs1D(S,bounds,handles);
    delete(hstatus)


    %then only fit the centers and background
    fitpar.name='DoublePearsonPeakSlope.m';
    fitpar.binning=1;
    fitpar.fit=[1 1 0 0 1 1 1 1];
    fitpar.numiter=500;
    fitpar.tol=0.001;
    fitpar.graphics=1;
    fitpar.start=[mainpeakpos mainpeakamp Fitparam(3) Fitparam(4) sidepeakpos sidepeakamp peakback backslope];
    fitpar.ll=[0 0 0 0 0 0 0 0 0 -Inf];
    fitpar.ul=[Inf Inf Inf Inf Inf Inf Inf Inf];

    bounds=[pleft(1) pright(1)];
    hstatus=figstatus('Fitting centers and amplitudes...',handles.figure);

    [Fitparam,Fitval,Info] = fitsaxs1D(S,bounds,handles);
    delete(hstatus)
    %fit everything
    fitpar.name='DoublePearsonPeakSlope.m';
    fitpar.binning=1;
    fitpar.fit=[1 1 1 1 1 1 1 1];
    fitpar.numiter=1000;
    fitpar.tol=0.001;
    fitpar.graphics=1;
    fitpar.start=Fitparam;
    fitpar.ll=Fitparam-0.25.*Fitparam; %Allow 25% change
    fitpar.ul=Fitparam+0.25.*Fitparam; %Allow 25% change

    bounds=[pleft(1) pright(1)];
    hstatus=figstatus('Fitting everything...',handles.figure);

    [Fitparam,Fitval,Info] = fitsaxs1D(S,bounds,handles);
    delete(hstatus)

    if Fitparam(4)<0.75
        peaktype='pointy';
    elseif Fitparam(4)>=0.75 && Fitparam(4)<2
        peaktype='Lorentzian';
    else
        peaktype='Gaussian';
    end
    % now calculates masses of the peaks.
    X_TMP=(X>pleft(1))& (X<pright(1));
    X_ROI=X(X_TMP);
    Peak1=DoublePearsonPeakSlope(X_ROI,X_ROI,[Fitparam(1),Fitparam(2),Fitparam(3),Fitparam(4),Fitparam(5),...
        0,0,0]);
    peak1_area=sum(gradient(X_ROI).*Peak1);
    Peak2=DoublePearsonPeakSlope(X_ROI,X_ROI,[Fitparam(1),0,Fitparam(3),Fitparam(4),Fitparam(5),...
        Fitparam(6),0,0]);
    peak2_area=sum(gradient(X_ROI).*Peak2);

    axes(handles.text);
    if (strcmp(S.type,'r-ave'))
        outtext={['Function: ',fitpar.name],...
            ['Data    : ',namestr],...
            ['----------'],...
            ['Center1: ',num2str(Fitparam(1))],...
            ['D-spacing [A]: ',num2str(2*pi/Fitparam(1))],...
            ['Amplitude 1: ', num2str(Fitparam(2))],...
            ['FWHM 1: ', num2str(Fitparam(3))],...
            ['Tailing(M) 1: ', num2str(Fitparam(4))],...
            ['Approx. peak type 1: ',peaktype],...
            ['Calc. Peak 1 Area: ',num2str(peak1_area)],...
            ['----------'],...
            ['Center 2: ',num2str(Fitparam(5))],...
            ['D-spacing [A]: ',num2str(2*pi/Fitparam(5))],...
            ['Amplitude 2: ', num2str(Fitparam(6))],...
            ['FWHM 2: ', num2str(Fitparam(3))],...
            ['Tailing(M) 2: ', num2str(Fitparam(4))],...
            ['Approx. peak type 2: ',peaktype],...
            ['Calc. Peak 2 Area: ',num2str(peak2_area)],...
            ['----------------']...
            % Save the area under peak for later if needed.
            %['Area in Peak :',num2str(Fitparam(2)*Fitparam(3)+Fitparam(6)*Fitparam(7))]
            };
    else
        outtext={['Function: ',fitpar.name],...
            ['Data    : ',namestr],...
            ['----------'],...
            ['Center1: ',num2str(Fitparam(1))],...
            ['Amplitude 1: ', num2str(Fitparam(2))],...
            ['FWHM 1: ', num2str(Fitparam(3))],...
            ['Tailing(M) 1: ', num2str(Fitparam(4))],...
            ['Approx. peak type 1: ',peaktype],...
            ['Calc. Peak 1 Area: ',num2str(peak1_area)],...
            ['----------'],...
            ['Center 2: ',num2str(Fitparam(5))],...
            ['Amplitude 2: ', num2str(Fitparam(6))],...
            ['FWHM 2: ', num2str(Fitparam(3))],...
            ['Tailing(M) 2: ', num2str(Fitparam(4))],...
            ['Approx. peak type 2: ',peaktype],...
            ['Calc. Peak 2 Area: ',num2str(peak2_area)],...
            ['----------------']...
            };
    end
    fittexthandle=text(0.1,0.5,outtext);
    set(handles.fit,'UserData',outtext)
    set(fittexthandle,'Tag','FitText')
    %now put something that outputs the image and the data to a file if we are
    %in batch mode
    if batch>0
        batchquikfitoutput(handles,fitfilespath,fitfiles{ii+1},outputpath,outputfile,tag)
    end

end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function fitsuccess = FitDoublePearsonPeakSpline(hmenu, eventdata,haxes,batch)
global fitpar

% first get some information from the data in the plot window
[S_orig,X,Y,E,Xdisp,Ydisp]=getdatafromaxes(haxes);
[pathstr,namestr]=fileparts(S_orig.raw_filename);

fittext='Fitting Double Pearson Peak with Background Spline';
% then if this is batch-mode, we need additional information
if batch==1,
    [S_template,fitfilespath,fitfiles,outputpath,outputfile,tag]=batchfitprepare(hmenu, eventdata, haxes);
    %S_template has the same raw information as S_orig...but has all of the data
    %added (masks, empty etc)
else
    fitfiles={namestr};
    fitfilespath=pathstr;
    outputfile='tmp';
    S_template=S_orig;
end
if isempty(fitfiles) || isempty(outputfile)
    errordlg('Batch fitting has been aborted since some of the parameters entered, could not be resolved (perhaps cancel button was pressed')
    return
end

% now get information for the fit
if (strcmp(S_orig.type,'r-ave'))
    helptext={'#1/4: Click on minimum q to fit' '#2/4: Click on maximum q to fit' '#3/4: Click on main peak center' '#4/4: Click on subsidiary peak center'};
else
    helptext={'#1/4: Click on minimum angle to fit' '#2/4: Click on maximum angle to fit' '#3/4: Click on main peak center' '#4/4: Click on subsidiary peak center'};

end
point_indices=enter_clickpoints(haxes,helptext,Xdisp);
% now begin to cycle the files to fit
for ii=0:length(fitfiles)-1
    namestr=fitfiles{ii+1};
    [S,X,Y]=get_create_SXY(S_orig,S_template,fitfilespath,fitfiles{ii+1},batch,X,Y);
    pleft=[X(point_indices(1)) Y(point_indices(1))];
    pright=[X(point_indices(2)) Y(point_indices(2))];
    if pleft(1)>pright(1);
        temp=pright;
        pright=pleft;
        pleft=temp;
    end
    mainpeak=[X(point_indices(3)) Y(point_indices(3))];
    sidepeak=[X(point_indices(4)) Y(point_indices(4))];

    mainpeakpos=mainpeak(1);
    sidepeakpos=sidepeak(1);
    %backslope=(pleft(2)-pright(2))/(pleft(1)-pright(1));
    %peakback=backslope*(mainpeakpos-pleft(1))+pleft(2);
    backexp=log(pleft(2)/pright(2))/(pleft(1)^2-pright(1)^2);
    backinten=pright(2)/exp(backexp*pright(1)^2);
    mainpeakamp=mainpeak(2)-backinten*exp(backexp*((pright(1)+pleft(1))/2)^2);
    sidepeakamp=sidepeak(2)-backinten*exp(backexp*((pright(1)+pleft(1))/2)^2);

    FWHM=0.25*(pright(1)-pleft(1)); %a little rough, but functional;
    peakwidth=FWHM;
    %sidepeakwidth=FWHM;

    peaktail=2;%start with Lorentzian type tailing
    %sidepeaktail=2;

    %first only fit the centers and widths, not the centers or background
    fitpar.name='DoublePearsonPeakSpline.m';
    fitpar.binning=1;
    fitpar.fit=[1 0 1 0 1 0 0 0];
    fitpar.numiter=500;
    fitpar.tol=0.001;
    fitpar.graphics=1;
    fitpar.start=[mainpeakpos mainpeakamp peakwidth peaktail sidepeakpos sidepeakamp backinten backexp];
    fitpar.ll=[0 0 0 0 0 0 0 -Inf];
    fitpar.ul=[Inf Inf Inf Inf Inf Inf Inf Inf];

    handles=create_quikfitplots(fittext,'linlog',ii,batch);

    bounds=[pleft(1) pright(1)];
    hstatus=figstatus('Fitting tails and widths...',handles.figure);

    [Fitparam,Fitval,Info] = fitsaxs1D(S,bounds,handles);
    delete(hstatus)


    %then only fit the amplitudes, widths and tailings
    fitpar.name='DoublePearsonPeakSpline.m';
    fitpar.binning=1;
    fitpar.fit=[0 1 0 1 1 0 0 0];
    fitpar.numiter=500;
    fitpar.tol=0.001;
    fitpar.graphics=1;
    fitpar.start=[Fitparam(1) mainpeakamp Fitparam(3) peaktail Fitparam(5) sidepeakamp backinten backexp];
    fitpar.ll=[0 0 0 0 0 0 0 0 0 -Inf];
    fitpar.ul=[Inf Inf Inf Inf Inf Inf Inf Inf];

    bounds=[pleft(1) pright(1)];
    hstatus=figstatus('Fitting centers and amplitudes...',handles.figure);

    [Fitparam,Fitval,Info] = fitsaxs1D(S,bounds,handles);
    delete(hstatus)
    %fit everything
    fitpar.name='DoublePearsonPeakSpline.m';
    fitpar.binning=1;
    fitpar.fit=[1 1 1 1 1 1 1 1];
    fitpar.numiter=1000;
    fitpar.tol=0.001;
    fitpar.graphics=1;
    fitpar.start=Fitparam;
    fitpar.ll=Fitparam-0.25.*Fitparam; %Allow 25% change
    fitpar.ul=Fitparam+0.25.*Fitparam; %Allow 25% change

    bounds=[pleft(1) pright(1)];
    hstatus=figstatus('Fitting everything...',handles.figure);

    [Fitparam,Fitval,Info] = fitsaxs1D(S,bounds,handles);
    delete(hstatus)

    if Fitparam(4)<0.75
        peaktype='pointy';
    elseif Fitparam(4)>=0.75 && Fitparam(4)<2
        peaktype='Lorentzian';
    else
        peaktype='Gaussian';
    end
    % now calculates masses of the peaks.
    X_TMP=(X>pleft(1))& (X<pright(1));
    X_ROI=X(X_TMP);
    Peak1=DoublePearsonPeakSlope(X_ROI,X_ROI,[Fitparam(1),Fitparam(2),Fitparam(3),Fitparam(4),Fitparam(5),...
        0,0,0]);
    peak1_area=sum(gradient(X_ROI).*Peak1);
    Peak2=DoublePearsonPeakSlope(X_ROI,X_ROI,[Fitparam(1),0,Fitparam(3),Fitparam(4),Fitparam(5),...
        Fitparam(6),0,0]);
    peak2_area=sum(gradient(X_ROI).*Peak2);

    axes(handles.text);
    if (strcmp(S.type,'r-ave'))
        outtext={['Function: ',fitpar.name],...
            ['Data    : ',namestr],...
            ['----------'],...
            ['Center1: ',num2str(Fitparam(1))],...
            ['D-spacing [A]: ',num2str(2*pi/Fitparam(1))],...
            ['Amplitude 1: ', num2str(Fitparam(2))],...
            ['FWHM 1: ', num2str(Fitparam(3))],...
            ['Tailing(M) 1: ', num2str(Fitparam(4))],...
            ['Approx. peak type 1: ',peaktype],...
            ['Calc. Peak 1 Area: ',num2str(peak1_area)],...
            ['----------'],...
            ['Center 2: ',num2str(Fitparam(5))],...
            ['D-spacing [A]: ',num2str(2*pi/Fitparam(5))],...
            ['Amplitude 2: ', num2str(Fitparam(6))],...
            ['FWHM 2: ', num2str(Fitparam(3))],...
            ['Tailing(M) 2: ', num2str(Fitparam(4))],...
            ['Approx. peak type 2: ',peaktype],...
            ['Calc. Peak 2 Area: ',num2str(peak2_area)],...
            ['----------------']...
            % Save the area under peak for later if needed.
            %['Area in Peak :',num2str(Fitparam(2)*Fitparam(3)+Fitparam(6)*Fitparam(7))]
            };
    else
        outtext={['Function: ',fitpar.name],...
            ['Data    : ',namestr],...
            ['----------'],...
            ['Center1: ',num2str(Fitparam(1))],...
            ['Amplitude 1: ', num2str(Fitparam(2))],...
            ['FWHM 1: ', num2str(Fitparam(3))],...
            ['Tailing(M) 1: ', num2str(Fitparam(4))],...
            ['Approx. peak type 1: ',peaktype],...
            ['Calc. Peak 1 Area: ',num2str(peak1_area)],...
            ['----------'],...
            ['Center 2: ',num2str(Fitparam(5))],...
            ['Amplitude 2: ', num2str(Fitparam(6))],...
            ['FWHM 2: ', num2str(Fitparam(3))],...
            ['Tailing(M) 2: ', num2str(Fitparam(4))],...
            ['Approx. peak type 2: ',peaktype],...
            ['Calc. Peak 2 Area: ',num2str(peak2_area)],...
            ['----------------']...
            };
    end
    fittexthandle=text(0.1,0.5,outtext);
    set(handles.fit,'UserData',outtext)
    set(fittexthandle,'Tag','FitText')
    %now put something that outputs the image and the data to a file if we are
    %in batch mode
    if batch>0
        batchquikfitoutput(handles,fitfilespath,fitfiles{ii+1},outputpath,outputfile,tag)
    end

end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Start Debye Fits
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function fitsuccess = FitDebye(hmenu, eventdata,haxes,batch)
global fitpar

%needs better initial guesses. according to Debye, 1949

% first get some information from the data in the plot window
[S_orig,X,Y,E,Xdisp,Ydisp]=getdatafromaxes(haxes);
[pathstr,namestr]=fileparts(S_orig.raw_filename);
fittext='Fitting Debye function to the entire range';
% then if this is batch-mode, we need additional information
if batch==1,
    [S_template,fitfilespath,fitfiles,outputpath,outputfile,tag]=batchfitprepare(hmenu, eventdata, haxes);
    %S_template has the same raw information as S_orig...but has all of the data
    %added (masks, empty etc)
else
    fitfiles={namestr};
    fitfilespath=pathstr;
    outputfile='tmp';
    S_template=S_orig;
end
if isempty(fitfiles) || isempty(outputfile)
    errordlg('Batch fitting has been aborted since some of the parameters entered, could not be resolved (perhaps cancel button was pressed')
    return
end

% now get information for the fit
if (strcmp(S_orig.type,'r-ave'))
    helptext={'#1/2: Click on minimum q to fit' '#2/2: Click on maximum q to fit'};
else
    helptext={'#1/2: Click on minimum angle to fit' '#2/2: Click on maximum q to fit'};
end
point_indices=enter_clickpoints(haxes,helptext,Xdisp);
% now begin to cycle the files to fit
for ii=0:length(fitfiles)-1
    namestr=fitfiles{ii+1};
    [S,X,Y]=get_create_SXY(S_orig,S_template,fitfilespath,fitfiles{ii+1},batch,X,Y);
    pleft=[X(point_indices(1)) Y(point_indices(1))];
    pright=[X(point_indices(2)) Y(point_indices(2))];
    if pleft(1)>pright(1);
        temp=pright;
        pright=pleft;
        pleft=temp;
    end
    fluct=0;
    amp=pleft(2);
    lc=10; %how to approximate/guess this?

    fitpar.name='Debye.m';
    fitpar.binning=1;
    fitpar.fit=[1 1 1];
    fitpar.numiter=1000;
    fitpar.tol=0.001;
    fitpar.graphics=1;
    fitpar.start=[amp lc fluct];
    fitpar.ll=[0 0 0];
    fitpar.ul=[Inf Inf Inf];

    handles=create_quikfitplots(fittext,'linlog',ii,batch);

    bounds=[pleft(1) pright(1)];
    hstatus=figstatus('Fitting...',handles.figure);

    [Fitparam,Fitval,Info] = fitsaxs1D(S,bounds,handles);
    delete(hstatus)

    axes(handles.text);
    outtext={['Function: ',fitpar.name],...
        ['Data    : ',namestr],...
        ['Amplitude: ',num2str(Fitparam(1))],...
        ['Correlation length: ', num2str(Fitparam(2))],...
        ['baseline addition: ', num2str(Fitparam(3))]};

    fittexthandle=text(0.1,0.5,outtext);
    set(handles.fit,'UserData',outtext)
    set(fittexthandle,'Tag','FitText')
    %now put something that outputs the image and the data to a file if we are
    %in batch mode
    if batch>0
        batchquikfitoutput(handles,fitfilespath,fitfiles{ii+1},outputpath,outputfile,tag)
    end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Start Porod Fits
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function fitsuccess = FitPorod(hmenu, eventdata,haxes,batch)
global fitpar

%This function fits a pure porod relationship to the function.
% first get some information from the data in the plot window
[S_orig,X,Y,E,Xdisp,Ydisp]=getdatafromaxes(haxes);
[pathstr,namestr]=fileparts(S_orig.raw_filename);

fittext='Fitting a pure Porod function';
% then if this is batch-mode, we need additional information
if batch==1,
    [S_template,fitfilespath,fitfiles,outputpath,outputfile,tag]=batchfitprepare(hmenu, eventdata, haxes);
    %S_template has the same raw information as S_orig...but has all of the data
    %added (masks, empty etc)
else
    fitfiles={namestr};
    fitfilespath=pathstr;
    outputfile='tmp';
    S_template=S_orig;
end
if isempty(fitfiles) || isempty(outputfile)
    errordlg('Batch fitting has been aborted since some of the parameters entered, could not be resolved (perhaps cancel button was pressed')
    return
end

% now get information for the fit
if (strcmp(S_orig.type,'r-ave'))
    helptext={'#1/2: Click on the approximate beginning of the Porod region' '#2/2: Click on the approximate end of the Porod region'};
else
    errordlg('Porod Fit is not valid for this type of data.')
    return
end
point_indices=enter_clickpoints(haxes,helptext,Xdisp);
% now begin to cycle the files to fit
for ii=0:length(fitfiles)-1
    namestr=fitfiles{ii+1};
    [S,X,Y]=get_create_SXY(S_orig,S_template,fitfilespath,fitfiles{ii+1},batch,X,Y);
    pleft=[X(point_indices(1)) Y(point_indices(1))];
    pright=[X(point_indices(2)) Y(point_indices(2))];
    if pleft(1)>pright(1);
        temp=pright;
        pright=pleft;
        pleft=temp;
    end
    center=(pleft+pright)/2;

    %make an initial guess for the Porod constant Kp
    Kp=center(2)*center(1)^4; %I(s-->inf)=Kp/s^4
    leftbound=pleft(1);
    rightbound=pright(1);

    fitpar.name='QuickPorodFluct.m';
    fitpar.binning=1;
    fitpar.fit=[1];
    fitpar.numiter=500;
    fitpar.tol=0.001;
    fitpar.graphics=1;
    fitpar.start=[Kp];
    fitpar.ll=[0]; %lower limit of rightbound is halfway to the center, lower limit of leftbound is first datapoint
    fitpar.ul=[Inf ]; %upper limit of leftbound is halfway to the center, upper limit of rightbound is last datapoint

    handles=create_quikfitplots(fittext,'loglog',ii,batch);

    hstatus=figstatus('Fitting...',handles.figure);

    [Fitparam,Fitval,Info] = fitsaxs1D(S,[leftbound rightbound],handles);
    delete(hstatus)


    axes(handles.text);
    outtext={['Function: ',fitpar.name],...
        ['Data    : ',namestr],...
        ['----------'],...
        ['Kp: ',num2str(Fitparam(1))],...
        };
    fittexthandle=text(0.1,0.5,outtext);
    set(handles.fit,'UserData',outtext)
    set(fittexthandle,'Tag','FitText')
    %now put something that outputs the image and the data to a file if we are
    %in batch mode
    if batch>0
        batchquikfitoutput(handles,fitfilespath,fitfiles{ii+1},outputpath,outputfile,tag)
    end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function fitsuccess = FitPorodFluct(hmenu, eventdata,haxes,batch)
global fitpar

%This function fits a porod relationship with fluctuation parameter to the function.

ftype=uigetpref('Fit','FluctType','Fluctuation Type',...
    {'Please choose the type of fluctuation (asymptotical behaviour) to take into account (default to 3D)'...
    'Explanation: ' '          1D adds 2nd order term' '          2D adds 1st order term' '         3D adds const. term'},...
    {'1D' '2D' '3D'},'DefaultButton', '3D');

% first get some information from the data in the plot window
[S_orig,X,Y,E,Xdisp,Ydisp]=getdatafromaxes(haxes);
[pathstr,namestr]=fileparts(S_orig.raw_filename);

fittext='Fitting a Porod function with fluctuation term';
% then if this is batch-mode, we need additional information
if batch==1,
    [S_template,fitfilespath,fitfiles,outputpath,outputfile,tag]=batchfitprepare(hmenu, eventdata, haxes);
    %S_template has the same raw information as S_orig...but has all of the data
    %added (masks, empty etc)
else
    fitfiles={namestr};
    fitfilespath=pathstr;
    outputfile='tmp';
    S_template=S_orig;
end
if isempty(fitfiles) || isempty(outputfile)
    errordlg('Batch fitting has been aborted since some of the parameters entered, could not be resolved (perhaps cancel button was pressed')
    return
end

% now get information for the fit
if (strcmp(S_orig.type,'r-ave'))
    helptext={'#1/2: Click on the approximate beginning of the Porod region' '#2/2: Click on the approximate end of the Porod region'};
else
    errordlg('Porod Fit is not valid for this type of data.')
    return
end
point_indices=enter_clickpoints(haxes,helptext,Xdisp);

% now begin to cycle the files to fit
for ii=0:length(fitfiles)-1
    namestr=fitfiles{ii+1};
    [S,X,Y]=get_create_SXY(S_orig,S_template,fitfilespath,fitfiles{ii+1},batch,X,Y);
    pleft=[X(point_indices(1)) Y(point_indices(1))];
    pright=[X(point_indices(2)) Y(point_indices(2))];
    if pleft(1)>pright(1);
        temp=pright;
        pright=pleft;
        pleft=temp;
    end
    center=(pleft+pright)/2;

    %make an initial guess for the Porod constant Kp
    Kp=center(2)*center(1)^4; %I(s-->inf)=Kp/s^4
    famp=0; % start with no fluctuation
    switch ftype %the only way to pass a string argument through fminsearchbnd is to convert it to numeric values.
        case '1d'
            ftype=1;
        case '2d'
            ftype=2;
        case '3d'
            ftype=3;
    end

    leftbound=pleft(1);
    rightbound=pright(1);

    fitpar.name='QuickPorodFluct.m';
    fitpar.binning=1;
    fitpar.fit=[1 1 0];
    fitpar.numiter=500;
    fitpar.tol=0.001;
    fitpar.graphics=1;
    fitpar.start=[Kp famp ftype];
    fitpar.ll=[0 0 -Inf]; %lower limit of rightbound is halfway to the center, lower limit of leftbound is first datapoint
    fitpar.ul=[Inf Inf Inf]; %upper limit of leftbound is halfway to the center, upper limit of rightbound is last datapoint

    handles=create_quikfitplots(fittext,'loglog',ii,batch);

    hstatus=figstatus('Fitting...',handles.figure);

    [Fitparam,Fitval,Info] = fitsaxs1D(S,[leftbound rightbound],handles);
    delete(hstatus)


    axes(handles.text);
    outtext={['Function: ',fitpar.name],...
        ['Data    : ',namestr],...
        ['----------'],...
        ['Kp: ',num2str(Fitparam(1))],...
        ['Fluctuation amplitude: ', num2str(Fitparam(2))],...
        ['Fluctuation Dimension: ', num2str(Fitparam(3))]
        };

    fittexthandle=text(0.1,0.5,outtext);
    set(handles.fit,'UserData',outtext)
    set(fittexthandle,'Tag','FitText')
    %now put something that outputs the image and the data to a file if we are
    %in batch mode
    if batch>0
        batchquikfitoutput(handles,fitfilespath,fitfiles{ii+1},outputpath,outputfile,tag)
    end

end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function fitsuccess = FitFract(hmenu, eventdata,haxes,batch)
global fitpar

%This function fits a fractal within the fractal regime
%Created by Brian Pauw - August 2007
%Altered by KJ 070912

% ftype=uigetpref('Warnings','Fract','Usage Warning',...
%     'This function will return rubbish if a fluctuation term is present! (Ruland, Adv. Mat., 2,528, 1990)',...
%     {'Ok'});

% first get some information from the data in the plot window
[S_orig,X,Y,E,Xdisp,Ydisp]=getdatafromaxes(haxes);
[pathstr,namestr]=fileparts(S_orig.raw_filename);

fittext='Fitting a Fractal function with no background';
% then if this is batch-mode, we need additional information
if batch==1,
    [S_template,fitfilespath,fitfiles,outputpath,outputfile,tag]=batchfitprepare(hmenu, eventdata, haxes);
    %S_template has the same raw information as S_orig...but has all of the data
    %added (masks, empty etc)
else
    fitfiles={namestr};
    fitfilespath=pathstr;
    outputfile='tmp';
    S_template=S_orig;
end
if isempty(fitfiles) || isempty(outputfile)
    errordlg('Batch fitting has been aborted since some of the parameters entered, could not be resolved (perhaps cancel button was pressed')
    return
end

% now get information for the fit
if (strcmp(S_orig.type,'r-ave'))
    helptext={'#1/2: Click on the approximate beginning of the Fractal region' '#2/2: Click on the approximate end of the Fractal region'};
else
    errordlg('Fractal Fit is not valid for this type of data.')
    return
end
point_indices=enter_clickpoints(haxes,helptext,Xdisp);
% now begin to cycle the files to fit
for ii=0:length(fitfiles)-1
    namestr=fitfiles{ii+1};
    [S,X,Y]=get_create_SXY(S_orig,S_template,fitfilespath,fitfiles{ii+1},batch,X,Y);

    pleft=[X(point_indices(1)) Y(point_indices(1))];
    pright=[X(point_indices(2)) Y(point_indices(2))];
    if pleft(1)>pright(1);
        temp=pright;
        pright=pleft;
        pleft=temp;
    end
    center=(pleft+pright)/2;

    %make an initial guess for the Slope, Fractal Dimension and amplification
    FractSlope=(log10(pright(2))-log10((pleft(2))))/(log10(pright(1))-log10((pleft(1))));
    HausdorffD=6+FractSlope;
    Fractamp=pright(1)*10^(-log10(pright(2))*FractSlope);

    leftbound=pleft(1);
    rightbound=pright(1);

    fitpar.name='QuickFract.m';
    fitpar.binning=1;
    fitpar.fit=[1 1];
    fitpar.numiter=500;
    fitpar.tol=0.001;
    fitpar.graphics=1;
    fitpar.start=[Fractamp HausdorffD];
    fitpar.ll=[0 0]; %lower limit of rightbound is halfway to the center, lower limit of leftbound is first datapoint
    fitpar.ul=[Inf 6]; %upper limit of leftbound is halfway to the center, upper limit of rightbound is last datapoint

    handles=create_quikfitplots(fittext,'loglog',ii,batch);

    hstatus=figstatus('Fitting...',handles.figure);

    [Fitparam,Fitval,Info] = fitsaxs1D(S,[leftbound rightbound],handles);
    delete(hstatus)


    axes(handles.text);
    outtext={['Function: ',fitpar.name],...
        ['Data    : ',namestr],...
        ['----------'],...
        ['Fractal amplitude: ', num2str(Fitparam(1))],...
        ['Fractal (Hausdorff) Dimension: ', num2str(Fitparam(2))],...
        ['----------'],...
        ['Slope : ',num2str(Fitparam(2)-6)],...
        };

    fittexthandle=text(0.1,0.5,outtext);
    set(handles.fit,'UserData',outtext)
    set(fittexthandle,'Tag','FitText')
    %now put something that outputs the image and the data to a file if we are
    %in batch mode
    if batch>0
        batchquikfitoutput(handles,fitfilespath,fitfiles{ii+1},outputpath,outputfile,tag);
    end

end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function fitsuccess = FitFractBackg(hmenu, eventdata,haxes,batch)
global fitpar

%This function fits an fractal within the fractal regime with a constant
%background
%Created by KJ 070912 


% first get some information from the data in the plot window
[S_orig,X,Y,E,Xdisp,Ydisp]=getdatafromaxes(haxes);
[pathstr,namestr]=fileparts(S_orig.raw_filename);
fittext='Fitting a Fractal function with background';
% then if this is batch-mode, we need additional information
if batch==1,
    [S_template,fitfilespath,fitfiles,outputpath,outputfile,tag]=batchfitprepare(hmenu, eventdata, haxes);
    %S_template has the same raw information as S_orig...but has all of the data
    %added (masks, empty etc)
else
    fitfiles={namestr};
    fitfilespath=pathstr;
    outputfile='tmp';
    S_template=S_orig;
end
if isempty(fitfiles) || isempty(outputfile)
    errordlg('Batch fitting has been aborted since some of the parameters entered, could not be resolved (perhaps cancel button was pressed')
    return
end

% now get information for the fit
if (strcmp(S_orig.type,'r-ave'))
    helptext={'#1/2: Click on the beginning of the fitting region' '#2/2: Click on the end of the fitting region'};
else
    errordlg('Fractal Fit is not valid for this type of data.')
    return
end
point_indices=enter_clickpoints(haxes,helptext,Xdisp);
% now begin to cycle the files to fit
for ii=0:length(fitfiles)-1
    namestr=fitfiles{ii+1};
    [S,X,Y]=get_create_SXY(S_orig,S_template,fitfilespath,fitfiles{ii+1},batch,X,Y);
    pleft=[X(point_indices(1)) Y(point_indices(1))];
    pright=[X(point_indices(2)) Y(point_indices(2))];
    if pleft(1)>pright(1);
        temp=pright;
        pright=pleft;
        pleft=temp;
    end

    %make an initial guess for the Slope, Fractal Dimension and amplification
    FractSlope=(log10(pright(2))-log10((pleft(2))))/(log10(pright(1))-log10((pleft(1))));
    HausdorffD=6+FractSlope;
    Fractamp=pright(1)*10^(-log10(pright(2))*FractSlope);
    FractBackg=0;

    leftbound=pleft(1);
    rightbound=pright(1);

    fitpar.name='QuickFract.m';
    fitpar.binning=1;
    fitpar.fit=[1 1 1];
    fitpar.numiter=500;
    fitpar.tol=0.001;
    fitpar.graphics=1;
    fitpar.start=[Fractamp HausdorffD FractBackg];
    fitpar.ll=[0 0 0]; %lower limit of rightbound is halfway to the center, lower limit of leftbound is first datapoint
    fitpar.ul=[Inf 6 Inf]; %upper limit of leftbound is halfway to the center, upper limit of rightbound is last datapoint

    handles=create_quikfitplots(fittext,'loglog',ii,batch);

    hstatus=figstatus('Fitting...',handles.figure);

    [Fitparam,Fitval,Info] = fitsaxs1D(S,[leftbound rightbound],handles);
    delete(hstatus)


    axes(handles.text);
    outtext={['Function: ',fitpar.name],...
        ['Data    : ',namestr],...
        ['----------'],...
        ['Fractal Amplitude: ', num2str(Fitparam(1))],...
        ['Fractal (Hausdorff) Dimension: ', num2str(Fitparam(2))],...
        ['Constant Background: ', num2str(Fitparam(3))],...
        ['----------'],...
        ['Slope : ',num2str(Fitparam(2)-6)],...
        };

    fittexthandle=text(0.1,0.5,outtext);
    set(handles.fit,'UserData',outtext)
    set(fittexthandle,'Tag','FitText')
    %now put something that outputs the image and the data to a file if we are
    %in batch mode
    if batch>0
        batchquikfitoutput(handles,fitfilespath,fitfiles{ii+1},outputpath,outputfile,tag)
    end

end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Start Gunier Fits
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function fitsuccess = FitGuinier(hmenu, eventdata,haxes,batch)
global fitpar

%needs better initial guesses. according to Debye, 1949

% first get some information from the data in the plot window
[S_orig,X,Y,E,Xdisp,Ydisp]=getdatafromaxes(haxes);
[pathstr,namestr]=fileparts(S_orig.raw_filename);
fittext='Fitting Gunier function to the chosen range';
% then if this is batch-mode, we need additional information
if batch==1,
    [S_template,fitfilespath,fitfiles,outputpath,outputfile,tag]=batchfitprepare(hmenu, eventdata, haxes);
    %S_template has the same raw information as S_orig...but has all of the data
    %added (masks, empty etc)
else
    fitfiles={namestr};
    fitfilespath=pathstr;
    outputfile='tmp';
    S_template=S_orig;
end
if isempty(fitfiles) || isempty(outputfile)
    errordlg('Batch fitting has been aborted since some of the parameters entered, could not be resolved (perhaps cancel button was pressed')
    return
end

% now get information for the fit
if (strcmp(S_orig.type,'r-ave'))
    helptext={'#1/2: Click on minimum q to fit' '#2/2: Click on maximum q to fit'};
else
    errordlg('Guinier Fit is not valid for this type of data.')
    return
end
point_indices=enter_clickpoints(haxes,helptext,Xdisp);
% now begin to cycle the files to fit
for ii=0:length(fitfiles)-1
    namestr=fitfiles{ii+1};
    [S,X,Y]=get_create_SXY(S_orig,S_template,fitfilespath,fitfiles{ii+1},batch,X,Y);

    pleft=[X(point_indices(1)) Y(point_indices(1))];
    pright=[X(point_indices(2)) Y(point_indices(2))];
    if pleft(1)>pright(1);
        temp=pright;
        pright=pleft;
        pleft=temp;
    end

    GuinierSlope=(log(pleft(2))-log(pright(2)))/(pleft(1)^2-pright(1)^2);
    Io=-GuinierSlope*pleft(1)^2+log(pleft(2));
    Rg=sqrt(-3*GuinierSlope);

    fitpar.name='QuikGuinier.m';
    fitpar.binning=1;
    fitpar.fit=[1 1];
    fitpar.numiter=1000;
    fitpar.tol=0.001;
    fitpar.graphics=1;
    fitpar.start=[Io Rg];
    fitpar.ll=[0 0];
    fitpar.ul=[Inf Inf];

    handles=create_quikfitplots(fittext,'linlog',ii,batch);

    bounds=[pleft(1) pright(1)];
    hstatus=figstatus('Fitting...',handles.figure);

    [Fitparam,Fitval,Info] = fitsaxs1D(S,bounds,handles);
    delete(hstatus)

    axes(handles.text);
    outtext={['Function: ',fitpar.name],...
        ['Data    : ',namestr],...
        ['----------'],...
        ['I(0): ', num2str(Fitparam(1))],...
        ['Rg: ', num2str(Fitparam(2))],...
        ['----------'],...
        ['r for sphere',num2str(Fitparam(2)*sqrt(5/3))]};

    fittexthandle=text(0.1,0.5,outtext);
    set(handles.fit,'UserData',outtext)
    set(fittexthandle,'Tag','FitText')
    %now put something that outputs the image and the data to a file if we are
    %in batch mode
    if batch>0
        batchquikfitoutput(handles,fitfilespath,fitfiles{ii+1},outputpath,outputfile,tag)
    end

end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Start USF Fits
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function fitsuccess = FitGuinierPorod(hmenu, eventdata,haxes,batch)
global fitpar

%needs better initial guesses. according to Debye, 1949

% first get some information from the data in the plot window
[S_orig,X,Y,E,Xdisp,Ydisp]=getdatafromaxes(haxes);
[pathstr,namestr]=fileparts(S_orig.raw_filename);
fittext='Fitting Gunier-Porod function to the chosen range';
% then if this is batch-mode, we need additional information
if batch==1,
    [S_template,fitfilespath,fitfiles,outputpath,outputfile,tag]=batchfitprepare(hmenu, eventdata, haxes);
    %S_template has the same raw information as S_orig...but has all of the data
    %added (masks, empty etc)
else
    fitfiles={namestr};
    fitfilespath=pathstr;
    outputfile='tmp';
    S_template=S_orig;
end
if isempty(fitfiles) || isempty(outputfile)
    errordlg('Batch fitting has been aborted since some of the parameters entered, could not be resolved (perhaps cancel button was pressed')
    return
end

% now get information for the fit
if (strcmp(S_orig.type,'r-ave'))
    helptext={'#1/4: Click on low-q end of Guinier Region' '#2/4: Click on high-q end of Guinier Region' ...
        '#3/4: Click on low-q end of Porod Region' '#4/4: Click on high-q end of Porod Region'};
else
    errordlg('Guinier and Porod Fits are not valid for this type of data.')
    return
end
point_indices=enter_clickpoints(haxes,helptext,Xdisp);
% now begin to cycle the files to fit
for ii=0:length(fitfiles)-1
    namestr=fitfiles{ii+1};
    [S,X,Y]=get_create_SXY(S_orig,S_template,fitfilespath,fitfiles{ii+1},batch,X,Y);
    pgleft=[X(point_indices(1)) Y(point_indices(1))];
    pgright=[X(point_indices(2)) Y(point_indices(2))];
    ppleft=[X(point_indices(3)) Y(point_indices(3))];
    ppright=[X(point_indices(4)) Y(point_indices(4))];
    if pgleft(1)>pgright(1);
        temp=pgright;
        pgright=pgleft;
        pgleft=temp;
    end
    if ppleft(1)>ppright(1);
        temp=ppright;
        ppright=ppleft;
        ppleft=temp;
    end

    %parameters for the Guinier regime
    GuinierSlope=(log(pgleft(2))-log(pgright(2)))/(pgleft(1)^2-pgright(1)^2);
    Io=exp(-GuinierSlope*pgleft(1)^2+log(pgleft(2)));
    Rg=sqrt(-3*GuinierSlope);

    %make an initial guess for the Slope and amplitude
    FractSlope=(log10(ppright(2))-log10((ppleft(2))))/(log10(ppright(1))-log10((ppleft(1))));
    Fractamp=ppleft(2)-Io*exp(-ppleft(1)^2*Rg^2/3);
    FractBackg=0;

    %first get the Fractamp more or less correct

    fitpar.name='QuikBeaucage.m';
    fitpar.binning=1;
    fitpar.fit=[0 0 1 0];
    fitpar.numiter=1000;
    fitpar.tol=0.001;
    fitpar.graphics=1;
    fitpar.start=[Io Rg Fractamp FractSlope];
    fitpar.ll=[0 0 0 0];
    fitpar.ul=[Inf Inf Inf 6];

    handles=create_quikfitplots(fittext,'loglog',ii,batch);

    bounds=[pgleft(1) ppright(1)];
    hstatus=figstatus('Fitting...',handles.figure);

    [Fitparam,Fitval,Info] = fitsaxs1D(S,bounds,handles);
    delete(hstatus)
    %first get the Fractamp more or less correct

    fitpar.name='QuikBeaucage.m';
    fitpar.binning=1;
    fitpar.fit=[1 1 1 1];
    fitpar.numiter=10000;
    fitpar.tol=0.001;
    fitpar.graphics=1;
    fitpar.start=[Io Rg Fitparam(3) FractSlope];
    fitpar.ll=[0 0 0 0];
    fitpar.ul=[Inf Inf Inf 6];

    bounds=[pgleft(1) ppright(1)];
    hstatus=figstatus('Fitting...',handles.figure);

    [Fitparam,Fitval,Info] = fitsaxs1D(S,bounds,handles);
    delete(hstatus)

    axes(handles.text);
    outtext={['Function: ',fitpar.name],...
        ['Data    : ',namestr],...
        ['----------'],...
        ['I(0): ', num2str(Fitparam(1))],...
        ['Rg: ', num2str(Fitparam(2))],...
        ['Porod Amplitude: ', num2str(Fitparam(3))],...
        ['Slope: ', num2str(Fitparam(4))],...
        ['----------'],...
        ['r for sphere: ',num2str(Fitparam(2)*sqrt(5/3))]};

    fittexthandle=text(0.1,0.5,outtext);
    set(handles.fit,'UserData',outtext)
    set(fittexthandle,'Tag','FitText')
    %now put something that outputs the image and the data to a file if we are
    %in batch mode
    if batch>0
        batchquikfitoutput(handles,fitfilespath,fitfiles{ii+1},outputpath,outputfile,tag)
    end

end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function fitsuccess = FitGuinierPorodConst(hmenu, eventdata,haxes,batch)
global fitpar

%needs better initial guesses. according to Debye, 1949

% first get some information from the data in the plot window
[S_orig,X,Y,E,Xdisp,Ydisp]=getdatafromaxes(haxes);
[pathstr,namestr]=fileparts(S_orig.raw_filename);
fittext='Fitting Gunier-Porod function to the chosen range';
% then if this is batch-mode, we need additional information
if batch==1,
    [S_template,fitfilespath,fitfiles,outputpath,outputfile,tag]=batchfitprepare(hmenu, eventdata, haxes);
    %S_template has the same raw information as S_orig...but has all of the data
    %added (masks, empty etc)
else
    fitfiles={namestr};
    fitfilespath=pathstr;
    outputfile='tmp';
    S_template=S_orig;
end
if isempty(fitfiles) || isempty(outputfile)
    errordlg('Batch fitting has been aborted since some of the parameters entered, could not be resolved (perhaps cancel button was pressed')
    return
end

% now get information for the fit
if (strcmp(S_orig.type,'r-ave'))
    helptext={'#1/4: Click on low-q end of Guinier Region' '#2/4: Click on high-q end of Guinier Region' ...
        '#3/4: Click on low-q end of Porod Region' '#4/4: Click on high-q end of Porod Region'};
else
    errordlg('Guinier and Porod Fits are not valid for this type of data.')
    return
end
point_indices=enter_clickpoints(haxes,helptext,Xdisp);
% now begin to cycle the files to fit
for ii=0:length(fitfiles)-1
    namestr=fitfiles{ii+1};
    [S,X,Y]=get_create_SXY(S_orig,S_template,fitfilespath,fitfiles{ii+1},batch,X,Y);
    pgleft=[X(point_indices(1)) Y(point_indices(1))];
    pgright=[X(point_indices(2)) Y(point_indices(2))];
    ppleft=[X(point_indices(3)) Y(point_indices(3))];
    ppright=[X(point_indices(4)) Y(point_indices(4))];
    if pgleft(1)>pgright(1);
        temp=pgright;
        pgright=pgleft;
        pgleft=temp;
    end
    if ppleft(1)>ppright(1);
        temp=ppright;
        ppright=ppleft;
        ppleft=temp;
    end

    %parameters for the Guinier regime
    GuinierSlope=(log(pgleft(2))-log(pgright(2)))/(pgleft(1)^2-pgright(1)^2);
    Io=exp(-GuinierSlope*pgleft(1)^2+log(pgleft(2)));
    Rg=sqrt(-3*GuinierSlope);

    %make an initial guess for the Slope and amplitude
    FractSlope=(log10(ppright(2))-log10((ppleft(2))))/(log10(ppright(1))-log10((ppleft(1))));
    Fractamp=ppleft(2)-Io*exp(-ppleft(1)^2*Rg^2/3);
    FractBackg=0;

    %first get the Fractamp more or less correct

    fitpar.name='QuikBeaucage.m';
    fitpar.binning=1;
    fitpar.fit=[0 0 1 0 1];
    fitpar.numiter=1000;
    fitpar.tol=0.001;
    fitpar.graphics=1;
    fitpar.start=[Io Rg Fractamp FractSlope FractBackg];
    fitpar.ll=[0 0 0 0 0];
    fitpar.ul=[Inf Inf Inf 6 Inf];

    handles=create_quikfitplots(fittext,'loglog',ii,batch);

    bounds=[pgleft(1) ppright(1)];
    hstatus=figstatus('Fitting...',handles.figure);

    [Fitparam,Fitval,Info] = fitsaxs1D(S,bounds,handles);
    delete(hstatus)
    %first get the Fractamp more or less correct

    fitpar.name='QuikBeaucage.m';
    fitpar.binning=1;
    fitpar.fit=[1 1 1 1 1];
    fitpar.numiter=10000;
    fitpar.tol=0.001;
    fitpar.graphics=1;
    fitpar.start=[Io Rg Fitparam(3) FractSlope Fitparam(5)];
    fitpar.ll=[0 0 0 0 0];
    fitpar.ul=[Inf Inf Inf 6 Inf];

    bounds=[pgleft(1) ppright(1)];
    hstatus=figstatus('Fitting...',handles.figure);

    [Fitparam,Fitval,Info] = fitsaxs1D(S,bounds,handles);
    delete(hstatus)

    axes(handles.text);
    outtext={['Function: ',fitpar.name],...
        ['Data    : ',namestr],...
        ['----------'],...
        ['I(0): ', num2str(Fitparam(1))],...
        ['Rg: ', num2str(Fitparam(2))],...
        ['Porod Amplitude: ', num2str(Fitparam(3))],...
        ['Slope: ', num2str(Fitparam(4))],...
        ['Background: ', num2str(Fitparam(5))],...
        ['----------'],...
        ['r for sphere: ',num2str(Fitparam(2)*sqrt(5/3))]};

    fittexthandle=text(0.1,0.5,outtext);
    set(handles.fit,'UserData',outtext)
    set(fittexthandle,'Tag','FitText')
    %now put something that outputs the image and the data to a file if we are
    %in batch mode
    if batch>0
        batchquikfitoutput(handles,fitfilespath,fitfiles{ii+1},outputpath,outputfile,tag)
    end

end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%end of fitting functions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Beginning of file for batch fitting
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [S_template,fitfilespath,fitfiles,outputpath,outputfile,tag]=batchfitprepare(hmenu, eventdata, haxes)
% Menu callback.  Start doing equivalent reduction on other files..
% The results are saved.
str2(1) = {'You are about to fit a number of reduced datasets'};
str2(2) = {'The data sets will all be reduced in the same way as the present data,'};
str2(3) = {'The reduced data will then be fitted, and the results will be put into one large file,'};
str2(4) = {' '};
str2(5) = {'The produced fit-images may be also saved in jpg-files,'};
str2(6) = {'whose names will be very similar to the original file names.'};
str2(7) = {' '};
if ispc && version('-release')>10 
    str2(8) = {'First you must choose the files that will be reduced'};
else
    str2(8) = {'First you must choose a directory containing exclusively the files you want to be reduced and fitted.'};
end
str2(9) = {'Secondly you must choose whether you want to save the images...'};
str2(10)= {'and if so you must decide which tag that you want the new image files to be given.'};
str2(11) = {'Then you must choose the directory that you want to put the results in'} ;
str2(12) = {'Finally you must choose the the file that you want the fit-data written to'} ;
str2(13) = {' '};
str2(14) = {'Proceed by clicking "OK"'};

button=questdlg(str2,'Instructions for batch fitting','OK','Cancel');
if ~strcmp(button,'OK')
    return
end

[S_template,X,Y,~,Xdisp,Ydisp]=getdatafromaxes(haxes);
 
%since the pixel data has been striped we need to put it back:
hstatus = figstatus('Preparing Data',get(haxes,'Parent'));  % tell user what to do in a status bar
if str2num(S_template.reduction_state(12))==1 % if the beamstop mask is to be used
    a=add_beastopmask(S_template);
    warning off MATLAB:divideByZero
    S_template.bsmask_pixels=double(a.bsmask_pixels)./double(a.bsmask_pixels); % this transforms it into 1's and NaN's
    warning on MATLAB:divideByZero
end
if str2num(S_template.reduction_state(8))==1 % if the mask is to be used
    a=load(S_template.mask_filename); %mask file contains 1's and 0's
    warning off MATLAB:divideByZero
    S_template.mask_pixels=double(a.mask)./double(a.mask); % this transforms it into 1's and NaN's
    warning on MATLAB:divideByZero
end
if str2num(S_template.reduction_state(7))==1 || str2num(S_template.reduction_state(6))==1 %if either flatfield correction average is to be used.
    stemp=getsaxs(S_template.flatfield_filename);
    S_template.flatfield_pixels=stemp.pixels;
end
if str2num(S_template.reduction_state(11))==1 % if solvet+holder subtraction is to be used.
    stemp=getsaxs(S_template.solvent_filename);
    S_template.solvent_pixels=stemp.pixels;
end
if str2num(S_template.reduction_state(4))==1 % if empty holder subtraction is to be used.
    stemp=getsaxs(S_template.empty_filename);
    S_template.empty_pixels=stemp.pixels;
end
if str2num(S_template.reduction_state(3))==1 % if darkcurrent correction average is to be used.
    stemp=getsaxs(S_template.darkcurrent_filename);
    S_template.darkcurrent_pixels=stemp.pixels;
end
delete(hstatus)

% here we choose the files to reduce
[fitfilespath,fitfiles]=getfiles('Choose the files you want to reduce');

% here we choose if we want to save the images of the fits
button = questdlg('Do you want to save the images showing the fits?','Save images?','Yes','No','Cancel','Yes'); 
if strcmp(button,'Yes')

    % if we want to save images we need the tag
    prompt={'Then please enter the "tag" you want to append to the filenames'};
    def={'1D'};
    dlgTitle='Input "tag" to append to images file names';
    lineNo=1;
    answer=inputdlg(prompt,dlgTitle,lineNo,def);
    tag=answer{1};
    % now we need to allow the user to put them in an appropriate directory
    outputpath=uigetdir(pwd,'Pick a directory for the output images');
    if outputpath==0, outputpath=pwd; end
    outputpath=[outputpath,filesep];
else
    tag=[];
    outputpath=[];
end
[file,path] = uiputfile('.txt','Output file for fit data');
outputfile=fullfile(path,file);




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [transmission,samplethickness]=gettransandthickness(filename,S_orig)
info_struct=mpainforead(filename);
if isempty(info_struct)
    transmission=S_orig.transfact;
    samplethickness=S_orig.sample_thickness;
end
if isempty(transmission) && isfield(info_struct,'sample_trans')
    transmission=info_struct.sample_trans;
else
    transmission=1;
end
if isempty(samplethickness) && isfield(info_struct,'sample_thickness')
    samplethickness=info_struct.sample_thickness;
else
    samplethickness=[];
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [S,X,Y]=get_create_SXY(S_orig,S_template,fitfilespath,fitfile,batch,X,Y)
% this function gets or creates S X and Y for the fitting routines based on
% if this is not batch mode just take the values from the original SAXS
% object
if batch==0
    S=S_orig;
else % if this is batch mode then probably the data has not been reduced
    filename=fullfile(fitfilespath,fitfile);
    [transmission, samplethickness]=gettransandthickness(filename,S_orig); %get transmission from info file if it exists
    [S,Sred]=reduce_templatewise(filename,S_template,transmission,samplethickness);
    S=Sred;
    S.pixels=S.pixels/Sred.livetime;
    X = Sred.xaxisfull;
    Y = Sred.pixels./Sred.livetime;
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function batchquikfitoutput(handles,fitfilespath,fitfile,outputpath,outputfile,tag)

filename=[fitfilespath fitfile];

% if we are supposed to print out the images
if ~isempty(outputpath)
    %first make the imagefilename
    [pathstr,name,ext] = fileparts(filename);
    jpgimagefile=[outputpath,name,'_',tag,'.jpg'];
    print(handles.figure,'-djpeg',jpgimagefile)
end
fid=fopen(outputfile,'a');
strcell=get(handles.fit,'UserData');
for ii=1:length(strcell)
    fprintf(fid,'%s \n',char(strcell(ii)));
end
fprintf(fid,' \n\n');
fclose(fid)





