function varargout = cp_fit(varargin)
% Begin initialization code - DO NOT EDIT
    gui_Singleton = 1;
    gui_State = struct('gui_Name',       mfilename, ...
                       'gui_Singleton',  gui_Singleton, ...
                       'gui_OpeningFcn', @dsc_OpeningFcn, ...
                       'gui_OutputFcn',  @dsc_OutputFcn, ...
                       'gui_LayoutFcn',  [] , ...
                       'gui_Callback',   []);
    if nargin && ischar(varargin{1})
        gui_State.gui_Callback = str2func(varargin{1});
    end

    if nargout
        [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
    else
        gui_mainfcn(gui_State, varargin{:});
    end
% End initialization code - DO NOT EDIT
end

% --- Executes when user attempts to close figure1.
function figure1_CloseRequestFcn(hObject, eventdata, handles)
% hObject    handle to figure1 (see GCBO)
    if isfield(handles,'hfig') && ishandle(handles.hfig)
        delete(handles.hfig);
    end
    delete(hObject);
end

% --- Executes just before lret is made visible.
function dsc_OpeningFcn(hObject, eventdata, handles, varargin)
    handles.output = hObject;
    handles.cdir = pwd;
    handles.two_state_irrev = 1;
    handles.two_state_rev_eq = 2;
    handles.two_state_rev_ode = 3;
    handles.three_state_irrev = 4;
    handles.three_state_rev_irrev_eq = 5;
    handles.three_state_rev_irrev_ode = 6;
    handles.three_state_irrev_rev_eq = 7;
    handles.three_state_irrev_rev_ode = 8;
    handles.three_state_rev_eq = 9;
    handles.three_state_rev_ode = 10;
    set(handles.uipanelModel,'SelectionChangeFcn',{@uipanelModel_SelectionChangeFcn,handles});
    set(handles.uipanelN2U,'SelectionChangeFcn',{@uipanelN2U_SelectionChangeFcn,handles});
    set(handles.uipanelU2I,'SelectionChangeFcn',{@uipanelU2I_SelectionChangeFcn,handles});
    updateRates(handles);
    guidata(hObject, handles);
end

% --- Outputs from this function are returned to the command line.
function varargout = dsc_OutputFcn(hObject, eventdata, handles) 
    % Get default command line output from handles structure
    varargout{1} = handles.output;
    set(handles.edTxtOut, 'FontName', 'Consolas');
    set(handles.edTxtOut, 'FontSize', 8);
    
    jScrollPane = findjobj(handles.edTxtOut);
    jViewPort = jScrollPane.getViewport;
    jTxtOut = jViewPort.getComponent(0);
    setappdata(handles.edTxtOut,'jTxtOut',jTxtOut);
    %
    cm = uicontextmenu;
    item1 = uimenu(cm, 'Label', 'Clear', 'Callback', @clearEdTxtOut);
    set(handles.edTxtOut,'uicontextmenu',cm);
    
    function clearEdTxtOut(~,~)
        set(handles.edTxtOut,'String','');
    end
end


function tabSelection_Callback(hObject, eventdata, handles)
    if hObject==handles.btnTab2
        set(handles.uipanel1,'Visible','Off'); 
        set(handles.uipanel2,'Visible','On');
        set(handles.uipanel2,'position',get(handles.uipanel1,'position'));
    else
        set(handles.uipanel1,'Visible','On');
        set(handles.uipanel2,'Visible','Off');
    end
end


function btnFile_Callback(hObject, eventdata, handles)
    handles.output = hObject;
    [fn,pn] = uigetfile(fullfile(handles.cdir,'*.xls;*.xlsx'),'Select file to open');
    if fn ~= 0   
        handles.cdir = pn;    
        set(handles.edInFile,'string',fullfile(pn,fn));
    end
    guidata(hObject, handles);
end


function btnTest_Callback(hObject, eventdata, handles)
    [DH,E,Th,mdl,inpfile] = getInputParams(handles);
    [T,cp,v] = readData(inpfile);
    handles = myplot('raw',T,cp,v,{'k'},{'-o','-*'},handles);
    [func_cp,p] = trimMdlParam(handles,mdl,DH,E,Th);
    cp_fit = func_cp(p,v,T);   
    handles = myplot('fit',T,cp_fit,v,{'r'},{':'},handles);
    guidata(hObject,handles); 
end


function btnFit_Callback(hObject, eventdata, handles)
    [DH,E,Th,mdl,inpfile,optparam,fix] = getInputParams(handles);
    [T,cp,v] = readData(inpfile);
    handles = myplot('raw',T,cp,v,{'k'},{'-o','*'}, handles);
    [func_cp,p0,fixp] = trimMdlParam(handles,mdl,DH,E,Th,fix);
    cp_fit = func_cp(p0,v,T);   
    handles = myplot('fit',T,cp_fit,v,{'r'},{':'},handles);
    set(handles.btnStop,'UserData',0);
    tabSelection_Callback(handles.btnTab2,0,handles); pause(1); % 1s
    [p,ci] = runnested(p0,T,cp,v,func_cp,optparam,fixp);
    cp_fit = func_cp(p,v,T);    
    handles = myplot('fit',T,cp_fit,v,{'r'},{':'}, handles);
    [DH,E,Th] = sortMdlParam(handles,mdl,p,DH,E,Th);
    updateModelParams(handles,DH,E,Th);
    handles.lastfit={DH,E,Th,mdl,v,T,cp_fit,inpfile};  
    guidata(hObject,handles); 
    
    function [p1,c1,g1] = runnested(p0,T,ydata,v,func_cp,optparam,fixp)
        z0 = p0(~logical(fixp));
        Niter = optparam(1);
        Nfunc = optparam(2);
        options = optimset('Display','iter','OutputFcn', @outfun,...
                           'TolX',1.0e-10,'TolFun',1.0e-10,'MaxFunEvals',Nfunc,'MaxIter',Niter);
        lb(z0>0)=0; lb(z0<0)=-inf;
        ub(z0>0)=inf; ub(z0<0)=0;
        [z1,~,residual,exitflag,output,~,jacobian] = lsqnonlin(@func_err,z0,lb,ub,options); % lsqcurvefit
        p1 = p0;
        p1(~logical(fixp)) = z1;
        c1 = NaN(length(p1),2);
        g1 = NaN(1,length(p1));
        if exitflag >=0
        end
        hed = handles.edTxtOut;
        txt_output(hed,sprintf('\n Param | Confidence interval | Gradient'));
        txt_output(hed,sprintf(' %-8.4g%-9.5g%-9.5g%12.4g\n',[p1' c1 g1']'));
        txt_output(hed,['Algorithm: ' output.algorithm]);
        line=strsplit(output.message,{'\r','\n'})
        txt_output(hed,sprintf('%s\n',line{1:min(length(line),3)}));
        txt_output(hed,' ');
        %
        % 
        function err = func_err(z) 
            p = p0;
            p(~logical(fixp)) = z;
            yfit = func_cp(p,v,T);   % cal/mol, row vect cell array
            err = cat(2,yfit{:}) - cat(2,ydata{:});  
        end
        
        function stop = outfun(z, optimValues, state, varargin)
            stop = logical(get(handles.btnStop,'UserData'));
            hed = handles.edTxtOut;
            switch state
                case 'init'
                    txt_output(hed,sprintf('\nIter  Func-count  f(x)  step  optimality'));
                    txt_output(hed,'-----------------------------------------');
                case 'iter' % others: interrupt,init,done
                    iter = optimValues.iteration;
                    fcount = optimValues.funccount;
                    fval = optimValues.resnorm;
                    step = optimValues.stepsize;
                    opt1st = optimValues.firstorderopt;
                    txt_output(hed,sprintf('%3d%4d%11.4g%11.4g%11.4g',iter,fcount,fval,step,opt1st));
                case 'done'
                    %txt_output(hed,['\nGradients: ', num2str(optimValues.gradient')]);
                case 'interrupt'
                otherwise
            end
        end
    end
end


function btnStop_Callback(hObject, eventdata, handles)
    set(hObject,'UserData',1);
end


function btnSave_Callback(hObject, eventdata, handles)
    if ~isfield(handles,'lastfit') 
        msgbox('Nothing to save - run fit first');
        return
    end
    [DH,E,Th,mdl,v,T,cp,fn]=handles.lastfit{:};
    [~,sheets] = xlsfinfo(fn);
    for i=1:length(v)
        raw(1:length(T{i}),2*i-1) = num2cell(T{i}');
        raw(1:length(cp{i}),2*i) = num2cell(cp{i}');  
    end
    raw(8:end+7,:) = raw(1:end,:);
    raw(1:7,:) = {[]};
    [DH,E,Th] = nullifyUndefParams(handles,DH,E,Th);
    raw(1,1:2) = ['model:' cellstr(getModelName(handles,mdl))];
    raw(2,1:2) = ['Source:' cellstr(sheets{1})];
    raw(3,1:length(DH)+1) = ['DH12,DH23:' num2cell(DH)];
    raw(4,1:length(E)+1) = ['E12,E21,E23,E32:' num2cell(E)];
    raw(5,1:length(Th)+1) = ['T12,T21,T23,T32:' num2cell(Th)];
    raw(6,1:length(v)+1) = ['scan rate:' num2cell(v)];
    e = actxserver('excel.application');
    wb = e.Workbooks.Open(fn, 0, false); 
    ws = wb.Worksheets; 
    ws.Add([],ws.Item(ws.Count));   
    name = ws.Item(ws.Count).Name;
    wb.Save();  
    e.Quit();   
    pause(2);
    xlswrite(fn,raw,name);
    txt_output(handles.edTxtOut,sprintf('Results saved to file: %s',fn));
end


function [T,cp,v] = readData(inpfile)
    [~,~,raw] = xlsread(inpfile,1);
    raw(all(cellfun(@(x) any(isnan(x)), raw)==1,2),:)=[];
    raw(1,:) = [];
    v = cell2mat(raw(1,:));
    v(2:2:end) = [];
    raw(1,:) = [];
    [~,ncol] = size(raw); 
    if ncol ~= 2*length(v)
        txt_output('Scan rates inconsistent with data');
        return;
    end
    for i=1:length(v)
        T{i} = cell2mat(raw(:,2*i-1))'; 
        cp{i} = cell2mat(raw(:,2*i))';   
        T{i} = T{i}(~isnan(T{i}));
        cp{i} = cp{i}(~isnan(cp{i}));
    end
end


function handles = myplot(name,T,cp,v,col,sym,handles)
    if ~isfield(handles,'hfig') || ~ishandle(handles.hfig) 
        hfig = figure('tag','dsc fit'); 
        hold on; 
        if isdeployed
        	set(hfig, 'MenuBar', 'none');   
            set(hfig, 'ToolBar', 'figure');
        end
        xlabel('Temperature (deg)');
        ylabel('Cp (cal/deg*mol)');
        box on;
        cm = uicontextmenu;
        item1 = uimenu(cm, 'Label', 'Copy Figure', 'Callback', @copyfig);
        item2 = uimenu(cm, 'Label', 'Save Figure', 'Callback', @savefig);
        item3 = uimenu(cm, 'Label', 'Copy Data', 'Callback', @copydat);
        set(gca,'uicontextmenu',cm);
        handles.hfig = hfig;
    end
    figure(handles.hfig); 
    for i=1:length(v)
        handle = getappdata(handles.hfig,[name '_' num2str(i)]);
        if isempty(handle)
            sty = [col{rem(i-1,length(col))+1}, sym{rem(i-1,length(sym))+1}];
            hg = plot(T{i},cp{i},sty,'MarkerSize',2);
            set(hg,'Tag',[name '-' num2str(i)]);
            setappdata(handles.hfig,[name '_' num2str(i)],hg);
        else
            set(handle(1),'xdata',T{i},'ydata',cp{i});
        end
        leg{i} = ['v = ' num2str(v(i))];
    end
    if name=='raw'
        legend(leg,'FontSize',8);
        ymin=min([cp{:}]);
        ymax=max([cp{:}]);
        axis([-inf inf ymin-0.01*(ymax-ymin),ymax+0.05*(ymax-ymin)]);
    end
    drawnow;
%    hold off;
end

function copyfig(src,~)  
    print(gcf,'-dmeta','-noui');  
end    
        
function savefig(src,~) 
	[fn,pn] = uiputfile('*.png;*.pdf','File Selection','test.pdf');
	%handles.cdir = pn;   
    try
        saveas(gcf,fullfile(pn,fn));
	catch e
        msgbox(e.message);
	end
end
        
function copydat(src,~)  
	objs = get(gca,'Children');
	xdata = get(objs, 'XData');
	ydata = get(objs, 'YData');
	xydat=vertcat(xdata{1},ydata{:});
	arraystring = num2clip(xydat'); 
end

function txt_output(hed,str)
    txt= get(hed,'String')
    txt{end+1}=str;
    set(hed,'String',txt);
    drawnow
    jTxtOut = getappdata(hed,'jTxtOut');
    jTxtOut.setCaretPosition(jTxtOut.getDocument.getLength);
end


function [func_cp,p,varargout] = trimMdlParam(handles,mdl,DH,E,Th,varargin)
    if (~isempty(varargin))
        fix = varargin{1};
        fix_DH=fix(1:2);fix_E=fix(3:6);fix_Th=fix(7:10);
    end
    switch mdl
        case handles.two_state_irrev 
            func_cp = @func_cp_2state_irrev;
            p = [DH(1),E(1),Th(1)];
            if (~isempty(varargin)) fixp=[fix_DH(1),fix_E(1),fix_Th(1)]; end
        case handles.two_state_rev_eq 
            func_cp = @func_cp_2state_rev_eq;
            p = [DH(1),Th(1)];
            if (~isempty(varargin)) fixp=[fix_DH(1),fix_Th(1)]; end
        case handles.two_state_rev_ode 
            func_cp = @func_cp_2state_rev_ode;
            p = [E(1:2),Th(1:2)];
            if (~isempty(varargin)) fixp=[fix_E(1:2),fix_Th(1:2)]; end
        case handles.three_state_irrev 
            func_cp = @func_cp_3state_irrev;
            p = [DH(1:2),E([1,3]),Th([1,3])];
            if (~isempty(varargin)) fixp=[fix_DH(1:2),fix_E([1,3]),fix_Th([1,3])]; end
        case handles.three_state_irrev_rev_eq 
            func_cp = @func_cp_3state_irrev_rev_eq;
            p = [DH(1:2),E(1),Th([1,3])];
            if (~isempty(varargin)) fixp=[fix_DH(1:2),fix_E(1),fix_Th([1,3])]; end
        case handles.three_state_irrev_rev_ode 
            func_cp = @func_cp_3state_irrev_rev_ode;
            p = [DH(1),E([1,3,4]),Th([1,3,4])];
            if (~isempty(varargin)) fixp=[fix_DH(1),fix_E([1,3,4]),fix_Th([1,3,4])]; end
        case handles.three_state_rev_eq 
            func_cp = @func_cp_3state_rev_eq;
            p = [DH(1:2),Th([1,3])];
            if (~isempty(varargin)) fixp=[fix_DH(1:2),fix_Th([1,3])]; end
        case handles.three_state_rev_ode 
            func_cp = @func_cp_3state_rev_ode;
            p = [E(1:4),Th(1:4)];
            if (~isempty(varargin)) fixp = [fix_E(1:4),fix_Th(1:4)]; end
        case handles.three_state_rev_irrev_eq 
            func_cp = @func_cp_LumryEyring_eq;
            p = [DH(1:2),E(3),Th([1,3])];
            if (~isempty(varargin)) fixp=[fix_DH(1:2),fix_E(3),fix_Th([1,3])]; end
        case handles.three_state_rev_irrev_ode 
            func_cp = @func_cp_LumryEyring_ode;
            p = [DH(2),E([1,2,3]),Th([1,2,3])];
            if (~isempty(varargin)) fixp=[fix_DH(2),fix_E([1,2,3]),fix_Th([1,2,3])]; end
        otherwise
    end
    if (~isempty(varargin)) 
        varargout(1) = {fixp}; 
    end
end


function [DH,E,Th] = sortMdlParam(handles,mdl,p,DH0,E0,Th0)
    DH=DH0;E=E0;Th=Th0;
    switch mdl
        case handles.two_state_irrev, DH(1)=p(1);E(1)=p(2);Th(1)=p(3);
        case handles.two_state_rev_eq, DH(1)=p(1);Th(1)=p(2);
        case handles.two_state_rev_ode, E(1:2)=p(1:2);Th(1:2)=p(3:4);
        case handles.three_state_irrev, DH(1:2)=p(1:2);E([1,3])=p(3:4);Th([1,3])=p(5:6);
        case handles.three_state_irrev_rev_eq, DH(1:2)=p(1:2);E(1)=p(3);Th([1,3])=p(4:5);
        case handles.three_state_irrev_rev_ode, DH(1)=p(1);E([1,3,4])=p(2:4);Th([1,3,4])=p(5:7);
        case handles.three_state_rev_irrev_eq, DH(1:2)=p(1:2);E(3)=p(3);Th([1,3])=p(4:5);
        case handles.three_state_rev_irrev_ode, DH(2)=p(1);E([1,2,3])=p(2:4);Th([1,2,3])=p(5:7);
        case handles.three_state_rev_eq, DH(1:2)=p(1:2);Th([1,3])=p(3:4);
        case handles.three_state_rev_ode, E(1:4)=p(1:4);Th(1:4)=p(5:8);
        otherwise
    end
end


function str = getModelName(handles,mdl)
    switch(mdl)
        case handles.two_state_irrev, str='two-state irrev';
        case handles.two_state_rev_eq,  str='two-state rev, equilibrium';
        case handles.two_state_rev_ode, str='two-state rev, non-equilibrium';
        case handles.three_state_irrev, str='three-state irrev';
        case handles.three_state_irrev_rev_eq, str='three-state irrev-rev, equilibrium';
        case handles.three_state_irrev_rev_ode, str='three-state irrev-rev, non-equilibrium';
        case handles.three_state_rev_irrev_eq, str='three-state rev-irrev, equilibrium';
        case handles.three_state_rev_irrev_ode, str='three-state rev-irrev, non-equilibrium';
        case handles.three_state_rev_eq, str='three-state rev, equilibrium';
        case handles.three_state_rev_ode, str='three-state rev, non-equilibrium';
    end 
end


function [DH,E,Th] = nullifyUndefParams(handles,DH0,E0,Th0)
    DH=DH0;E=E0;Th=Th0;
    if get(handles.radio2State,'Value') == 1 
        DH([2])=NaN; E([3,4])=NaN; Th([3,4])=NaN;
    end
    if get(handles.radioN2Uirrev,'Value')==1 
        E([2])=NaN; Th([2])=NaN;
    else
        if get(handles.checkboxN2Ueq,'Value')==1
            E([1,2])=NaN; Th([2])=NaN;
        else
            DH([1])=NaN;
        end
    end
    if get(handles.radioU2Iirrev,'Value')==1 
        E([4])=NaN; Th([4])=NaN;
    else
        if get(handles.checkboxU2Ieq,'Value')==1
            E([3,4])=NaN; Th([4])=NaN;
        else
            DH([2])=NaN;
        end
    end
end


function [DH,E,Th,varargout] = getInputParams(handles)
    DH(1) = str2double(get(handles.edDH12,'string'));
    DH(2) = str2double(get(handles.edDH23,'string'));
    E(1) = str2double(get(handles.edE12,'string'));
    E(2) = str2double(get(handles.edE21,'string'));
    E(3) = str2double(get(handles.edE23,'string'));
    E(4) = str2double(get(handles.edE32,'string'));
    Th(1) = str2double(get(handles.edT12,'string'));
    Th(2) = str2double(get(handles.edT21,'string'));
    Th(3) = str2double(get(handles.edT23,'string'));
    Th(4) = str2double(get(handles.edT32,'string'));
    % determine which model
    switch get(get(handles.uipanelModel,'SelectedObject'),'Tag')
        case 'radio2State'
            if get(handles.radioN2Uirrev,'Value') == 1  
                mdl = handles.two_state_irrev;
            else     % reversible
                if get(handles.checkboxN2Ueq,'Value') == 1 
                    mdl = handles.two_state_rev_eq;
                else
                    mdl = handles.two_state_rev_ode;
                end
            end
        case 'radio3State'
            if get(handles.radioN2Uirrev,'Value') == 1  
                if get(handles.radioU2Iirrev,'Value') == 1  
                    mdl = handles.three_state_irrev;
                else   %U-I reversible
                    if get(handles.checkboxU2Ieq,'Value') == 1 
                        mdl = handles.three_state_irrev_rev_eq;
                    else  % U-I kinetically driven
                        mdl = handles.three_state_irrev_rev_ode;
                    end
                end
            else   
                if get(handles.checkboxN2Ueq,'Value') == 1  
                    if get(handles.radioU2Iirrev,'Value') == 1  
                        mdl = handles.three_state_rev_irrev_eq;
                    else  
                        mdl = handles.three_state_rev_eq;
                    end
                else   
                    if get(handles.radioU2Iirrev,'Value') == 1  
                        mdl = handles.three_state_rev_irrev_ode;
                    else  
                        mdl = handles.three_state_rev_ode;
                    end
                end
            end
        otherwise
    end
    %
    Niter = 100; 
    Nfunc = 5000; 
    inpfile = get(handles.edInFile,'string');
    fix_DH(1) = (get(handles.checkboxFixDH12,'Value') == get(handles.checkboxFixDH12,'Max'));
    fix_DH(2) = (get(handles.checkboxFixDH23,'Value') == get(handles.checkboxFixDH23,'Max'));
    fix_E(1) = (get(handles.checkboxFixE12,'Value') == get(handles.checkboxFixE12,'Max'));
    fix_E(2) = (get(handles.checkboxFixE21,'Value') == get(handles.checkboxFixE21,'Max'));
    fix_E(3) = (get(handles.checkboxFixE23,'Value') == get(handles.checkboxFixE23,'Max'));
    fix_E(4) = (get(handles.checkboxFixE32,'Value') == get(handles.checkboxFixE32,'Max'));
    fix_Th(1) = (get(handles.checkboxFixT12,'Value') == get(handles.checkboxFixT12,'Max'));
    fix_Th(2) = (get(handles.checkboxFixT21,'Value') == get(handles.checkboxFixT21,'Max'));
    fix_Th(3) = (get(handles.checkboxFixT23,'Value') == get(handles.checkboxFixT23,'Max'));
    fix_Th(4) = (get(handles.checkboxFixT32,'Value') == get(handles.checkboxFixT32,'Max'));
    varargout(1) = {mdl};
    varargout(2) = {inpfile};
    varargout(3) = {[Niter,Nfunc]};
    varargout(4) = {[fix_DH,fix_E,fix_Th]};
end



function updateModelParams(handles,DH,E,Th)
    set(handles.edDH12,'string',float2str(DH(1)));
    set(handles.edDH23,'string',float2str(DH(2)));
    set(handles.edE12,'string',float2str(E(1)));
    set(handles.edE21,'string',float2str(E(2)));
    set(handles.edE23,'string',float2str(E(3)));
    set(handles.edE32,'string',float2str(E(4)));
    set(handles.edT12,'string',float2str(Th(1)));
    set(handles.edT21,'string',float2str(Th(2)));
    set(handles.edT23,'string',float2str(Th(3)));
    set(handles.edT32,'string',float2str(Th(4)));
end


function str = float2str(x)
    if abs(x) < 1
        str = num2str(x,'%.1e');
    elseif abs(x)<1e5
        str = num2str(x,'%.0f');
    else 
        str = num2str(x,'%.0e');
    end
end



function edit_Callback(hObject, eventdata, handles)
    updateRates(handles);
end


function updateRates(handles)
    [~,E,Th] = getInputParams(handles);
    R = 1.987e-3;         % kcal/mol*K
    T(1) = str2double(get(handles.edT1,'string'));
    T(2) = str2double(get(handles.edT2,'string'));
    T(3) = str2double(get(handles.edT3,'string'));
    k = exp(-repmat(E',1,3)/R.*(1./(273+repmat(T,4,1))-1./(273+repmat(Th',1,3))));
    if get(handles.radio2State,'Value') == 1 
        k([3,4],:)=NaN;
    end
    if get(handles.radioN2Uirrev,'Value')==1 
        k([2],:)=NaN;
    elseif get(handles.checkboxN2Ueq,'Value')==1
        k([1,2],:)=NaN;
    end
    if get(handles.radioU2Iirrev,'Value')==1 
        k([4],:)=NaN; 
    elseif get(handles.checkboxU2Ieq,'Value')==1
        k([3,4],:)=NaN; 
    end
    set(handles.txtRate12T1,'string',float2str(k(1,1)));
    set(handles.txtRate21T1,'string',float2str(k(2,1)));
    set(handles.txtRate23T1,'string',float2str(k(3,1)));
    set(handles.txtRate32T1,'string',float2str(k(4,1)));
    %
    set(handles.txtRate12T2,'string',float2str(k(1,2)));
    set(handles.txtRate21T2,'string',float2str(k(2,2)));
    set(handles.txtRate23T2,'string',float2str(k(3,2)));
    set(handles.txtRate32T2,'string',float2str(k(4,2)));
    %
    set(handles.txtRate12T3,'string',float2str(k(1,3)));
    set(handles.txtRate21T3,'string',float2str(k(2,3)));
    set(handles.txtRate23T3,'string',float2str(k(3,3)));
    set(handles.txtRate32T3,'string',float2str(k(4,3)));
end



function btnReset_Callback(hObject, eventdata, handles)
updateModelParams(handles,[100 10],[100 -10 20 10],[50 50 60 60]);
updateRates(handles);
end


function uipanelModel_SelectionChangeFcn(hObject, eventdata, handles)
switch get(eventdata.NewValue, 'Tag')
    case 'radio2State'
        set(handles.radioU2Iirrev,'enable','off');
        set(handles.radioU2Irev,'enable','off');
        set(handles.checkboxU2Ieq,'enable','off');
        set(handles.edDH23,'enable','off'); set(handles.checkboxFixDH23,'enable','off');
        set(handles.edE23,'enable','off'); set(handles.checkboxFixE23,'enable','off');
        set(handles.edE32,'enable','off'); set(handles.checkboxFixE32,'enable','off');
        set(handles.edT23,'enable','off'); set(handles.checkboxFixT23,'enable','off');
        set(handles.edT32,'enable','off'); set(handles.checkboxFixT32,'enable','off');
    case 'radio3State'
        set(handles.radioU2Iirrev,'enable','on');
        set(handles.radioU2Irev,'enable','on');
        set(handles.edDH23,'enable','on'); set(handles.checkboxFixDH23,'enable','on');
        set(handles.edE23,'enable','on'); set(handles.checkboxFixE23,'enable','on');
        set(handles.edT23,'enable','on'); set(handles.checkboxFixT23,'enable','on');
        if get(handles.radioU2Iirrev,'Value')~=1
            set(handles.checkboxU2Ieq,'enable','on');
            if get(handles.checkboxU2Ieq,'Value')~=1
                set(handles.edE32,'enable','on'); set(handles.checkboxFixE32,'enable','on');
                set(handles.edT32,'enable','on'); set(handles.checkboxFixT32,'enable','on');
            else
                set(handles.edE32,'enable','off'); set(handles.checkboxFixE32,'enable','off');
                set(handles.edT32,'enable','off'); set(handles.checkboxFixT32,'enable','off');
                set(handles.edE23,'enable','off'); set(handles.checkboxFixE23,'enable','off');
            end
        end
    otherwise
end
updateRates(handles);
%guidata(hObject,handles);
end


        
function uipanelN2U_SelectionChangeFcn(hObject, eventdata, handles)
switch get(eventdata.NewValue, 'Tag')
    case 'radioN2Uirrev' 
        set(handles.checkboxN2Ueq,'enable','off');
        set(handles.edDH12,'enable','on'); set(handles.checkboxFixDH12,'enable','on');
        set(handles.edE12,'enable','on'); set(handles.checkboxFixE12,'enable','on');
        set(handles.edE21,'enable','off'); set(handles.checkboxFixE21,'enable','off');
        set(handles.edT21,'enable','off'); set(handles.checkboxFixT21,'enable','off');
    case 'radioN2Urev'
        set(handles.checkboxN2Ueq,'enable','on');
        if get(handles.checkboxN2Ueq,'Value')==1 
            set(handles.edE12,'enable','off'); set(handles.checkboxFixE12,'enable','off');
            set(handles.edE21,'enable','off'); set(handles.checkboxFixE21,'enable','off');
            set(handles.edT21,'enable','off'); set(handles.checkboxFixT21,'enable','off');
        else
            set(handles.edDH12,'enable','off'); set(handles.checkboxFixDH12,'enable','off');
            set(handles.edE12,'enable','on'); set(handles.checkboxFixE12,'enable','on');
            set(handles.edE21,'enable','on'); set(handles.checkboxFixE21,'enable','on');
            set(handles.edT21,'enable','on'); set(handles.checkboxFixT21,'enable','on');
        end
    otherwise
end
updateRates(handles);
%guidata(hObject,handles);
end



function uipanelU2I_SelectionChangeFcn(hObject, eventdata, handles)
switch get(eventdata.NewValue, 'Tag')
    case 'radioU2Iirrev'
        set(handles.checkboxU2Ieq,'enable','off');
        set(handles.edDH23,'enable','on'); set(handles.checkboxFixDH23,'enable','on');
        set(handles.edE23,'enable','on'); set(handles.checkboxFixE23,'enable','on');
        set(handles.edE32,'enable','off'); set(handles.checkboxFixE32,'enable','off');
        set(handles.edT32,'enable','off'); set(handles.checkboxFixT32,'enable','off');        
    case 'radioU2Irev'
        set(handles.checkboxU2Ieq,'enable','on');
        if get(handles.checkboxU2Ieq,'Value')==1 
            set(handles.edE23,'enable','off'); set(handles.checkboxFixE23,'enable','off');
            set(handles.edE32,'enable','off'); set(handles.checkboxFixE32,'enable','off');
            set(handles.edT32,'enable','off'); set(handles.checkboxFixT32,'enable','off');
        else
            set(handles.edDH23,'enable','off'); set(handles.checkboxFixDH23,'enable','off');
            set(handles.edE23,'enable','on'); set(handles.checkboxFixE23,'enable','on');
            set(handles.edE32,'enable','on'); set(handles.checkboxFixE32,'enable','on');
            set(handles.edT32,'enable','on'); set(handles.checkboxFixT32,'enable','on');
        end
    otherwise
        
end
updateRates(handles);
end



function checkboxN2Ueq_Callback(hObject, eventdata, handles)
if get(hObject,'Value')==1 
    set(handles.edDH12,'enable','on'); set(handles.checkboxFixDH12,'enable','on');
    set(handles.edE12,'enable','off'); set(handles.checkboxFixE12,'enable','off');
    set(handles.edE21,'enable','off'); set(handles.checkboxFixE21,'enable','off');
    set(handles.edT21,'enable','off'); set(handles.checkboxFixT21,'enable','off');
else
    if get(handles.radioN2Uirrev,'Value')==1
        set(handles.edDH12,'enable','on'); set(handles.checkboxFixDH12,'enable','on');
    else
        set(handles.edDH12,'enable','off'); set(handles.checkboxFixDH12,'enable','off');
    end
    set(handles.edE12,'enable','on'); set(handles.checkboxFixE12,'enable','on');
    set(handles.edE21,'enable','on'); set(handles.checkboxFixE21,'enable','on');
    set(handles.edT21,'enable','on'); set(handles.checkboxFixT21,'enable','on');
end
updateRates(handles);
%guidata(hObject,handles);
end


function checkboxU2Ieq_Callback(hObject, eventdata, handles)
if get(hObject,'Value')==1 
    set(handles.edDH23,'enable','on'); set(handles.checkboxFixDH23,'enable','on'); 
    set(handles.edE23,'enable','off'); set(handles.checkboxFixE23,'enable','off');  
    set(handles.edE32,'enable','off'); set(handles.checkboxFixE32,'enable','off');
    set(handles.edT32,'enable','off'); set(handles.checkboxFixT32,'enable','off');
else
    if get(handles.radioU2Iirrev,'Value')==1
        set(handles.edDH23,'enable','on'); set(handles.checkboxFixDH23,'enable','on');
    else
        set(handles.edDH23,'enable','off'); set(handles.checkboxFixDH23,'enable','off');
    end
    set(handles.edE23,'enable','on'); set(handles.checkboxFixE23,'enable','on');
    set(handles.edE32,'enable','on'); set(handles.checkboxFixE32,'enable','on');
    set(handles.edT32,'enable','on'); set(handles.checkboxFixT32,'enable','on');
end
updateRates(handles);
end
