function [params] = simulation_TREPR(params)
%SIMULATION_TREPR uses esfit to perform fitting of TREPR simulation
%
%   Usage: [params] = SIMULATION_TREPR(params), where params is a struct
%   created by the PRE_SIMULATION_TREPR function.
%   
%   This function will show the mean of maxima, specified in the
%   NORMALIZE_DATA function and allow inputs for Variation limits of
%   relevant parameters for the simulations and for fitting options.
%   "Start Fit" will call esfit and perform the specified fitting. For
%   possible values, please refer to the easyspin docs.
%   "Save Parameters" will write the current best fitting simulation
%   parameters as starting values for a possible next iteration of fitting
%   and also write them to the params struct. The button may only be
%   pressed after performing at least one iteration of fitting.
%   "Done" will close the window.

%% setup
%create struct for passing data between callbacks
eventdata.manSys = params.Manual_Sys;
eventdata.manExp.mwFreq = params.mwFreq; %GHz
eventdata.manExp.nPoints= length(params.Field_Vector);
eventdata.manExp.CenterSweep = 0.1*[params.Field_Center params.Field_Sweep]; % mT (converted from Gauss)
eventdata.manExp.Harmonic = 0; % zeroth harmonic
eventdata.manExp.Temperature = params.Triplett_pop;
eventdata.simSys = params.Manual_Sys; %initialize simulation parameters
eventdata.simExp = eventdata.manExp;

%% creating UI
fig = figure;
fig.Name = 'Simulation';
fig.Units = 'Normalized';
fig.Position = [.15 .2 .7 .6];
fig.Tag = 'Normalize';

%panel for plot
plotpanel = uipanel(fig);
plotpanel.Units = 'Normalized';
plotpanel.Position = [.01 .01 .7 .98];
%axes for plot
ax = axes(plotpanel);
ax.XLabel.String = 'magnetic field';
ax.YLabel.String = 'Intensity';
%plot manual simulation
[bfield,spec] = pepper(eventdata.manSys,eventdata.manExp);
spec_norm = spec/max(spec); % normalize the simulation
plot(ax,0.1*params.Field_Vector,params.max_mean,'r',...
     bfield,spec_norm,'b','LineWidth',1.2)
xlabel 'Magnetic Field / mT'
ylabel 'EPR signal / A. U.'
legend('experimental','simulation')
axis tight

%% create push buttons
s = uicontrol(fig,'Style','pushbutton');
s.String = 'Start Fit';
s.Units = 'Normalized';
s.Position = [.72 .13 .27 .05];
s.FontUnits = 'Normalized';
s.FontSize = 0.6;
s.Tag = 'Start';
s.Callback = @SimStartButtonPushed;

p = uicontrol(fig,'Style','pushbutton');
p.String = 'Save Parameters';
p.Units = 'Normalized';
p.Position = [.72 .07 .27 .05];
p.FontUnits = 'Normalized';
p.FontSize = 0.6;
p.Tag = 'Save';
p.Callback = @SimSaveButtonPushed;

d = uicontrol(fig,'Style','pushbutton');
d.String = 'Done';
d.Units = 'Normalized';
d.Position = [.72 .01 .27 .05];
d.FontUnits = 'Normalized';
d.FontSize = 0.6;
d.Tag = 'Done';
d.Callback = @SimDoneButtonPushed;

%% create input and text fields (Triplet)
textTrip = uicontrol(fig,'Style','text');
textTrip.String = 'Triplett population variations';
textTrip.Units = 'Normalized';
textTrip.Position = [.71 .94 .28 .05];
textTrip.HorizontalAlignment = 'center';
textTrip.FontUnits = 'Normalized';
textTrip.FontSize = 0.6;
textTrip.FontWeight = 'bold';
textTrip.Tag = 'textTrip';

textTx = uicontrol(fig,'Style','text');
textTx.String = 'T_1 = ';
textTx.Units = 'Normalized';
textTx.Position = [.71 .89 .04333 .05];
textTx.HorizontalAlignment = 'right';
textTx.FontUnits = 'Normalized';
textTx.FontSize = 0.6;
textTx.Tag = 'textTx';

InpTx = uicontrol(fig,'Style','edit');
InpTx.String = '0';
InpTx.Units = 'Normalized';
InpTx.Position = [.75334 .89 .04333 .05];
InpTx.HorizontalAlignment = 'left';
InpTx.FontUnits = 'Normalized';
InpTx.FontSize = 0.6;
InpTx.Tag = 'InpTx';

textTy = uicontrol(fig,'Style','text');
textTy.String = 'T_2 = ';
textTy.Units = 'Normalized';
textTy.Position = [.80668 .89 .04333 .05];
textTy.HorizontalAlignment = 'right';
textTy.FontUnits = 'Normalized';
textTy.FontSize = 0.6;
textTy.Tag = 'textTy';

InpTy = uicontrol(fig,'Style','edit');
InpTy.String = '0';
InpTy.Units = 'Normalized';
InpTy.Position = [.85001 .89 .04333 .05];
InpTy.HorizontalAlignment = 'left';
InpTy.FontUnits = 'Normalized';
InpTy.FontSize = 0.6;
InpTy.Tag = 'InpTy';

textTz = uicontrol(fig,'Style','text');
textTz.String = 'T_3 = ';
textTz.Units = 'Normalized';
textTz.Position = [.90334 .89 .04333 .05];
textTz.HorizontalAlignment = 'right';
textTz.FontUnits = 'Normalized';
textTz.FontSize = 0.6;
textTz.Tag = 'textTz';

InpTz = uicontrol(fig,'Style','edit');
InpTz.String = '0';
InpTz.Units = 'Normalized';
InpTz.Position = [.94667 .89 .04333 .05];
InpTz.HorizontalAlignment = 'left';
InpTz.FontUnits = 'Normalized';
InpTz.FontSize = 0.6;
InpTz.Tag = 'InpTz';

%% create input and text fields (D & E)
textDE = uicontrol(fig,'Style','text');
textDE.String = 'D tensor variation';
textDE.Units = 'Normalized';
textDE.Position = [.71 .78 .28 .05];
textDE.HorizontalAlignment = 'center';
textDE.FontUnits = 'Normalized';
textDE.FontSize = 0.6;
textDE.FontWeight = 'bold';
textDE.Tag = 'textDE';

textD = uicontrol(fig,'Style','text');
textD.String = 'D = ';
textD.Units = 'Normalized';
textD.Position = [.71 .73 .0675 .05];
textD.HorizontalAlignment = 'right';
textD.FontUnits = 'Normalized';
textD.FontSize = 0.6;
textD.Tag = 'textD';

InpD = uicontrol(fig,'Style','edit');
InpD.String = '100';
InpD.Units = 'Normalized';
InpD.Position = [.7775 .73 .0675 .05];
InpD.HorizontalAlignment = 'left';
InpD.FontUnits = 'Normalized';
InpD.FontSize = 0.6;
InpD.Tag = 'InpD';

textE = uicontrol(fig,'Style','text');
textE.String = 'E = ';
textE.Units = 'Normalized';
textE.Position = [.855 .73 .0675 .05];
textE.HorizontalAlignment = 'right';
textE.FontUnits = 'Normalized';
textE.FontSize = 0.6;
textE.Tag = 'textE';

InpE = uicontrol(fig,'Style','edit');
InpE.String = '20';
InpE.Units = 'Normalized';
InpE.Position = [.9225 .73 .0675 .05];
InpE.HorizontalAlignment = 'left';
InpE.FontUnits = 'Normalized';
InpE.FontSize = 0.6;
InpE.Tag = 'InpE';

%% create input and text fields (linewidth)
textLW = uicontrol(fig,'Style','text');
textLW.String = 'Linewidth variations';
textLW.Units = 'Normalized';
textLW.Position = [.71 .62 .28 .05];
textLW.HorizontalAlignment = 'center';
textLW.FontUnits = 'Normalized';
textLW.FontSize = 0.6;
textLW.FontWeight = 'bold';
textLW.Tag = 'textLW';

textGauss = uicontrol(fig,'Style','text');
textGauss.String = 'lw(Gau) = ';
textGauss.Units = 'Normalized';
textGauss.Position = [.71 .57 .0675 .05];
textGauss.HorizontalAlignment = 'right';
textGauss.FontUnits = 'Normalized';
textGauss.FontSize = 0.6;
textGauss.Tag = 'textGauss';

InpGauss = uicontrol(fig,'Style','edit');
InpGauss.String = '1';
InpGauss.Units = 'Normalized';
InpGauss.Position = [.7775 .57 .0675 .05];
InpGauss.HorizontalAlignment = 'left';
InpGauss.FontUnits = 'Normalized';
InpGauss.FontSize = 0.6;
InpGauss.Tag = 'InpGauss';

textLor = uicontrol(fig,'Style','text');
textLor.String = 'lw(Lor) = ';
textLor.Units = 'Normalized';
textLor.Position = [.855 .57 .0675 .05];
textLor.HorizontalAlignment = 'right';
textLor.FontUnits = 'Normalized';
textLor.FontSize = 0.6;
textLor.Tag = 'textLor';

InpLor = uicontrol(fig,'Style','edit');
InpLor.String = '0';
InpLor.Units = 'Normalized';
InpLor.Position = [.9225 .57 .0675 .05];
InpLor.HorizontalAlignment = 'left';
InpLor.FontUnits = 'Normalized';
InpLor.FontSize = 0.6;
InpLor.Tag = 'InpLor';

%% create input and text fields (g)
textG = uicontrol(fig,'Style','text');
textG.String = 'g-value variation = ';
textG.Units = 'Normalized';
textG.Position = [.71 .46 .2 .05];
textG.HorizontalAlignment = 'right';
textG.FontUnits = 'Normalized';
textG.FontSize = 0.6;
textG.Tag = 'textG';

InpG = uicontrol(fig,'Style','edit');
InpG.String = '0.01';
InpG.Units = 'Normalized';
InpG.Position = [.9225 .46 .0675 .05];
InpG.HorizontalAlignment = 'left';
InpG.FontUnits = 'Normalized';
InpG.FontSize = 0.6;
InpG.Tag = 'InpG';

%% create input and text fields (FitOpt)
textOpt = uicontrol(fig,'Style','text');
textOpt.String = 'Fitting Options';
textOpt.Units = 'Normalized';
textOpt.Position = [.71 .35 .28 .05];
textOpt.HorizontalAlignment = 'center';
textOpt.FontUnits = 'Normalized';
textOpt.FontSize = 0.6;
textOpt.FontWeight = 'bold';
textOpt.Tag = 'textFitOpt';

textMeth = uicontrol(fig,'Style','text');
textMeth.String = 'Method: ';
textMeth.Units = 'Normalized';
textMeth.Position = [.71 .30 .0675 .05];
textMeth.HorizontalAlignment = 'right';
textMeth.FontUnits = 'Normalized';
textMeth.FontSize = 0.6;
textMeth.Tag = 'textMeth';

InpMeth = uicontrol(fig,'Style','edit');
InpMeth.String = 'simplex fcn';
InpMeth.Units = 'Normalized';
InpMeth.Position = [.7775 .30 .2125 .05];
InpMeth.HorizontalAlignment = 'left';
InpMeth.FontUnits = 'Normalized';
InpMeth.FontSize = 0.6;
InpMeth.Tag = 'InpMeth';

textScal = uicontrol(fig,'Style','text');
textScal.String = 'Scaling: ';
textScal.Units = 'Normalized';
textScal.Position = [.71 .24 .0675 .05];
textScal.HorizontalAlignment = 'right';
textScal.FontUnits = 'Normalized';
textScal.FontSize = 0.6;
textScal.Tag = 'textScal';

InpScal = uicontrol(fig,'Style','edit');
InpScal.String = 'lsq';
InpScal.Units = 'Normalized';
InpScal.Position = [.7775 .24 .2125 .05];
InpScal.HorizontalAlignment = 'left';
InpScal.FontUnits = 'Normalized';
InpScal.FontSize = 0.6;
InpScal.Tag = 'InpScal';

%% UI wait
uicontrol(InpTx); %passes focus to first input
uiwait(fig)

%% Callback functions
    function SimStartButtonPushed(src,event)
        %get Vary and Opt from Input
        varT1 = str2double(get(InpTx,'String'));
        varT2 = str2double(get(InpTy,'String'));
        varT3 = str2double(get(InpTz,'String'));
        Vary.Temperature = [varT1 varT2 varT3];
        varD = str2double(get(InpD,'String'));
        varE = str2double(get(InpE,'String'));
        Vary.D = [varD varE];
        varGauss = str2double(get(InpGauss,'String'));
        varLor = str2double(get(InpLor,'String'));
        Vary.lw = [varGauss varLor];
        Vary.g = str2double(get(InpG,'String'));
        FitOpt.Method = get(InpMeth,'String');
        FitOpt.Scaling = get(InpScal,'String');
        %get previous simulation parameters (manual or saved)
        Sys0 = eventdata.simSys;
        Exp0 = eventdata.simExp;
        %perform fit
        Sys0.Temperature = [0 0 0];
        [BestSys,BestSpc] = esfit('thyme',params.max_mean,Sys0,Vary,Exp0,[],FitOpt);
        plot(ax,0.1*params.Field_Vector,params.max_mean,'r',...
                0.1*params.Field_Vector,BestSpc,'b','LineWidth',1.2)
        xlabel 'Magnetic Field / mT'
        ylabel 'EPR signal / A. U.'
        legend('experimental','simulation')
        axis tight
        %normalize Triplett population
        Tsum = sum(BestSys.Temperature);
        BestSys.Temperature = BestSys.Temperature ./ Tsum;
        %write best simulation parameters to eventdata
        eventdata.BestSys = BestSys;
    end
    
    function SimSaveButtonPushed(src,event)
        %set current parameters as new start values
        eventdata.simSys = eventdata.BestSys;
        eventdata.simExp.Temperature = eventdata.BestSys.Temperature;
        %save fitted parameters to struct
        params.Fitted_Simulation = eventdata.BestSys;
    end
    
    function SimDoneButtonPushed(src,event)
        close 'Simulation'
    end
 
end