classdef pH_calibration < matlab.apps.AppBase

    % Properties that correspond to app components
    properties (Access = public)
        UIFigure                    matlab.ui.Figure
        TabGroup                    matlab.ui.container.TabGroup
        PTraw_tab                   matlab.ui.container.Tab
        raw_VrsButtonGroup          matlab.ui.container.ButtonGroup
        VrsSTDButton                matlab.ui.control.RadioButton
        VrsVButton                  matlab.ui.control.RadioButton
        raw_VkButtonGroup           matlab.ui.container.ButtonGroup
        VkSTDButton                 matlab.ui.control.RadioButton
        VkVButton                   matlab.ui.control.RadioButton
        MaxSlider                   matlab.ui.control.Slider
        Slider_2Label               matlab.ui.control.Label
        MinSlider                   matlab.ui.control.Slider
        SliderLabel                 matlab.ui.control.Label
        Choose_PTfile_Button        matlab.ui.control.Button
        UIAxes_IbIk                 matlab.ui.control.UIAxes
        UIAxes_Vk                   matlab.ui.control.UIAxes
        UIAxes_Vrs                  matlab.ui.control.UIAxes
        k2_tab                      matlab.ui.container.Tab
        idsEditField                matlab.ui.control.NumericEditField
        idsEditFieldLabel           matlab.ui.control.Label
        Upload_ph_log_to_penguin    matlab.ui.control.Button
        k2_SurfZoom_Slider          matlab.ui.control.Slider
        YaxissurfacezoomLabel_2     matlab.ui.control.Label
        k2fP_polyEdit               matlab.ui.control.NumericEditField
        k2fppolyorderLabel          matlab.ui.control.Label
        CalReportButton             matlab.ui.control.Button
        UITable_results             matlab.ui.control.Table
        PTrawSubset_ButtonGroup     matlab.ui.container.ButtonGroup
        PstationaryButton           matlab.ui.control.RadioButton
        PdecreasingButton           matlab.ui.control.RadioButton
        PincreasingButton           matlab.ui.control.RadioButton
        allButton                   matlab.ui.control.RadioButton
        k2_VrsCorr                  matlab.ui.control.UIAxes
        k2_P_vs_k2                  matlab.ui.control.UIAxes
        k2_VrsVc_vs_T               matlab.ui.control.UIAxes
        k2_VrsDrift                 matlab.ui.control.UIAxes
        Pcoefs_tab                  matlab.ui.container.Tab
        fP_SurfZoom_Slider          matlab.ui.control.Slider
        YaxissurfacezoomLabel       matlab.ui.control.Label
        Pcoefs_CAxisButtonGroup     matlab.ui.container.ButtonGroup
        DirectionButton             matlab.ui.control.RadioButton
        VkButton                    matlab.ui.control.RadioButton
        TimeButton                  matlab.ui.control.RadioButton
        TemperatureButton           matlab.ui.control.RadioButton
        fP_polyEdit                 matlab.ui.control.NumericEditField
        polyorderEditFieldLabel     matlab.ui.control.Label
        Pcoefs_FvsP_anom            matlab.ui.control.UIAxes
        Pcoefs_FvsP                 matlab.ui.control.UIAxes
        k0_tab                      matlab.ui.container.Tab
        k0_k0YaxisButtonGroup       matlab.ui.container.ButtonGroup
        k0_k0_medk0Button           matlab.ui.control.RadioButton
        k0_k0Button                 matlab.ui.control.RadioButton
        polyfitorderEditField       matlab.ui.control.EditField
        polyfitorderEditFieldLabel  matlab.ui.control.Label
        TimeoffsetEditField         matlab.ui.control.EditField
        TimeoffsetEditFieldLabel    matlab.ui.control.Label
        k0_YaxisButtonGroup         matlab.ui.container.ButtonGroup
        k0_TempButton               matlab.ui.control.RadioButton
        k0_stdVkButton              matlab.ui.control.RadioButton
        k0_VkButton                 matlab.ui.control.RadioButton
        MaxSlider_k0                matlab.ui.control.Slider
        MinSlider_k0                matlab.ui.control.Slider
        Choose_k0file_Button        matlab.ui.control.Button
        UIAxes_k0_Vk                matlab.ui.control.UIAxes
        UIAxes_k0_k0                matlab.ui.control.UIAxes
        UIAxes_k0_pH                matlab.ui.control.UIAxes
        SummaryTab                  matlab.ui.container.Tab
        GridLayout                  matlab.ui.container.GridLayout
        TextArea_summary            matlab.ui.control.TextArea
        UIAxes_k0OnHCl_hist         matlab.ui.control.UIAxes
        UIAxes_fPstats              matlab.ui.control.UIAxes
        UIAxes_k0OnOff_hist         matlab.ui.control.UIAxes
        UIAxes_k0_hist              matlab.ui.control.UIAxes
        UIAxes_k2_hist              matlab.ui.control.UIAxes
        UIAxes_k0stats              matlab.ui.control.UIAxes
        UIAxes_k2stats              matlab.ui.control.UIAxes
    end


    properties (Access = private)
        % Initialize PT chamber GUI parameters
        dirs = struct;      % Initialize a structure for paths
        PTdata  = [];       % Initialize a data matrix to hold data from data file
        PThdr   = {};       % Initialize header cell array
        PTinfo = struct;        % file source info holder
        I       = struct;   % Initialize index structure for PT chamber data
        PTtime = datetime; % Initialize datetime array for plotting
        tPT_SDN = [];       % predimension indexing array to be used with
        Pdir    = [];       % predim pressure trend array: up down, steady
        tPdir   = [];       % predim pressure trend array subset logical
        hVMinLine           % Vertical dashed Minimum slider line
        hVMaxLine           % Vertical dashed Minimum slider line

        % Initialize general purpose info structure
        info     = struct;   % predim structure to hold path, file name & results

        k2_data  = struct; % Initialize k2 & PCoeff results structure
        k0_data  = struct; % Initialize k0 results structure
        I2       = struct;   % Initialize k0 sw index structure
        color_pH = struct; % container for discrete color pH data

        MSC_list % look up table for pH SN & MSC, parsed from pHlog file

        k0raw_data  = [];       % Initialize a data matrix to hold data from data file
        k0raw_hdr   = {};       % Initialize header cell array
        k0raw_info  = struct;   % file source info holder

        tk0raw_SDN = [];
        tk0raw_ON  = [];


        hVMinLine_k0
        hVMaxLine_k0
        % Init plot handle holder
        summary= struct;
    end

    methods (Access = private)


        % ************************************************************
        % ***********   UPDATE PT CHAMBER RAW DATA TAB   *************
        % ************************************************************
        function update_raw_PT_tab(app)

            tg_raw = app.tPT_SDN & app.tPdir;
            X      = app.PTtime(tg_raw); % X axis data for all plots

            if isfield(app.info,'PT_TXT') && ishandle(app.info.PT_TXT)% hide Pdir legend
                app.info.PT_TXT.Visible = 'off';
            end

            % TOP PLOT VRS - choose between Vrs & std Vrs
            selectedButton = app.raw_VrsButtonGroup.SelectedObject;
            if strcmp(selectedButton.Text,'volts')
                Y_Vrs   = app.PTdata(tg_raw, app.I.VRS);
                Y_Label = app.PThdr{app.I.VRS};
                yscale  = 3;
            elseif strcmp(selectedButton.Text,'std volts')
                if isempty(app.I.VRSS)
                    Y_Vrs   = app.PTdata(tg_raw, app.I.VRS)*0;
                    Y_Label = 'No std VRS data available';
                else
                    Y_Vrs   = app.PTdata(tg_raw, app.I.VRSS);
                    Y_Label = app.PThdr{app.I.VRSS};
                end
                
                yscale  = 4;
            end
            y_std = std(Y_Vrs,'omitnan');
            y_lim = [-y_std y_std]*yscale + median(Y_Vrs,'omitnan');
            x_lim = datetime(app.info.LSDN_lim,'ConvertFrom','datenum');
            tstr  = {app.PTinfo.SourceDir, app.PTinfo.SourceFile};

            % Check y_lim values. SBS PT data has std Vrs & std Vk = all 0
            % JP 11/22/22 to suck in SBS raw data
            if diff(y_lim) == 0
                yy = y_lim;
                y_lim = [yy(1)-1, yy(1)+1];
                clear yy
            end



            % *********************************************************
            % TOP PLOT -- Vrs Plot
            app.UIAxes_Vrs.Box = 'On';

            InnerPos = app.UIAxes_Vrs.InnerPosition;

            scatter(app.UIAxes_Vrs, X, Y_Vrs, 9, app.PTdata(tg_raw, app.I.T),'filled')
            xlim(app.UIAxes_Vrs, x_lim);
            ylim(app.UIAxes_Vrs, y_lim);

            %caxis(app.UIAxes_Vrs, [min(app.PTdata(tg_raw, app.I.T)) max(app.PTdata(tg_raw, app.I.T))]);
            clim(app.UIAxes_Vrs, [min(app.PTdata(tg_raw, app.I.T)) max(app.PTdata(tg_raw, app.I.T))]);

            c = colorbar(app.UIAxes_Vrs);
            colormap(app.UIAxes_Vrs, jet);
            c.Label.String = app.PThdr{app.I.T};
            app.UIAxes_Vrs.FontSize = 12;
            title(app.UIAxes_Vrs, tstr,'Interpreter','none')
            xlabel(app.UIAxes_Vrs, '')
            ylabel(app.UIAxes_Vrs, Y_Label)

            hold(app.UIAxes_Vrs,'on')
            app.hVMinLine = xline(app.UIAxes_Vrs, min(app.UIAxes_Vrs.XLim),'k--');
            app.hVMaxLine = xline(app.UIAxes_Vrs, max(app.UIAxes_Vrs.XLim),'k--');
            hold(app.UIAxes_Vrs,'off')

            innerPosDiff = InnerPos - app.UIAxes_Vrs.InnerPosition;
            app.UIAxes_Vrs.Position = app.UIAxes_Vrs.Position + innerPosDiff;

            % *********************************************************
            % MIDDLE PLOT -- VK
            selectedButton = app.raw_VkButtonGroup.SelectedObject;
            if strcmp(selectedButton.Text,'volts')
                Y_Vk    = app.PTdata(tg_raw, app.I.VK);
                Y_Label = app.PThdr{app.I.VK};
                yscale  = 3;
            elseif strcmp(selectedButton.Text,'std volts')
                if isempty(app.I.VKS)
                    Y_Vk    = app.PTdata(tg_raw, app.I.VK)*0;
                    Y_Label = 'No std VK data available';
                else
                    Y_Vk    = app.PTdata(tg_raw, app.I.VKS);
                    Y_Label = app.PThdr{app.I.VKS}; 
                end
                yscale  = 4;
            end
            y_std = std(Y_Vk,'omitnan');
            y_lim = [-y_std y_std]*yscale + median(Y_Vk,'omitnan');

            % Check y_lim values. SBS PT data has std Vrs & std Vk = all 0
            % JP 11/22/22 to suck in SBS raw data
            if diff(y_lim) == 0
                yy = y_lim;
                y_lim = [yy(1)-1, yy(1)+1];
                clear yy
            end

            app.UIAxes_Vk.Box = 'On';
            axInnerPos = app.UIAxes_Vk.InnerPosition;

            scatter(app.UIAxes_Vk, X, Y_Vk, 9, app.PTdata(tg_raw, app.I.P),'filled')
            %caxis(app.UIAxes_Vk,[min(app.PTdata(tg_raw, app.I.P)) max(app.PTdata(tg_raw, app.I.P))]);
            clim(app.UIAxes_Vk,[min(app.PTdata(tg_raw, app.I.P)) max(app.PTdata(tg_raw, app.I.P))]);
            c2 = colorbar(app.UIAxes_Vk);
            colormap(app.UIAxes_Vk, jet);
            c2.Label.String = app.PThdr{app.I.P};
            app.UIAxes_Vk.FontSize = 12;

            xlabel(app.UIAxes_Vk, '')
            ylabel(app.UIAxes_Vk, Y_Label)
            xlim(app.UIAxes_Vk, x_lim);
            ylim(app.UIAxes_Vk, y_lim);
            innerPosDiff = axInnerPos - app.UIAxes_Vk.InnerPosition;
            app.UIAxes_Vk.Position = app.UIAxes_Vk.Position + innerPosDiff;


            % *********************************************************
            % BOTTOM PLOT Ik & Ib
            cla(app.UIAxes_IbIk);
            app.UIAxes_IbIk.Box = 'On';
            axInnerPos = app.UIAxes_IbIk.InnerPosition;

            tmp = [app.PTdata(tg_raw, app.I.IK)*1e9; app.PTdata(tg_raw, app.I.IB)*1e9];
            y_lim  = [fix(min(tmp,[],'omitnan')), ceil(max(tmp,[],'omitnan'))];
            y_tick = round(linspace(y_lim(1), y_lim(2), 4));

            plot(app.UIAxes_IbIk, X, app.PTdata(tg_raw, app.I.IK)*1e9,'bo','MarkerSize',3)
            xlim(app.UIAxes_IbIk, x_lim);
            xlabel(app.UIAxes_IbIk, '')

            ylabel(app.UIAxes_IbIk, 'Ik and Ib, nano amps')
            hold(app.UIAxes_IbIk,'on')
            plot(app.UIAxes_IbIk, X, app.PTdata(tg_raw, app.I.IB)*1e9,'ro','MarkerSize',3)
            hold(app.UIAxes_IbIk,'off')
            legend(app.UIAxes_IbIk,'Ik','Ib')
            app.UIAxes_IbIk.YTick = y_tick;
            app.UIAxes_IbIk.YLim = y_lim;

            innerPosDiff = axInnerPos - app.UIAxes_IbIk.InnerPosition;
            app.UIAxes_IbIk.Position = app.UIAxes_IbIk.Position + innerPosDiff;


        end

        % ******* UPDATE K2 TAB ***************
        function update_k2_tab(app)

            % FILL RESULTS TABLE WITH RESULTS SUMMARY
            %app.info.PTfn
            removeStyle(app.UITable_results); % Clear any existing styles
            app.UITable_results.FontSize = 14;

            tmp = app.k2_data.Results; % DF serial number
            tmp = [tmp(1:3,:);...
                {'MSC #:' app.info.MSC ''};...
                tmp(4:end,:)];

            % IF phlog needs filling add warning line
            if isfield(app.info,'pHlog_warn_msg')
                tmp = [{'Sensor SN not in pH log file!!!!','', ''}; tmp];
            end

            tmpk0 = app.k0_data;
            if ~isfield(tmpk0,'Results')
                app.UITable_results.Data = tmp;
            else
                app.UITable_results.Data = [tmp; {'' '' ''}; ...
                    tmpk0.Results];
            end


            %             % DEFINE COLOR STYLE FOR OUT OF RANGE TABLE DATA
            %             s1 = uistyle;
            %             s1.BackgroundColor = 'red';
            %             s1.FontWeight = 'bold';
            %
            %             % PT CHAMBER AVG STD Vk CHECK [80 uV]
            %             iX = find(strcmp(tmp(:,1), 'Avg std Vk') == 1);
            %             if app.k2_data.avg_std_Vk * 1e6 > 80 % uVolts
            %                 addStyle(app.UITable_results,s1,'cell',[iX,2])
            %             end
            %
            %             % PT CHAMBER VRS DRIFT [-0.1 0.2] mV/day
            %             iX = find(strcmp(tmp(:,1), 'Vrs drift rate:') == 1);
            %             Vrs_Drift = app.k2_data.Vrs_Drift(1)*1000;
            %             if Vrs_Drift< -0.1 || Vrs_Drift >0.2
            %                 addStyle(app.UITable_results,s1,'cell',[iX,2])
            %             end
            %
            % IF SBE STEM NO DETAILED K2 DATA SO END function
            if app.info.tf_SBE_stem == 1
                disp('hello I think this is an SBE stem')
                return % stop here, don't do any plotting if SBE stem
            end


            % UPDATE PLOTS
            tg_k2 = app.tPT_SDN & app.tPdir;
            tstr  = {app.PTinfo.SourceDir, app.PTinfo.SourceFile};

            % TOP PLOT VRS DRIFT
            tDrift = app.k2_data.tDrift;
            app.k2_VrsDrift.Box = 'On';
            scatter(app.k2_VrsDrift, app.PTtime(tDrift), app.PTdata(tDrift, app.I.VRS), ...
                9, app.PTdata(tDrift, app.I.VK),'filled')
            xlim(app.k2_VrsDrift, datetime(app.info.LSDN_lim,'ConvertFrom','datenum'));
            %caxis(app.k2_VrsDrift, [min(app.PTdata(tDrift, app.I.VK)) max(app.PTdata(tDrift, app.I.VK))]);
            c = colorbar(app.k2_VrsDrift);
            colormap(app.k2_VrsDrift, jet);
            c.Label.String = app.PThdr{app.I.VK};
            %c.AxisLocation = 'in';
            app.k2_VrsDrift.FontSize = 12;
            title(app.k2_VrsDrift, tstr,'Interpreter','none')
            %xlabel(app.k2_VrsDrift, '')
            %ylabel(app.k2_VrsDrift, app.PThdr{app.I.VRS})
            hold(app.k2_VrsDrift,'on')
            X = app.PTtime(tg_k2);
            Y = app.PTdata(tg_k2,app.I.LSDN)*app.k2_data.Vrs_Drift(1) + app.k2_data.Vrs_Drift(2);
            plot(app.k2_VrsDrift, X, Y, 'k--')

            hold(app.k2_VrsDrift,'off')

            % DRIFT CORRECTED VRS
            app.k2_VrsCorr.Box = 'On';
            scatter(app.k2_VrsCorr, app.PTtime(tg_k2), app.k2_data.Vrs_Dcor(tg_k2), 9, app.PTdata(tg_k2, app.I.T),'filled')
            xlim(app.k2_VrsCorr, datetime(app.info.LSDN_lim,'ConvertFrom','datenum'));
            clim(app.k2_VrsCorr, [min(app.PTdata(tg_k2, app.I.T)) max(app.PTdata(tg_k2, app.I.T))]);
            c = colorbar(app.k2_VrsCorr);
            colormap(app.k2_VrsCorr, jet);
            c.Label.String = app.PThdr{app.I.T};
            %c.AxisLocation = 'in';
            app.k2_VrsCorr.FontSize = 12;
            %title(app.k2_VrsVc_vs_T, app.info.PTfn,'Interpreter','none')
            %xlabel(app.k2_VrsVc_vs_T, '')
            %ylabel(app.k2_VrsDrift, app.PThdr{app.I.VRS})

            % Vrs_vC vs T
            app.k2_VrsVc_vs_T.Box = 'On';
            axInnerPos = app.k2_VrsVc_vs_T.InnerPosition;
            scatter(app.k2_VrsVc_vs_T, app.PTdata(tg_k2,app.I.T), app.k2_data.Vrs_Vc(tg_k2), 9, app.PTdata(tg_k2, app.I.P),'filled')
            %xlim(app.k2_VrsVc_vs_T, datetime(app.info.LSDN_lim,'ConvertFrom','datenum'));
            clim(app.k2_VrsVc_vs_T, [min(app.PTdata(tg_k2, app.I.P)) max(app.PTdata(tg_k2, app.I.P))]);
            innerPosDiff = axInnerPos - app.k2_VrsVc_vs_T.InnerPosition;
            axOuterPos   = app.k2_VrsVc_vs_T.Position + innerPosDiff;
            app.k2_VrsVc_vs_T.Position = axOuterPos;
            axInnerPos = app.k2_VrsVc_vs_T.InnerPosition;
            c = colorbar(app.k2_VrsVc_vs_T);
            innerPosDiff = axInnerPos - app.k2_VrsVc_vs_T.InnerPosition;
            axOuterPos   = app.k2_VrsVc_vs_T.Position + innerPosDiff;
            app.k2_VrsVc_vs_T.Position = axOuterPos;

            %             c.Position(1) = c.Position(1)*1.10;
            disp(c.Position)
            disp(c.Units)
            colormap(app.k2_VrsVc_vs_T, jet);
            %c.Label.String = app.PThdr{app.I.P};
            %c.AxisLocation = 'in';
            app.k2_VrsVc_vs_T.FontSize = 12;
            %hold(app.k2_VrsVc_vs_T,'off')


            % k2 vs P
            if ~isempty(app.k2_data.BinK2_data)
                app.k2_P_vs_k2.Box = 'On';
                %axInnerPos = app.k2_P_vs_k2.InnerPosition;
                plot(app.k2_P_vs_k2, app.k2_data.BinK2_data(:,2), app.k2_data.BinK2_data(:,1), 'ko')
                %xlim(app.k2_VrsVc_vs_T, datetime(app.info.LSDN_lim,'ConvertFrom','datenum'));
                app.k2_P_vs_k2.YDir = 'Reverse';
                %app.k2_P_vs_k2.YLim = [min(app.k2_data.BinK2_data(:,1)) max(app.k2_data.BinK2_data(:,1))];
                app.k2_P_vs_k2.YLim = [0 app.k2_SurfZoom_Slider.Value];


                k2PolyOrder =app.k2fP_polyEdit.Value; % current k2f(P) ppoly order
                t1 =  app.k2_data.k2_opt.data(:,1) == k2PolyOrder;
                tstr = {app.k2_data.k2_opt.tstr, sprintf('BIC = %0.1f  Range = %0.0fuV/degC', ...
                    app.k2_data.k2_opt.data(t1,3),app.k2_data.k2_opt.range*1e6)};
                
                %title(app.k2_P_vs_k2, app.k2_data.k2_opt.tstr)
                title(app.k2_P_vs_k2, tstr)

                hold(app.k2_P_vs_k2, 'on');

                Xtmp = polyval(app.k2_data.k2_Pcoefs, app.k2_data.BinK2_data(:,1));

                %             Xtmp = app.k2_data.dk2dP(1) .* app.k2_P_vs_k2.YLim + ...
                %                 app.k2_data.dk2dP(2);

                plot(app.k2_P_vs_k2, Xtmp, app.k2_data.BinK2_data(:,1), 'r--')
                hold(app.k2_P_vs_k2, 'off');
                %c.AxisLocation = 'in';
                app.k2_P_vs_k2.FontSize = 12;
                %title(app.k2_VrsVc_vs_T, app.info.PTfn,'Interpreter','none')
                %xlabel(app.k2_VrsVc_vs_T, '')
                %ylabel(app.k2_VrsDrift, app.PThdr{app.I.VRS})
                innerPosDiff = app.k2_VrsVc_vs_T.InnerPosition - app.k2_P_vs_k2.InnerPosition;
                app.k2_P_vs_k2.Position(2:4) = app.k2_P_vs_k2.Position(2:4) + innerPosDiff(2:4);
            end

        end



        % ******* UPDATE PCOEF TAB ***************
        function update_Pcoef_tab(app)

            if isfield(app.info,'LP') % hide Pdir legend
                app.info.LP.Visible = 'off';
            end


            tg_fp = app.tPT_SDN & app.tPdir; % defined by k2 tab choice
            tstr  = {app.PTinfo.SourceDir, app.PTinfo.SourceFile};
            time_flag = 0;

            % f(P) sorted
            PS = sort(app.PTdata(tg_fp,app.I.P)); % sorted for poly line pl;ot
            if PS(1) > 0 % 11/22/22 JP and some value to 0 to check surf poly behavior
                PS = [(0:5:PS(1))';PS];
            end
            PX = polyval(app.k2_data.Pcoefs, PS); % fsorted (P) poly fit
             
            X  = app.k2_data.Vrs_Vc_k2T(tg_fp) - polyval(app.k2_data.Pcoefs, ...
                app.PTdata(tg_fp,app.I.P)); % f(P) fit anomaly - not sorted

            selectedButton = app.Pcoefs_CAxisButtonGroup.SelectedObject;

            if ~strcmp(selectedButton.Text,'Direction')
                if strcmp(selectedButton.Text,'Temperature')
                    Z = app.PTdata(tg_fp, app.I.T);
                    cb_label = 'Temperature';
                elseif strcmp(selectedButton.Text,'Time')
                    Z = app.PTdata(tg_fp, app.I.LSDN);
                    cb_label = 'Time';
                    time_flag = 1;
                elseif strcmp(selectedButton.Text,'Vk')
                    Z = app.PTdata(tg_fp, app.I.VK);
                    cb_label = 'Vk';
                end


                % ********************************************************
                % PCOEF PLOT
                app.Pcoefs_FvsP.Box = 'On';
                axInnerPos = app.Pcoefs_FvsP.InnerPosition;
                scatter(app.Pcoefs_FvsP, app.k2_data.Vrs_Vc_k2T(tg_fp),  ...
                    app.PTdata(tg_fp,app.I.P), 9, Z,'filled')
                app.Pcoefs_FvsP.YDir = 'Reverse';

                % P  = app.PTdata(tg_fp,app.I.P); % TESTING
                % fP = app.k2_data.Vrs_Vc_k2T(tg_fp);
                % save('C:\temp\fP_play.mat','P','fP')

                %app.Pcoefs_FvsP.YLim = [0 max(app.PTdata(tg_fp,app.I.P),[],'omitnan')];
                app.Pcoefs_FvsP.YLim = [0 app.fP_SurfZoom_Slider.Value];

                clim(app.Pcoefs_FvsP, [min(Z) max(Z)]);

                app.info.CBP = colorbar(app.Pcoefs_FvsP);
                colormap(app.Pcoefs_FvsP, jet);
                app.info.CBP.Label.String = cb_label;

                app.Pcoefs_FvsP.FontSize = 12;
                if time_flag == 1
                    app.info.CBP.TickLabels = datestr(app.info.CBP.Ticks,'mm/dd');
                end

                title(app.Pcoefs_FvsP,tstr, 'Interpreter','none');
                hold(app.Pcoefs_FvsP,'on')

                % P = sort(app.PTdata(tg_fp,app.I.P));
                % if P(1) > 0 % 11/22/22 JP and some value to 0 to check surf poly behavior
                %     P = [(0:5:P(1))';P];
                % end
                % X = polyval(app.k2_data.Pcoefs, P);

                %                 plot(app.Pcoefs_FvsP, app.k2_data.BinPcoef_data(:,2), ...
                %                     app.k2_data.BinPcoef_data(:,1), 'ro',...
                %                     'MarkerFaceColor','r')

                plot(app.Pcoefs_FvsP, PX,  PS, 'k-','LineWidth',2)

                hold(app.Pcoefs_FvsP,'off')

                innerPosDiff = axInnerPos - app.Pcoefs_FvsP.InnerPosition;
                axOuterPos   = app.Pcoefs_FvsP.Position + innerPosDiff;
                app.Pcoefs_FvsP.Position = axOuterPos;

                % ********************************************************
                % PCOEF ANOM PLOT
                app.Pcoefs_FvsP_anom.Box = 'On';
                axInnerPos = app.Pcoefs_FvsP_anom.InnerPosition;

                % X = app.k2_data.Vrs_Vc_k2T(tg_fp) - polyval(app.k2_data.Pcoefs, ...
                %     app.PTdata(tg_fp,app.I.P));
                scatter(app.Pcoefs_FvsP_anom, X*1e6,  app.PTdata(tg_fp,app.I.P), 9, Z,'filled')
                app.Pcoefs_FvsP_anom.YDir = 'Reverse';
                %app.Pcoefs_FvsP_anom.YLim = [0 max(app.PTdata(tg_fp,app.I.P),[],'omitnan')];
                app.Pcoefs_FvsP_anom.YLim = [0 app.fP_SurfZoom_Slider.Value];

                clim(app.Pcoefs_FvsP_anom, [min(Z) max(Z)]);
                %title(app.Pcoefs_FvsP_anom,{' ',' '});
                % title(app.Pcoefs_FvsP_anom, app.k2_data.fP_opt.tstr);

                % ADD STATS INFO TO AXIS TITLE
                fPPolyOrder =app.fP_polyEdit.Value; % current k2f(P) poly order
                t1 =  app.k2_data.fP_opt.data(:,1) == fPPolyOrder;
                tstr = {app.k2_data.fP_opt.tstr, ...
                    sprintf('BIC = %0.1f  f(P) range= %0.1fmV   std anom = %0.0fuV', ...
                    app.k2_data.fP_opt.data(t1,3), app.k2_data.fP_opt.range*1e3, ...
                    std(X*1e6))};
                title(app.Pcoefs_FvsP_anom, tstr);

                app.info.CBPA  = colorbar(app.Pcoefs_FvsP_anom);
                colormap(app.Pcoefs_FvsP_anom, jet);
                app.info.CBPA.Label.String = cb_label;

                app.Pcoefs_FvsP_anom.FontSize = 12;
                if time_flag == 1
                    app.info.CBPA.TickLabels = datestr(app.info.CBPA.Ticks,'mm/dd');
                end
                innerPosDiff = axInnerPos - app.Pcoefs_FvsP_anom.InnerPosition;
                axOuterPos   = app.Pcoefs_FvsP_anom.Position + innerPosDiff;
                app.Pcoefs_FvsP_anom.Position = axOuterPos;

            else    % COLOR BY DIRECTION & NO COLOR BAR OR SCATTER PLOT
                P  = app.PTdata(:,app.I.P);
                X1 = app.k2_data.Vrs_Vc_k2T; % f(P)
                X2 = app.k2_data.Vrs_Vc_k2T - polyval(app.k2_data.Pcoefs, ...
                    app.PTdata(:,app.I.P)); % f(P) anom
                X2 = X2 * 1e6;
                tDOWN = app.Pdir > 0 & tg_fp;
                tUP   = app.Pdir < 0 & tg_fp;
                tSTOP = app.Pdir == 0 & tg_fp;
                dir_colors = [204,0,0;0,0,204;0,153,0]/256; %red, blue, orange

                Lstr = {};
                if sum(tDOWN) > 0
                    plot(app.Pcoefs_FvsP, X1(tDOWN),  P(tDOWN), 'o', ...
                        'MarkerEdgeColor',dir_colors(1,:),'MarkerSize',3)
                    hold(app.Pcoefs_FvsP,'on');
                    plot(app.Pcoefs_FvsP_anom, X2(tDOWN),  P(tDOWN), 'o', ...
                        'MarkerEdgeColor',dir_colors(1,:),'MarkerSize',3)
                    hold(app.Pcoefs_FvsP_anom,'on');
                    Lstr = [Lstr,'P increasing'];
                end
                if sum(tUP) > 0
                    plot(app.Pcoefs_FvsP, X1(tUP),  P(tUP), 'o', ...
                        'MarkerEdgeColor',dir_colors(2,:),'MarkerSize',3)
                    hold(app.Pcoefs_FvsP,'on');
                    plot(app.Pcoefs_FvsP_anom, X2(tUP),  P(tUP), 'o', ...
                        'MarkerEdgeColor',dir_colors(2,:),'MarkerSize',3)
                    hold(app.Pcoefs_FvsP_anom,'on');
                    Lstr = [Lstr,'P decreasing'];
                end
                if sum(tSTOP) > 0
                    plot(app.Pcoefs_FvsP, X1(tSTOP),  P(tSTOP), 'o', ...
                        'MarkerEdgeColor',dir_colors(3,:),'MarkerSize',3)
                    hold(app.Pcoefs_FvsP,'on')
                    plot(app.Pcoefs_FvsP_anom, X2(tSTOP),  P(tSTOP), 'o', ...
                        'MarkerEdgeColor',dir_colors(3,:),'MarkerSize',3)
                    hold(app.Pcoefs_FvsP_anom,'on')
                    Lstr = [Lstr,'P Stationary'];
                end

                % ADD POLY FIT TO PCOEF
                % PP = sort(app.PTdata(tg_fp,app.I.P));
                % if PP(1) > 0 % 11/22/22 JP and some value to 0 to check surf poly behavior
                %     PP = [(0:5:PP(1))';PP];
                % end

                %XX = polyval(app.k2_data.Pcoefs, PP);
                plot(app.Pcoefs_FvsP, PX,  PS, 'Color',[0 255 255]/256, 'LineWidth',3)
                Lstr = [Lstr,'Polyfit'];

                % ADD STATS INFO TO AXIS TITLE
                fPPolyOrder =app.fP_polyEdit.Value; % current k2f(P) poly order
                t1 =  app.k2_data.fP_opt.data(:,1) == fPPolyOrder;
                tstr = {app.k2_data.fP_opt.tstr, ...
                    sprintf('BIC = %0.1f  f(P) range= %0.1fmV   std anom = %0.0fuV', ...
                    app.k2_data.fP_opt.data(t1,3), app.k2_data.fP_opt.range*1e3, ...
                    std(X*1e6))};
                title(app.Pcoefs_FvsP_anom, tstr);

                % FINISH PLOTS
                hold(app.Pcoefs_FvsP,'off');
                app.Pcoefs_FvsP.Box = 'On';
                app.Pcoefs_FvsP.YDir = 'Reverse';
                app.Pcoefs_FvsP.YLim = [0 app.fP_SurfZoom_Slider.Value];
                title(app.Pcoefs_FvsP,tstr, 'Interpreter','none');
                app.info.CBP.Visible = 'off';
                app.info.LP =legend(app.Pcoefs_FvsP,Lstr,'Location','SouthEast');
                app.info.LP.FontSize = 12;

                hold(app.Pcoefs_FvsP_anom,'off');
                app.Pcoefs_FvsP_anom.Box = 'On';
                app.Pcoefs_FvsP_anom.YDir = 'Reverse';
                app.Pcoefs_FvsP_anom.YLim = [0 app.fP_SurfZoom_Slider.Value];
                app.info.CBPA.Visible = 'off';

            end

        end

        % ************************************************************
        %         UPDATE KO SEAWATER CALIBRATION DATA
        % ************************************************************
        function update_k0_tab(app)
            tg_k0 = app.tk0raw_SDN;
            tON   = app.tk0raw_ON;

            %app.color_pH.TimeOffset

            % THIS USES AN AVG K2 VALUE FROM PRESSURE BINNED DATA .BINNING
            % IS UNEVEN AND FOLLOWS SAMPLING SCHEME SO AVG IS WEIGHTED
            % TOWARDS SURFACE VALUES A BIT
            d = calc_phcal_k0(app.k0raw_data, app.k0raw_hdr, app.k0raw_info,...
                tg_k0 , tON, app.k2_data.avg_k2, app.color_pH.data, ...
                app.color_pH.TimeOffset, app.color_pH.FitOrder);

            % THIS USES THE C0 COEFFICIENT FROM THE POLYNOMIAL FIT OF K2 VS
            % PRES. C0 IS K0 AT PRES=0
            d = calc_phcal_k0(app.k0raw_data, app.k0raw_hdr, app.k0raw_info,...
                tg_k0 , tON, app.k2_data.k2_Pcoefs(end), app.color_pH.data, ...
                app.color_pH.TimeOffset, app.color_pH.FitOrder);


            %             d.avg_k0_pON     = [mean(k0(tONtg)), std(k0(tONtg))];
            %             d.avg_k0_pOFF    = [mean(k0(~tONtg)), std(k0(~tONtg))];
            %             d.k0_data        = k0data;
            %             d.tON            = tON;
            %             d.tk0            = tg;
            %             d.k0_cal_win     = [min(k0data(tg,I.SDN)), max(k0data(tg,I.SDN))];
            %             d.C_pH           = color_pH;
            %             d.fit_order      = fit_order;
            %             d.coef_C_pH      = pp;
            %
            %             d.int_C_pH20(tg) = pHT20;
            %             d.int_C_pH(tg)   = pHT;
            %             d.k0(tg)         = k0;

            app.k0_data   = d;


            % PREP
            X_C_pH  = datetime(d.C_pH(:,1),'ConvertFrom','datenum');
            k0_time = datetime(d.k0_data(:,app.I2.SDN),'ConvertFrom','datenum');
            k0_xlim = datetime(app.info.k0SDN_lim,'ConvertFrom','datenum');
            %datestr(app.info.k0SDN_lim)


            % TOP PLOT pH
            app.UIAxes_k0_pH.Box = 'On';
            axInnerPos = app.UIAxes_k0_pH.InnerPosition;
            p1 = plot(app.UIAxes_k0_pH, X_C_pH, d.C_pH(:,2),'o', ...
                'MarkerfaceColor',[0 102 0]/256, 'MarkerEdgeColor','k');
            xlim(app.UIAxes_k0_pH, k0_xlim);
            tstr = {d.SourceDir, sprintf('pump ON = %s    and    pump OFF = %s',...
                d.pONfile,d.pOFFfile)};
            title(app.UIAxes_k0_pH, tstr, 'Interpreter', 'none');
            xlabel(app.UIAxes_k0_pH, '')
            ylabel(app.UIAxes_k0_pH, 'pH Total')
            app.UIAxes_k0_pH.FontSize = 12;

            hold(app.UIAxes_k0_pH,'on')
            %             p2 = plot(app.UIAxes_k0_pH, k0_time, d.int_C_pH20,'-',...
            %                 'Color',[0 102 0]/256);
            %             p3 = plot(app.UIAxes_k0_pH, k0_time, d.int_C_pH,'b-');
            p2 = plot(app.UIAxes_k0_pH, k0_time(d.tk0), d.int_C_pH20(d.tk0),'-',...
                'Color',[0 102 0]/256);
            p3 = plot(app.UIAxes_k0_pH, k0_time(d.tk0), d.int_C_pH(d.tk0),'b-');

            app.hVMinLine_k0 = xline(app.UIAxes_k0_pH, min(app.UIAxes_k0_pH.XLim),'k--');
            app.hVMaxLine_k0 = xline(app.UIAxes_k0_pH, max(app.UIAxes_k0_pH.XLim),'k--');
            hold(app.UIAxes_k0_pH,'off')
            legend(app.UIAxes_k0_pH,'Color 20C','interp color 20C', ...
                'interp color in situ T','Location','NorthWest')
            innerPosDiff = axInnerPos - app.UIAxes_k0_pH.InnerPosition;
            app.UIAxes_k0_pH.Position = app.UIAxes_k0_pH.Position + innerPosDiff;


            % Middle PLOT k0
            % CHOOSE BETWEEN k0 & k0 - k0(1)
            k0X_ON  = d.k0(d.tk0 & d.tON);
            k0X_OFF = d.k0(d.tk0 & ~d.tON);
            selectedButton = app.k0_k0YaxisButtonGroup.SelectedObject;
            if strcmp(selectedButton.Text,'k0 - median(k0)')
                k0X_ON  = (k0X_ON - median(k0X_ON,'omitnan'))*1e6;
                k0X_OFF = (k0X_OFF - median(k0X_OFF,'omitnan'))*1e6;
                ylabel(app.UIAxes_k0_k0, 'k0 - median(k0), uV')
            else
                ylabel(app.UIAxes_k0_k0, 'k0, Volts')
            end

            app.UIAxes_k0_k0.Box = 'On';
            axInnerPos = app.UIAxes_k0_k0.InnerPosition;
            plot(app.UIAxes_k0_k0, k0_time(d.tk0&d.tON), k0X_ON, 'r-')
            xlim(app.UIAxes_k0_k0, k0_xlim);
            xlabel(app.UIAxes_k0_k0, '')
            app.UIAxes_k0_k0.FontSize = 12;

            hold(app.UIAxes_k0_k0,'on')
            plot(app.UIAxes_k0_k0, k0_time(d.tk0&~d.tON), k0X_OFF, 'b-')

            hold(app.UIAxes_k0_k0,'off')
            legend(app.UIAxes_k0_k0,'Pump ON','Pump OFF')
            innerPosDiff = axInnerPos - app.UIAxes_k0_k0.InnerPosition;
            app.UIAxes_k0_k0.Position = app.UIAxes_k0_k0.Position + innerPosDiff;



            % BOTTOM PLOT Vk, std Vk or Temperature
            selectedButton = app.k0_YaxisButtonGroup.SelectedObject;
            %selectedButton.Text
            if strcmp(selectedButton.Text,'Vk')
                Y_ON  = d.k0_data((d.tk0&d.tON), app.I2.VK);
                Y_OFF = d.k0_data((d.tk0&~d.tON), app.I2.VK);
                Y_Label = app.k0raw_hdr{app.I2.VK};
                yscale  = 3;
                y_std  = std([Y_ON;Y_OFF],'omitnan');
                y_lim  = [-y_std y_std]*yscale + median([Y_ON;Y_OFF],'omitnan');
                y_tick = linspace(y_lim(1), y_lim(2),4);

            elseif strcmp(selectedButton.Text,'std Vk')
                Y_ON  = d.k0_data((d.tk0&d.tON), app.I2.VKS)*1e6;
                Y_OFF = d.k0_data((d.tk0&~d.tON), app.I2.VKS)*1e6;
                Y_Label = 'std Vk, uVolts';
                yscale  = 4;
                y_std  = std([Y_ON;Y_OFF],'omitnan');
                y_lim  = [0, y_std*yscale + median([Y_ON;Y_OFF],'omitnan')];
                y_tick = round(linspace(y_lim(1), y_lim(2),4),0);

            elseif strcmp(selectedButton.Text,'Temperature')
                Y_ON  = d.k0_data((d.tk0&d.tON), app.I2.T);
                Y_OFF = d.k0_data((d.tk0&~d.tON), app.I2.T);
                Y_Label = app.k0raw_hdr{app.I2.T};
                yscale  = 3;
                y_std  = std([Y_ON;Y_OFF],'omitnan');
                y_lim  = [-y_std y_std]*yscale + median([Y_ON;Y_OFF],'omitnan');
                y_tick = linspace(y_lim(1), y_lim(2),4);

            end

            app.UIAxes_k0_Vk.Box = 'On';
            axInnerPos = app.UIAxes_k0_Vk.InnerPosition;
            plot(app.UIAxes_k0_Vk, k0_time(d.tk0&d.tON), Y_ON, 'r.')

            xlim(app.UIAxes_k0_Vk, k0_xlim);
            ylim(app.UIAxes_k0_Vk, y_lim);
            app.UIAxes_k0_Vk.YTick = y_tick;
            xlabel(app.UIAxes_k0_Vk, '')
            ylabel(app.UIAxes_k0_Vk, Y_Label)
            app.UIAxes_k0_Vk.FontSize = 12;

            hold(app.UIAxes_k0_Vk,'on')
            plot(app.UIAxes_k0_Vk, k0_time(d.tk0&~d.tON), Y_OFF, 'b.')

            hold(app.UIAxes_k0_Vk,'off')
            legend(app.UIAxes_k0_Vk,'Pump ON','Pump OFF')
            innerPosDiff = axInnerPos - app.UIAxes_k0_Vk.InnerPosition;
            app.UIAxes_k0_Vk.Position = app.UIAxes_k0_Vk.Position + innerPosDiff;

            update_k2_tab(app)
            update_summary_tab(app)

        end


        % *****************************************************************
        % INTITIALIZE SETTINGS & CLEAR VARIABLES WHEN A NEW SENSOR IS
        % LOADED
        function  new_sensor_init(app)
            % DISABLE KO TAB FILE OPEN UNTIL FILE RESOLVED
            app.Choose_k0file_Button.Enable = 'off';
            app.Choose_k0file_Button.Text = 'NO k0 sea water file available';
            app.allButton.Value = true; % reset to "all" if opening 2nd file

            % RESET DATA & AXES FO k0 tab
            arrayfun(@cla,findall(app.k0_tab,'type','axes'))
            title(app.UIAxes_k0_pH, '');

            % TURN ON BUTTON GROUPS
            app.PTrawSubset_ButtonGroup.Visible = 'on';
            app.raw_VrsButtonGroup.Visible      = 'on';
            app.raw_VkButtonGroup.Visible       = 'on';
            app.Pcoefs_CAxisButtonGroup.Visible = 'on';
            app.MaxSlider.Visible     = 'on';
            app.MinSlider.Visible     = 'on';
            app.fP_polyEdit.Visible   = 'on';
            app.k2fP_polyEdit.Visible = 'on';
            app.fP_SurfZoom_Slider.Visible     = 'on';
            app.k2_SurfZoom_Slider.Visible     = 'on';


            % RESET KO DATA
            app.k0_data = struct;
            app.k0raw_data = struct;
            app.info.k0_tf = 0;

            app.k0raw_hdr  = {};
            app.tk0raw_SDN = [];
            app.I2    = struct;   % Initialize k0 sw index structure
            %if isfield(app.color_pH,'data')

            app.info.k0_cal_win   = [datenum(0,0,0),datenum(0,0,0)];
            app.info.k0_fit_order = [];
            app.info.avg_k0_pON   = [NaN NaN];
            app.info.avg_k0_pOFF  = [NaN NaN];
            app.info.avg_Vk       = [];
            app.info.avg_std_Vk   = [];

            app.info.avg_Vk_pON   = [];
            app.info.avg_Vk_pOFF  = [];
            app.info.avg_std_Vk_pON   = [];
            app.info.avg_std_Vk_pOFF  = [];

            app.info.MSC = '---';
            app.info.tf_SBE_stem = 0;
            app.fP_polyEdit.Value = 6;
            app.k2fP_polyEdit.Value = 0;
            app.info.sbe_warn_msg ={}; % predim for SBE pdf file inconsitancy

            if isfield(app.info,'pHlog_warn_msg')
                app.info = rmfield(app.info, 'pHlog_warn_msg');
            end

            if isfield(app.info,'sbe_warn_msg')
                app.info = rmfield(app.info, 'sbe_warn_msg');
            end
            
            % Clear summary bars on histograms
            app.summary.k2stats.YData = [1 1]* NaN;
            app.summary.k0stats.YData = [1 1]* NaN;
            app.summary.k2_hist.XData = [NaN NaN];
            app.summary.k0_hist.XData = [NaN NaN];
            app.summary.k0OnOff_hist.XData = [1 1]* NaN;
            app.summary.k0OnHCl_hist.XData = [1 1]* NaN;

        end


        % *******************************
        function summary_tab_init(app)
            % PLOT all baseline pH cal data in summary tab
            % *******************
            % PLOT all k2's
            X      = app.MSC_list.flt_ct;

            app.UIAxes_k2stats.Box = 'On';
            ck2    = size(app.MSC_list.k2,2); % num of cols
            L_cell = cell(size(app.MSC_list.uSV));
            for i = 1: size(app.MSC_list.uSV,1)
                t1 = fix(app.MSC_list.SV) == app.MSC_list.uSV(i);
                Y = app.MSC_list.k2(t1,ck2);
                sum_color = app.MSC_list.colors(i,:);
                plot(app.UIAxes_k2stats, X(t1), Y, 'ko', ...
                    'MarkerFaceColor',sum_color);
                if i == 1
                    hold(app.UIAxes_k2stats,'on');
                end
                if app.MSC_list.uSV(i) == 0 % SBE STEM
                    L_cell{i} = 'SBE';
                elseif app.MSC_list.uSV(i) == 7 % GDF
                    L_cell{i} = 'GDF';
                elseif app.MSC_list.uSV(i) == 8 % GDF
                    L_cell{i} = 'AE GDF';
                else
                    L_cell{i} = sprintf('V %0.0f',app.MSC_list.uSV(i));
                end
            end
            app.summary.k2stats = plot(app.UIAxes_k2stats, ...
                app.UIAxes_k2stats.XLim, [NaN NaN],...
                'k--','LineWidth',3); % placeholder for cal data

            hold(app.UIAxes_k2stats,'off');
            legend(app.UIAxes_k2stats,L_cell,'Location','EastOutside')


            % ********************
            % PLOT all k0's
            app.UIAxes_k0stats.Box = 'On';
            L_cell = cell(size(app.MSC_list.uSV));
            for i = 1: size(app.MSC_list.uSV,1)
                t1 = fix(app.MSC_list.SV) == app.MSC_list.uSV(i);
                Y = app.MSC_list.k0_ON(t1);
                sum_color = app.MSC_list.colors(i,:);
                plot(app.UIAxes_k0stats, X(t1), Y, 'ko', ...
                    'MarkerFaceColor',sum_color);
                if i == 1
                    hold(app.UIAxes_k0stats,'on');
                end
                if app.MSC_list.uSV(i) == 0 % SBE STEM
                    L_cell{i} = 'SBE';
                elseif app.MSC_list.uSV(i) == 7 % GDF
                    L_cell{i} = 'GDF';
                else
                    L_cell{i} = sprintf('V %0.0f',app.MSC_list.uSV(i));
                end
            end

            app.summary.k0stats = plot(app.UIAxes_k0stats, ...
                app.UIAxes_k0stats.XLim, [NaN NaN],...
                'k--','LineWidth',3); % placeholder for cal data

            hold(app.UIAxes_k0stats,'off');
            legend(app.UIAxes_k0stats,L_cell,'Location','EastOutside')

            axpos_k2 = app.UIAxes_k2stats.InnerPosition;
            axpos_k0 = app.UIAxes_k0stats.InnerPosition;
            app.UIAxes_k0stats.InnerPosition = [axpos_k2(1),axpos_k0(2), ...
                axpos_k2(3), axpos_k0(4)];

            % ********************
            % PLOT Histgrams

            % *****************
            X     = app.MSC_list.k2(:,ck2); % K2
            Xmean = mean(X,1,'omitnan');
            Xstd  = std(X,[],1,'omitnan');
            edges = linspace(Xmean-4*Xstd, Xmean+4*Xstd, 30);
            app.UIAxes_k2_hist.Box = 'On';
            h = histogram(app.UIAxes_k2_hist, X, edges);
            h.FaceColor = [153 204 255]/256;
            h.EdgeColor = [192 192 192]/256;
            h.LineWidth = 0.5;

            hold(app.UIAxes_k2_hist,'on');
            app.summary.k2_hist = plot(app.UIAxes_k2_hist, ...
                [NaN NaN],app.UIAxes_k2_hist.YLim,...
                'k--','LineWidth',3); % placeholder for cal data
            hold(app.UIAxes_k2_hist,'off');

            % *****************
            X     = app.MSC_list.k0_ON; % K0 pON
            Xmean = mean(X,1,'omitnan');
            Xstd  = std(X,[],1,'omitnan');
            edges = linspace(Xmean-4*Xstd, Xmean+4*Xstd, 30);
            app.UIAxes_k0_hist.Box = 'On';
            h = histogram(app.UIAxes_k0_hist, X, edges);
            h.FaceColor = [153 204 255]/256;
            h.EdgeColor = [192 192 192]/256;
            h.LineWidth = 0.5;

            hold(app.UIAxes_k0_hist,'on');
            app.summary.k0_hist = plot(app.UIAxes_k0_hist, ...
                [NaN NaN], app.UIAxes_k0_hist.YLim,...
                'k--','LineWidth',3); % placeholder for cal data        
            hold(app.UIAxes_k0_hist,'off');

            % *****************
            X     = app.MSC_list.k0_ON - app.MSC_list.k0_OFF; % K0 pON - K0 pON
            Xmean = mean(X,1,'omitnan');
            Xstd  = std(X,[],1,'omitnan');
            edges = linspace(Xmean-4*Xstd, Xmean+4*Xstd, 30);
            app.UIAxes_k0OnOff_hist.Box = 'On';
            h = histogram(app.UIAxes_k0OnOff_hist, X, edges);
            h.FaceColor = [153 204 255]/256;
            h.EdgeColor = [192 192 192]/256;
            h.LineWidth = 0.5;

            hold(app.UIAxes_k0OnOff_hist,'on');
            app.summary.k0OnOff_hist = plot(app.UIAxes_k0OnOff_hist, ...
                [NaN NaN], app.UIAxes_k0OnOff_hist.YLim,...
                'k--','LineWidth',3); % placeholder for cal data           
            hold(app.UIAxes_k0OnOff_hist,'off');

            % *****************
            X     = app.MSC_list.k0_ON - app.MSC_list.k0_HCL; % K0 pON - K0 HCl
            Xmean = mean(X,1,'omitnan');
            Xstd  = std(X,[],1,'omitnan');
            edges = linspace(Xmean-4*Xstd, Xmean+4*Xstd, 30);
            app.UIAxes_k0OnHCl_hist.Box = 'On';
            h = histogram(app.UIAxes_k0OnHCl_hist, X, edges);
            h.FaceColor = [153 204 255]/256;
            h.EdgeColor = [192 192 192]/256;
            h.LineWidth = 0.5;

            hold(app.UIAxes_k0OnHCl_hist,'on');
            app.summary.k0OnHCl_hist = plot(app.UIAxes_k0OnHCl_hist, ...
                [NaN NaN],app.UIAxes_k0OnHCl_hist.YLim,...
                'k--','LineWidth',3); % placeholder for cal data        
            hold(app.UIAxes_k0OnHCl_hist,'off');

            % ********************
            % Plot background f(P)
            P = app.MSC_list.P;
            app.UIAxes_fPstats.Box = 'On';
            VERs  = [0 6 7 8]; % SBE Ver6 GDF AE GDF
            Lcell = {'SBE' 'V6' 'GDF' 'AE GDF'};
            for i = 1: size(VERs,2)
                %colr = app.MSC_list.colors(i*2+1,:);
                colr = app.MSC_list.colors(VERs(i)+1,:);
                %colr = app.MSC_list.colors( VERs(i)+1,:);
                t1   = fix(app.MSC_list.SV) == VERs(i);
                X    = app.MSC_list.FP(t1,:);
                mX   = median(X,1,'omitnan')';
                sX   = std(X,[],1,'omitnan')';
                fillX  = [[mX-1*sX;flipud(mX+1*sX)],[P';flipud(P')]];
                p(i) = plot(app.UIAxes_fPstats, mX, P', '-', ...
                    'Color', colr, 'LineWidth',2);
                if i == 1
                    app.UIAxes_fPstats.YDir = 'Reverse';
                    hold(app.UIAxes_fPstats,'on');
                end
                FX = patch(app.UIAxes_fPstats, fillX(:,1), fillX(:,2), colr);
                FX.FaceAlpha = 0.2';
                FX.LineStyle = 'none';

            end

            app.summary.fPstats = plot(app.UIAxes_fPstats, ...
                P'*NaN, P', 'k--','LineWidth',3); % placeholder for cal data


            hold(app.UIAxes_fPstats,'off');
            legend(p, Lcell,'NumColumns',3','Location','NorthOutside')


            % ***************************************
            % init summary Text area text
            app.TextArea_summary.Value = {'No summary calibration data to report!'};
            app.TextArea_summary.FontSize = 14;
            app.TextArea_summary.Editable = 'off';
            app.TextArea_summary.FontName = 'Courier'; % use nor proportional font to keep spacing nice
        end


        % *************************************************************
        function update_summary_tab(app)
            % Update calibration data for all summary plots by accessing
            % stored plot handels
            
            % UPDATE K2 PT CHAMBER DATA RESULTS
            app.summary.k2stats.YData = [1 1]* app.k2_data.avg_k2;
            
            app.summary.k2_hist.XData = [1 1]* app.k2_data.avg_k2;
            app.summary.k2_hist.YData = app.UIAxes_k2_hist.YLim;

            pp = app.k2_data.Pcoefs;
            if app.info.tf_SBE_stem == 0
                pp(end) = 0;
            elseif app.info.tf_SBE_stem == 1
                pp = [pp,0];
            end
                
            P = app.MSC_list.P;
            app.summary.fPstats.XData = polyval(pp,P);


            % UPDATE k0 DATA RESULTS IF IT EXISTS
            if app.info.k0_tf == 1 % K0 data have been loaded into GUI
                % app.k0_data
                 app.summary.k0stats.YData = [1 1]* app.k0_data.avg_k0_pON(1);
                 
                 app.summary.k0_hist.XData = [1 1]* app.k0_data.avg_k0_pON(1);
                 app.summary.k0_hist.YData = app.UIAxes_k0_hist.YLim;
                
                k0_ON_OFF = app.k0_data.avg_k0_pON(1) - app.k0_data.avg_k0_pOFF(1);
                 app.summary.k0OnOff_hist.XData = [1 1]* k0_ON_OFF;
                 app.summary.k0OnOff_hist.YData = app.UIAxes_k0OnOff_hist.YLim;

                k0_ON_HCL = app.k0_data.avg_k0_pON(1) - app.k2_data.k0_HCL;
                 app.summary.k0OnHCl_hist.XData = [1 1]* k0_ON_HCL;
                 app.summary.k0OnHCl_hist.YData = app.UIAxes_k0OnHCl_hist.YLim;

            end
            
            % UPDATE TEXT AREA WITH SOME SUMMARY RESULTS
%             jp = app.info;
%             save('C:\temp\GUItest.mat','jp') % TESTING
            

            TXT{1} = sprintf('%-s','CALIBRATION SUMMARY');
            TXT{2} = sprintf('%-20s%-10s','Serial Number:',app.k2_data.DF_SN);
            TXT{3} = sprintf('%-20s%-10s','Sensor type:',app.k2_data.DF_TYPE);
            TXT{4} = sprintf('%-20s%-10s','PT source file:',app.k2_data.SourceFile);
            TXT{5} = sprintf('%-20s%-10s','Data subset:', ...
                app.PTrawSubset_ButtonGroup.SelectedObject.Text);
            
            TXT{6} = sprintf('%-20s%-10.5e','Average k2:',app.k2_data.avg_k2);
            TXT{7} = sprintf('%-20s%-10.5e','k2 @ P=0 (c0):',app.k2_data.k2_Pcoefs(end));
            
            app.info.k0_tf
            
            if app.info.k0_tf == 1
                TXT{8} = sprintf('%-20s\t',' ');
                TXT{9} = sprintf('%-20s%-10s','MSC:',app.k0_data.MSC);
                TXT{10} = sprintf('%-20s%-10s','k0 pump ON file:',app.k0_data.pONfile);
                TXT{11} = sprintf('%-20s%-10s','k0 pump OFF file:',app.k0_data.pOFFfile);
                TXT{12} = sprintf('%-20s%-10.5f','Average k0 pON:',app.k0_data.avg_k0_pON(1));
                TXT{13} = sprintf('%-20s%-10.5f','Average k0 pOFF:',app.k0_data.avg_k0_pOFF(1));
                TXT{14} = sprintf('%-20s%-10.5f','k0 HCL:',app.k2_data.k0_HCL);
                TXT{15} = sprintf('%-20s   ',' ');
                TXT{16} = sprintf('%-20s%-10.5f','k0, pON-pOFF:',k0_ON_OFF);
                TXT{17} = sprintf('%-20s%-10.5f','k0, pON- HCL:',k0_ON_HCL);
            end
            app.TextArea_summary.Value = TXT;

        end
    end


    % Callbacks that handle component events
    methods (Access = private)

        % Code that executes after component creation
        function startupFcn(app)



            % ACTUAL WORKING DIRS ON CHEM
            %             app.dirs.MBARI_PT = '\\thalassa\chem\DuraFET\PTchamber\RawData\';
            %             app.dirs.SBE_PT   = '\\thalassa\chem\DuraFET\PTchamber\SBE stems f(P) cal sheets\';
            %             app.dirs.k0SW = '\\thalassa\chem\DuraFET\K0 for DSD Stems\';
            %             app.dirs.k0SW_discrete_pH = '\\thalassa\chem\DuraFET\K0 for DSD Stems\SpecpH_data\';
            %             UserProfile = getenv('USERPROFILE'); % returns ie 'C:\Users\jplant'
            %             app.dirs.save = [UserProfile,'\Documents\MATLAB\Apps\pH_Calibration\test data\'];

            if ispc
                app.dirs.MBARI_PT         = '\\thalassa\chem\DuraFET\CALIBRATION\K2_PTChamber_data\';
                app.dirs.SBE_PT           = '\\thalassa\chem\DuraFET\CALIBRATION\K2_SBE_CalSheets\';
                app.dirs.k0SW             = '\\thalassa\chem\DuraFET\CALIBRATION\K0_seawater_data\';
                app.dirs.k0SW_discrete_pH = '\\thalassa\chem\DuraFET\CALIBRATION\SpecpH_data\';
                UserProfile = userpath; % returns ie 'C:\Users\jplant'
                app.dirs.save = fullfile(UserProfile,'Apps\pH_Calibration\Apps\pH_Calibration\test data');

            elseif ismac
                app.dirs.MBARI_PT         = '/Volumes/Chem/DuraFET/CALIBRATION/K2_PTChamber_data/';
                app.dirs.SBE_PT           = '/Volumes/Chem/DuraFET/CALIBRATION/K2_SBE_CalSheets/';
                app.dirs.k0SW             = '/Volumes/chem/DuraFET/CALIBRATION/K0_seawater_data/';
                app.dirs.k0SW_discrete_pH = '/Volumes/chem/DuraFET/CALIBRATION/SpecpH_data/';
                UserProfile = userpath; % returns ie ''/Users/jmetter/Documents/MATLAB'
                app.dirs.save = fullfile(UserProfile,'Apps/pH_Calibration/test data/');
            end

            app.MinSlider.MajorTickLabels = {};
            app.MinSlider.MajorTicks =[];
            app.MinSlider.MinorTicks =[];
            app.SliderLabel.Text = 'Min';

            app.MaxSlider.MajorTickLabels = {};
            app.MaxSlider.MajorTicks =[];
            app.MaxSlider.MinorTicks =[];
            app.Slider_2Label.Text   = 'Max';
            app.UITable_results.ColumnName = {};
            app.UITable_results.ColumnEditable = [];
            app.UITable_results.ColumnWidth = '1x';


            % GET PH version info from log files
            %app.MSC_list = get_ph_version(); % build pH version matrix
            app.MSC_list = get_ph_cal_stats();
            summary_tab_init(app) % plot all call data as background


            app.Choose_k0file_Button.Enable = 'off';
            app.color_pH.TimeOffset = 7; % hours
            app.color_pH.FitOrder   = 1;

            app.fP_SurfZoom_Slider.MajorTickLabels = {};
            app.fP_SurfZoom_Slider.MajorTicks =[];
            app.fP_SurfZoom_Slider.MinorTicks =[];

            app.k2_SurfZoom_Slider.MajorTickLabels = {};
            app.k2_SurfZoom_Slider.MajorTicks =[];
            app.k2_SurfZoom_Slider.MinorTicks =[];


        end

        % Button pushed function: Choose_PTfile_Button
        function Choose_PTfile_ButtonPushed(app, event)
      

            dp = fullfile(app.dirs.MBARI_PT);
            wp = pwd;
            cd(dp);
            [fn,path] = uigetfile({'*.csv'; '*.pdf';'*.docx'}, ...
                'Choose k2 Press chamber file or SBE k2 cal file');
            cd(wp);
            clear dp wp
            if ~isequal(fn,0)
                new_sensor_init(app) % helper function to clear / reset things

                if regexp(path,'K2_SBE_PTChamber_data','once')
                    app.info.FileType = 'SBE raw';
                elseif ~isempty(regexp(fn,'csv$','once'))
                    app.info.FileType = 'MBARI';
                elseif ~isempty(regexp(fn,'pdf$|docx$','once'))
                    app.info.FileType = 'SBE'; % partial cal file with k2 & f(p) only
                else
                    app.info.FileType = 'UNKNOWN';
                end

                app.info.PTfn    = fn;
                app.info.PTpath  = path;
                app.info.SBS_multi_chan  = 0;
                if strcmp(app.info.FileType,'SBE raw') && ~isempty(regexp(fn,'SN\d+','once'))
                    fprintf(['This appears to be a multi channel SBS PT ',...
                        'file. The SN can not be determined from the file name!\n']);
                    app.info.SBS_multi_chan  = 1;
                    app.info.DF_SN ='?';

                elseif strcmp(app.info.FileType,'MBARI') || strcmp(app.info.FileType,'SBE raw')
                    app.info.DF_SN = regexp(fn,'(?<=DF\#)\d+|(?<=DF)\d+','once','match');
                    if isempty(app.info.DF_SN) % MBARI RECAL OF SEB STEM? TRY diff pattern
                        app.info.DF_SN = regexp(fn,'(?<=[SBE\s*]*)C*\d+','once','match');
                    end
                elseif strcmp(app.info.FileType,'SBE')
                    app.info.DF_SN = regexp(fn,'(?<=[SBE\s*]*)C*\d+','once','match');
                end

                % REMOVE LEADING 0 in SN if it exists
                app.info.DF_SN = regexprep(app.info.DF_SN,'^0','');

                t1  = strcmp(app.MSC_list.SN, app.info.DF_SN);

                if sum(t1) == 1 && app.info.SBS_multi_chan == 0

                    app.info.MSC = sprintf('%04.0f',app.MSC_list.MSC(t1));
                    app.info.APEX_ID = sprintf('%0.0f',app.MSC_list.UW(t1));

                    if strncmp(app.MSC_list.VNOTES{t1},'SBE',3) && ...
                            strcmp(app.info.FileType,'SBE')
                        app.info.tf_SBE_stem = 1;
                    elseif strcmp(app.info.FileType,'SBE')
                        app.info.sbe_warn_msg ={...
                            ['WARNING: pdf or docx file suggests SBE ', ...
                            'stem, but the pH log file does not indicate this!'], ...
                            'Does the log file need updating?', ...
                            'Asumming this is a SBE stem for now'};
                        app.info.tf_SBE_stem = 1;
                    end

                elseif sum(t1) == 0 && app.info.SBS_multi_chan == 0 % NO DF SN FOUND!!!
                    fprintf(['WARNING: Sensor SN %s was not found in ', ...
                        'pHlog.xlsx. PLEASE UPDATE LOG FILE!\n'], app.info.DF_SN);
                    tstr = sprintf('PLEASE UPDATE pHlog.xlsx!');
                    msg = {sprintf(['WARNING: Sensor SN %s was not found in ',...
                        'pHlog.xlsx'], app.info.DF_SN),...
                        'MSC & APEX ID can not be identified', ...
                        'Continue anyway?'};
                    uialert(app.UIFigure, msg, tstr)
                    app.info.pHlog_warn_msg = 'SN not found in pHlog file';

                    app.info.MSC     = 'XXXX';
                    app.info.APEX_ID = 'XXXX';
                end

                clear iSN iMSC tmp t1

%                 % CHECK for k0 FILES
%                 if ~strcmp(app.info.MSC,'---') 
%                     %k0fn_pattern  = ['MSC',app.info.MSC,'*DURA*.dat'];
%                     k0fn_pattern  = ['MSC',app.info.MSC,'*DURA.dat'];
%                     k0fn_pattern2 = regexprep(k0fn_pattern,'.dat','.csv');
% 
%                     if ~isempty(ls([app.dirs.k0SW, k0fn_pattern]))
%                         app.Choose_k0file_Button.Text = 'Choose k0 sea water file';
%                         app.Choose_k0file_Button.Enable = 'on';
%                         app.info.k0fn_pattern = k0fn_pattern;
%                     elseif ~isempty(ls([app.dirs.k0SW, k0fn_pattern2]))
%                         app.Choose_k0file_Button.Text = 'Choose k0 sea water file';
%                         app.Choose_k0file_Button.Enable = 'on';
%                         app.info.k0fn_pattern = k0fn_pattern2;
%                     end
%                 end


                % PARSE PT DATA FILE & GET INDICES
                if app.info.tf_SBE_stem == 0 || strcmp(app.info.FileType,'SBE raw')
                    tmp = parse_PTchamber_file(fullfile(path, fn));
%                     save('C:\temp\pH_GUI_test.mat','tmp') % testing
%                     tmp.info % testing
                    app.PThdr = tmp.hdr;

                    % *****************************************
                    % need to get SN & MSC here for multi channel - a
                    % repeat code block - could be cleaner
                    if app.info.SBS_multi_chan  == 1 % need to get SN & MSC here for multi channel
                        app.info.DF_SN = tmp.info.DF_SN;
                        t1  = strcmp(app.MSC_list.SN, app.info.DF_SN);
                        if sum(t1) == 1
                            app.info.MSC = sprintf('%04.0f',app.MSC_list.MSC(t1));
                            app.info.APEX_ID = sprintf('%0.0f',app.MSC_list.UW(t1));

                            if strncmp(app.MSC_list.VNOTES{t1},'SBE',3) && ...
                                    strcmp(app.info.FileType,'SBE')
                                app.info.tf_SBE_stem = 1;
                            elseif strcmp(app.info.FileType,'SBE')
                                app.info.sbe_warn_msg ={...
                                    ['WARNING: pdf or docx file suggests SBE ', ...
                                    'stem, but the pH log file does not indicate this!'], ...
                                    'Does the log file need updating?', ...
                                    'Asumming this is a SBE stem for now'};
                                app.info.tf_SBE_stem = 1;
                            end
                        elseif sum(t1) == 0  % NO DF SN FOUND! IN pHlog file!!
                            fprintf(['WARNING: Sensor SN %s was not found in ', ...
                                'pHlog.xlsx. PLEASE UPDATE LOG FILE!\n'], app.info.DF_SN);
                            tstr = sprintf('PLEASE UPDATE pHlog.xlsx!');
                            msg = {sprintf(['WARNING: Sensor SN %s was not found in ',...
                                'pHlog.xlsx'], app.info.DF_SN),...
                                'MSC & APEX ID can not be identified', ...
                                'Continue anyway?'};
                            uialert(app.UIFigure, msg, tstr)
                            app.info.pHlog_warn_msg = 'SN not found in pHlog file';

                            app.info.MSC     = 'XXXX';
                            app.info.APEX_ID = 'XXXX';
                        end
                    end

                    % column indices for PT data
                    if tmp.info.tf_MultiChan == 0 % single channel files
                        app.I.LSDN = find(strcmp(app.PThdr,'Labview Date/Time') == 1);
                        app.I.T    = find(strcmp(app.PThdr,'Thermistor Temp') == 1);
                        app.I.P    = find(strcmp(app.PThdr,'Pressure (dBar)') == 1);
                        app.I.VRS  = find(strcmp(app.PThdr,'VRS VOLTS') == 1);
                        app.I.VRSS = find(strcmp(app.PThdr,'VRS STDDEV') == 1);
                        app.I.VK   = find(strcmp(app.PThdr,'VK VOLTS') == 1);
                        app.I.VKS  = find(strcmp(app.PThdr,'VK STDDEV') == 1);
                        app.I.IK   = find(strcmp(app.PThdr,'IK AMPS') == 1);
                        app.I.IB   = find(strcmp(app.PThdr,'IB AMPS') == 1);
                    elseif tmp.info.tf_MultiChan == 1 && app.info.SBS_multi_chan  == 1
                        app.I.LSDN = find(strcmp(app.PThdr,'Date') == 1);
                        if ~isempty(regexp('ABC',tmp.info.DF_CH,'once'))
                            app.I.T    = find(strcmp(app.PThdr,'SBE38 1') == 1);
                        elseif ~isempty(regexp('DEF',tmp.info.DF_CH,'once'))
                            app.I.T    = find(strcmp(app.PThdr,'SBE38 2') == 1);
                        elseif ~isempty(regexp('GHJ',tmp.info.DF_CH,'once'))
                            app.I.T    = find(strcmp(app.PThdr,'SBE38 3') == 1);
                        end
                        app.I.P    = find(strcmp(app.PThdr,'SBE50') == 1);
                        app.I.VRS  = find(strcmp(app.PThdr,'Vrs') == 1);
                        app.I.VRSS = find(strcmp(app.PThdr,'VRS STDDEV') == 1);
                        app.I.VK   = find(strcmp(app.PThdr,'Vk') == 1);
                        app.I.VKS  = find(strcmp(app.PThdr,'VK STDDEV') == 1);
                        app.I.IK   = find(strcmp(app.PThdr,'Ik') == 1);
                        app.I.IB   = find(strcmp(app.PThdr,'Ib') == 1);
                    end

                    % FILTER P/T DATA BASED ON RATE OF CHANGE OF T -
                    % ONLY KEEP STABLE T DATA
                    max_dT   = 0.003; %deg C /dayslider
                    %max_dT   = 0.1; %deg C /dayslider TESTING
                    dT       = diff(tmp.data(:, app.I.T));
                    tT       = logical([0; abs(dT) <= max_dT]);
                    tmp.data = tmp.data(tT,:);
                    clear dT tT max_dT

                    % Store raw data in app
                    app.PTdata   = tmp.data;
                    app.PTinfo   = tmp.info;
                    app.tPT_SDN  = true(size(app.PTdata,1),1); % predim all

                    app.PTtime = datetime(app.PTdata(:,app.I.LSDN),'ConvertFrom','datenum');
                    app.Pdir  = [0;diff(app.PTdata(:,app.I.P))]; % positive is descending
                    app.tPdir = true(size(app.PTdata,1),1); % predim all

                    % SET SLIDERS
                    app.MinSlider.Limits = [min(app.PTdata(:,app.I.LSDN)), max(app.PTdata(:,app.I.LSDN))];
                    app.MinSlider.Value  = app.MinSlider.Limits(1);

                    app.MaxSlider.Limits = app.MinSlider.Limits;
                    app.MaxSlider.Value  = app.MaxSlider.Limits(2);

                    app.fP_SurfZoom_Slider.Limits = [0, max(app.PTdata(app.tPdir & app.tPT_SDN, app.I.P))];
                    app.fP_SurfZoom_Slider.Value = app.fP_SurfZoom_Slider.Limits(2);
                    app.fP_SurfZoom_Slider.MajorTicks = ...
                        fix(linspace(0, fix(app.fP_SurfZoom_Slider.Limits(2)),4));
                    app.fP_SurfZoom_Slider.MajorTickLabels = ...
                        cellstr(num2str(app.fP_SurfZoom_Slider.MajorTicks'));

                    app.k2_SurfZoom_Slider.Limits = [0, max(app.PTdata(app.tPdir & app.tPT_SDN, app.I.P))];
                    app.k2_SurfZoom_Slider.Value = app.k2_SurfZoom_Slider.Limits(2);
                    app.k2_SurfZoom_Slider.MajorTicks = ...
                        fix(linspace(0, fix(app.k2_SurfZoom_Slider.Limits(2)),4));
                    app.k2_SurfZoom_Slider.MajorTickLabels = ...
                        cellstr(num2str(app.k2_SurfZoom_Slider.MajorTicks'));



                    app.info.LSDN_lim    =[app.MinSlider.Value, app.MaxSlider.Value];


                    update_raw_PT_tab(app)
                    app.k2_data = calc_phcal_k2(app.PTdata, app.PThdr, app.PTinfo, ...
                        app.tPT_SDN, app.tPdir, app.fP_polyEdit.Value, ...
                        app.k2fP_polyEdit.Value);
                    update_k2_tab(app)
                    update_Pcoef_tab(app)
                    update_summary_tab(app)

                elseif app.info.tf_SBE_stem == 1 % from SBE  - no detailed data

                    % CLEAR EXISTING PT RAW AXES INCASE REPOPENING FILE
                    arrayfun(@cla,findall(app.UIAxes_Vrs,'type','axes'));
                    arrayfun(@cla,findall(app.UIAxes_Vk,'type','axes'));
                    arrayfun(@cla,findall(app.UIAxes_IbIk,'type','axes'));
                    title(app.UIAxes_Vrs, '');

                    % CLEAR EXISTING K2 AXES INCASE REPOPENING FILE
                    arrayfun(@cla,findall(app.k2_VrsDrift,'type','axes'));
                    arrayfun(@cla,findall(app.k2_VrsCorr,'type','axes'));
                    arrayfun(@cla,findall(app.k2_VrsVc_vs_T,'type','axes'));
                    arrayfun(@cla,findall(app.k2_P_vs_k2,'type','axes'));
                    title(app.k2_VrsDrift, '');

                    % CLEAR EXISTING PCOEF AXES INCASE REPOPENING FILE
                    arrayfun(@cla,findall(app.Pcoefs_FvsP,'type','axes'))
                    arrayfun(@cla,findall(app.Pcoefs_FvsP_anom,'type','axes'))
                    title(app.Pcoefs_FvsP, '');

                    % hide GUI components that can't be used
                    app.PTrawSubset_ButtonGroup.Visible = 'off';
                    app.raw_VrsButtonGroup.Visible      = 'off';
                    app.raw_VkButtonGroup.Visible       = 'off';
                    app.Pcoefs_CAxisButtonGroup.Visible = 'off';
                    app.MaxSlider.Visible               = 'off';
                    app.MinSlider.Visible               = 'off';
                    app.fP_polyEdit.Visible             = 'off';
                    app.k2fP_polyEdit.Visible           = 'off';

                    app.k2_data = get_SBE_k2stem_cal(fullfile(path, fn));

                    app.PTinfo.SourceDir  = app.k2_data.SourceDir;
                    app.PTinfo.SourceFile = app.k2_data.SourceFile;
                    app.PTinfo.DF_SN      = app.k2_data.DF_SN;

                    % ADD WARNING TEXT THAT THIS A SBE STEM
                    txt1 = {['An SBE pH Stem Calibration file has ', ...
                        'been loaded'], 'NO DETAILED PT DATA!', ...
                        fullfile(app.PTinfo.SourceDir, app.PTinfo.SourceFile)};
                    disp(txt1)
                    x_lim = xlim(app.UIAxes_Vrs);
                    y_lim = ylim(app.UIAxes_Vrs);
                    app.info.PT_TXT = text(app.UIAxes_Vrs, ...
                        x_lim(1) + diff(x_lim)/2, y_lim(1) + diff(y_lim)/2,...
                        txt1,'Color','r', 'FontSize',16, ...
                        'HorizontalAlignment','center','Interpreter','none');

                    update_k2_tab(app)
                    update_summary_tab(app)

                end

                % CHECK for k0 FILES
                if ~strcmp(app.info.MSC,'---')
                    %k0fn_pattern  = ['MSC',app.info.MSC,'*DURA*.dat'];
                    k0fn_pattern  = ['MSC',app.info.MSC,'*DURA.dat'];
                    k0fn_pattern2 = regexprep(k0fn_pattern,'.dat','.csv');


                    chk_k0_fns = dir(fullfile(app.dirs.k0SW, k0fn_pattern));
                    if isempty(chk_k0_fns)
                        fprintf('No k0 files detected at %s\n',fullfile(app.dirs.k0SW, k0fn_pattern))
                        if contains(k0fn_pattern,'XXXX') 
                            fprintf('No MSC has been detected!\n')
                        end
                    elseif ~isempty(ls(fullfile(app.dirs.k0SW, k0fn_pattern)))
                        app.Choose_k0file_Button.Text = 'Choose k0 sea water file';
                        app.Choose_k0file_Button.Enable = 'on';
                        app.info.k0fn_pattern = k0fn_pattern;
                    elseif ~isempty(ls(fullfile(app.dirs.k0SW, k0fn_pattern2)))
                        app.Choose_k0file_Button.Text = 'Choose k0 sea water file';
                        app.Choose_k0file_Button.Enable = 'on';
                        app.info.k0fn_pattern = k0fn_pattern2;
                    end
                end

                figure(app.UIFigure); % bring app figure to foreground
                if isfield(app.info,'sbe_warn_msg') % SBE pdf file inconsistancy warning
                    warndlg(app.info.sbe_warn_msg);
                end

            end
        end

        % Value changed function: MinSlider
        function MinSliderValueChanged(app, event)
            %value = app.MinSlider.Value;
            NewMinValue = event.Value;
            if NewMinValue >= app.MaxSlider.Value % min can't be >  than max
                use_diff =  app.MaxSlider.Value - app.MinSlider.Limits(1);
                app.MinSlider.Value = app.MinSlider.Limits(1) + use_diff*0.95;
            end
            app.tPT_SDN = app.PTdata(:,app.I.LSDN) >= app.MinSlider.Value & ...
                app.PTdata(:,app.I.LSDN) <= app.MaxSlider.Value;

            app.MinSlider.MajorTicks =min(app.PTdata(app.tPT_SDN, app.I.LSDN));
            app.MinSlider.MajorTickLabels = {datestr(app.MinSlider.MajorTicks,'mmm dd HH:MM')};

            app.info.LSDN_lim(1)    = app.MinSlider.Value;

            %hold(app.UIAxes_Vrs,'off')
            update_raw_PT_tab(app)

            jp1 = app.PTdata;
            jp2 = app.tPT_SDN;
            jp3 = app.tPdir;
            save('C:\temp\ph_gui_test.mat','jp1','jp2','jp3');

            app.k2_data = calc_phcal_k2(app.PTdata, app.PThdr, app.PTinfo, ...
                app.tPT_SDN, app.tPdir, app.fP_polyEdit.Value, ...
                app.k2fP_polyEdit.Value);
            update_k2_tab(app)
            update_Pcoef_tab(app)

            if ~isempty(app.k0raw_hdr)
                update_k0_tab(app)
            end
            
            update_summary_tab(app)

            %             if isfield(app.color_pH,'data')
            %                 update_k0_tab(app)
            %             end
        end

        % Value changed function: MaxSlider
        function MaxSliderValueChanged(app, event)
            %value = app.MaxSlider.Value;
            NewMaxValue = event.Value;
            if NewMaxValue  <= app.MinSlider.Value  % max can't be <  than min
                use_diff =  app.MaxSlider.Limits(2) - app.MinSlider.Value;
                app.MaxSlider.Value = app.MaxSlider.Limits(2) - use_diff*0.95;
            end

            app.tPT_SDN = app.PTdata(:,app.I.LSDN) >= app.MinSlider.Value & ...
                app.PTdata(:,app.I.LSDN) <= app.MaxSlider.Value;

            app.MaxSlider.MajorTicks =max(app.PTdata(app.tPT_SDN, app.I.LSDN));
            app.MaxSlider.MajorTickLabels = {datestr(app.MaxSlider.MajorTicks,'mmm dd HH:MM')};

            app.info.LSDN_lim(2)    = app.MaxSlider.Value;

            update_raw_PT_tab(app)
            app.k2_data = calc_phcal_k2(app.PTdata, app.PThdr, app.PTinfo, ...
                app.tPT_SDN, app.tPdir, app.fP_polyEdit.Value, ...
                app.k2fP_polyEdit.Value);
            update_k2_tab(app)
            update_Pcoef_tab(app)

            if ~isempty(app.k0raw_hdr)
                update_k0_tab(app)
            end
            
            update_summary_tab(app)


            %             if isfield(app.color_pH,'data')
            %                 update_k0_tab(app)
            %             end

        end

        % Value changing function: MinSlider
        function MinSliderValueChanging(app, event)

            app.MinSlider.MajorTicks = event.Value;
            app.MinSlider.MajorTickLabels = {datestr(app.MinSlider.MajorTicks,'mmm dd HH:MM')};
            app.hVMinLine.Value = datetime(event.Value,'ConvertFrom','datenum');

        end

        % Value changing function: MaxSlider
        function MaxSliderValueChanging(app, event)

            app.MaxSlider.MajorTicks = event.Value;
            app.MaxSlider.MajorTickLabels = {datestr(app.MaxSlider.MajorTicks,'mmm dd HH:MM')};
            app.hVMaxLine.Value = datetime(event.Value,'ConvertFrom','datenum');

        end

        % Selection changed function: PTrawSubset_ButtonGroup
        function PTrawSubset_ButtonGroupSelectionChanged(app, event)
            selectedButton = app.PTrawSubset_ButtonGroup.SelectedObject;
            if strcmp(selectedButton.Text,'all')
                app.tPdir = true(size(app.PTdata,1),1);
            elseif strcmp(selectedButton.Text,'P increasing')
                app.tPdir = app.Pdir > 0;
            elseif strcmp(selectedButton.Text,'P decreasing')
                app.tPdir = app.Pdir < 0;
            elseif strcmp(selectedButton.Text,'P stationary')
                app.tPdir = app.Pdir == 0;
            end

            % UPDATE Surf zoom slider limits based on data subsetselection
            SurfZoomMax = max(app.PTdata(app.tPdir & app.tPT_SDN, app.I.P));
            if SurfZoomMax == 0
                SurfZoomMax = 50;
            end
            if app.fP_SurfZoom_Slider.Value > SurfZoomMax
                app.fP_SurfZoom_Slider.Value = SurfZoomMax;
            end
            app.fP_SurfZoom_Slider.Limits(2) = SurfZoomMax;
            app.fP_SurfZoom_Slider.MajorTicks = ...
                fix(linspace(0, fix(app.fP_SurfZoom_Slider.Limits(2)),4));
            app.fP_SurfZoom_Slider.MajorTickLabels = ...
                cellstr(num2str(app.fP_SurfZoom_Slider.MajorTicks'));


            if app.k2_SurfZoom_Slider.Value > SurfZoomMax
                app.k2_SurfZoom_Slider.Value = SurfZoomMax;
            end
            app.k2_SurfZoom_Slider.Limits(2) = SurfZoomMax;
            app.k2_SurfZoom_Slider.MajorTicks = ...
                fix(linspace(0, fix(app.k2_SurfZoom_Slider.Limits(2)),4));
            app.k2_SurfZoom_Slider.MajorTickLabels = ...
                cellstr(num2str(app.k2_SurfZoom_Slider.MajorTicks'));


            update_raw_PT_tab(app)
            app.k2_data = calc_phcal_k2(app.PTdata, app.PThdr, app.PTinfo, ...
                app.tPT_SDN, app.tPdir, app.fP_polyEdit.Value, ...
                app.k2fP_polyEdit.Value);
            update_k2_tab(app)
            update_Pcoef_tab(app)

            %             if isfield(app.color_pH,'data')
            %                 update_k0_tab(app)
            %             end

            if app.info.k0_tf == 1 && isfield(app.color_pH,'data')
                update_k0_tab(app)
            end
            
            update_summary_tab(app)

            app.info.k0_tf = 0;

        end

        % Value changed function: fP_polyEdit
        function fP_polyEditValueChanged(app, event)
            %value = app.fP_polyEdit.Value;
            app.k2_data = calc_phcal_k2(app.PTdata, app.PThdr, app.PTinfo, ...
                app.tPT_SDN, app.tPdir, app.fP_polyEdit.Value, ...
                app.k2fP_polyEdit.Value);
            app.UITable_results.Data = app.k2_data.Results;
            update_Pcoef_tab(app)
            
            update_summary_tab(app)

        end

        % Selection changed function: Pcoefs_CAxisButtonGroup
        function Pcoefs_CAxisButtonGroupSelectionChanged(app, event)
            update_Pcoef_tab(app)

        end

        % Button pushed function: Choose_k0file_Button
        function Choose_k0file_ButtonPushed(app, event)
            %             k0_pwd = pwd;
            %             cd(app.dirs.k0SW)
            %             [k0fn, k0path] = uigetfile(app.info.k0fn_pattern, ...
            %                 'Choose k0 sea water file');

            % THIS GETS BOTH FLAVORS OF P ON *.DAT FILES!!!! & SHOULD MAKE
            % WARNINGS UN NEEDED BUT LEAVE 'EM IN FOR NOW
            [k0fn, k0path] = uigetfile({[app.info.k0fn_pattern,';', ...
                regexprep(app.info.k0fn_pattern,'DURA','DURA *')]}, ...
                'Choose k0 sea water file',fullfile(app.dirs.k0SW));

            %             cd(k0_pwd)
            if ~isequal(k0fn,0)

                % IF PUMP OFF ('*_2" ACCIDENTALLY CHOOSEN CONVERT BACK TO
                % PUMP ON FILE NAME
                tf_warn = 0;
                if regexp(k0fn,'\_2','once')
                    str1 = ['Pump ON FILE WAS CHOOSEN: ',k0fn];
                    str2 =   'CHOICE SHOULD BE A PUMP OFF FILE!';
                    str3 = 'CONVERTING CHOICE TO PUMP OFF FILE NAME!';
                    fprintf('%s\n%s\n%s\n',str1,str2,str3);
                    k0fn = regexprep(k0fn,'_2','');
                    tf_warn = 1;
                    warn_cell = {str1,str2, str3};
                    %f = warndlg({str1,str2});
                end

                app.info.k0fn    = k0fn;
                app.info.k0path  = k0path;

                % GET PUMP ON & OFF DATA FILES & MERGE
                d = parse_k0_SW_file(fullfile(k0path, k0fn)); % PUMP OFF FILE
                app.k0raw_hdr  = d.hdr;
                pOFF = d.data;

                % GET PUMP ON DATA
                d = parse_k0_SW_file(fullfile(k0path,regexprep(k0fn,'DURA','DURA_2')));
                pON = d.data;

                % THIS BLOCK USED TO HELP REPORT GENERATION
                app.k0raw_info.MSC = app.info.MSC;
                app.k0raw_info.SourceDir = fullfile(app.info.k0path);
                app.k0raw_info.pOFFfile = app.info.k0fn;
                app.k0raw_info.pONfile = regexprep(app.info.k0fn,'DURA','DURA_2');

                app.I2.SDN  = find(strcmp(app.k0raw_hdr,'DATE TIME') == 1);
                app.I2.SCT  = find(strcmp(app.k0raw_hdr,'SAMPLE COUNTER') == 1);
                app.I2.T    = find(strcmp(app.k0raw_hdr,'CTD TEMP') == 1);
                app.I2.S    = find(strcmp(app.k0raw_hdr,'CTD SALINITY') == 1);
                app.I2.VBB  = find(strcmp(app.k0raw_hdr,'BACKUP BATTERY') == 1);

                app.I2.VRS  = find(strcmp(app.k0raw_hdr,'VRS VOLTS') == 1);
                app.I2.VRSS = find(strcmp(app.k0raw_hdr,'VRS STDDEV') == 1);
                app.I2.VK   = find(strcmp(app.k0raw_hdr,'VK VOLTS') == 1);
                app.I2.VKS  = find(strcmp(app.k0raw_hdr,'VK STDDEV') == 1);
                app.I2.IK   = find(strcmp(app.k0raw_hdr,'IK AMPS') == 1);
                app.I2.IB   = find(strcmp(app.k0raw_hdr,'IB AMPS') == 1);

                % MERGE & SORT
                tmp        = [pON; pOFF];
                tON        = [ones(size(pON(:,1))); ones(size(pOFF(:,1)))*0];
                [~,ia]     = sort(tmp(:, app.I2.SDN));
                app.k0raw_data = tmp(ia,:);
                app.tk0raw_ON = tON(ia);
                app.tk0raw_SDN = true(size(tmp(:,1)));
                app.info.k0_tf = 1;

                %                 datestr([min(app.k0raw_data(:,app.I2.SDN)), ...
                %                     max(app.k0raw_data(:,app.I2.SDN))])


                clear tmp ia tON pON pOFF


                % GET COLOR_pH (DISCRETE pH CALIBRATION SAMPLES
                %                             color_pH_fn = 'master_k0cal_SWpH_list.xlsx';
                %                             c = readcell([app.dirs.k0SW_discrete_pH, color_pH_fn],'Range','A3', ...
                %                                 'DatetimeType','text'); % date, pH, quality flag
                %                             app.color_pH.data = [datenum(c(:,1), 'dd-mmm-yyyy HH:MM:SS'), ...
                %                                 cell2mat(c(:,2:3))];
                app.color_pH.data = merge_discrete_pH(app.dirs.k0SW_discrete_pH, 'K0', 0);


                % SET SLIDERS
                app.MinSlider_k0.Limits = [min(app.k0raw_data(:,app.I2.SDN)), ...
                    max(app.k0raw_data(:,app.I2.SDN))];
                app.MinSlider_k0.Value  = app.MinSlider_k0.Limits(1);

                app.MaxSlider_k0.Limits = app.MinSlider_k0.Limits;
                app.MaxSlider_k0.Value  = app.MaxSlider_k0.Limits(2);

                app.info.k0SDN_lim    =[app.MinSlider_k0.Value, app.MaxSlider_k0.Value];

                update_k0_tab(app)
                update_k2_tab(app)
                update_summary_tab(app)

                figure(app.UIFigure); % bring app figure to foreground
                if tf_warn == 1
                    f = warndlg(warn_cell);
                end
            end

        end

        % Value changed function: MinSlider_k0
        function MinSlider_k0ValueChanged(app, event)

            app.tk0raw_SDN = app.k0raw_data(:,app.I2.SDN) >= app.MinSlider_k0.Value & ...
                app.k0raw_data(:,app.I2.SDN) <= app.MaxSlider_k0.Value;

            app.MinSlider_k0.MajorTicks =min(app.k0raw_data(app.tk0raw_SDN, app.I2.SDN));
            app.MinSlider_k0.MajorTickLabels = {datestr(app.MinSlider_k0.MajorTicks,'mmm dd HH:MM')};

            app.info.k0SDN_lim(1)    = app.MinSlider_k0.Value;

            %             app.k2_data = calc_phcal_k2(app.PTdata, app.PThdr, app.tPT_SDN, app.tPdir, app.fP_polyEdit.Value, app.k2fP_polyEdit.Value);
            %             update_k2_tab(app)
            update_k0_tab(app)
            update_k2_tab(app)
            update_summary_tab(app)

        end

        % Value changing function: MinSlider_k0
        function MinSlider_k0ValueChanging(app, event)
            changingValue = event.Value;
            app.MinSlider_k0.MajorTicks = event.Value;
            app.MinSlider_k0.MajorTickLabels = {datestr(app.MinSlider_k0.MajorTicks,'mmm dd HH:MM')};
            app.hVMinLine_k0.Value = datetime(event.Value,'ConvertFrom','datenum');

        end

        % Value changed function: MaxSlider_k0
        function MaxSlider_k0ValueChanged(app, event)

            app.tk0raw_SDN = app.k0raw_data(:,app.I2.SDN) >= app.MinSlider_k0.Value & ...
                app.k0raw_data(:,app.I2.SDN) <= app.MaxSlider_k0.Value;

            sum(app.tk0raw_SDN)

            app.MaxSlider_k0.MajorTicks =max(app.k0raw_data(app.tk0raw_SDN, app.I2.SDN));
            app.MaxSlider_k0.MajorTickLabels = {datestr(app.MaxSlider_k0.MajorTicks,'mmm dd HH:MM')};

            app.info.k0SDN_lim(2)    = app.MaxSlider_k0.Value;

            update_k0_tab(app)
            update_k2_tab(app)
            update_summary_tab(app)

        end

        % Value changing function: MaxSlider_k0
        function MaxSlider_k0ValueChanging(app, event)
            app.MaxSlider_k0.MajorTicks = event.Value;
            app.MaxSlider_k0.MajorTickLabels = {datestr(app.MaxSlider_k0.MajorTicks,'mmm dd HH:MM')};
            app.hVMaxLine_k0.Value = datetime(event.Value,'ConvertFrom','datenum');

        end

        % Selection changed function: raw_VrsButtonGroup
        function raw_VrsButtonGroupSelectionChanged(app, event)
            update_raw_PT_tab(app)

        end

        % Selection changed function: raw_VkButtonGroup
        function raw_VkButtonGroupSelectionChanged(app, event)
            selectedButton = app.raw_VkButtonGroup.SelectedObject;
            update_raw_PT_tab(app)

        end

        % Value changed function: TimeoffsetEditField
        function TimeoffsetEditFieldValueChanged(app, event)
            value = app.TimeoffsetEditField.Value;
            %app.color_pH.TimeOffset = value;
            app.color_pH.TimeOffset = str2double(value);
            update_k0_tab(app)
            update_summary_tab(app)
        end

        % Value changed function: polyfitorderEditField
        function polyfitorderEditFieldValueChanged(app, event)
            value = app.polyfitorderEditField.Value;
            app.color_pH.FitOrder = str2double(value);
            update_k0_tab(app)
            update_summary_tab(app)
        end

        % Selection changed function: k0_YaxisButtonGroup
        function k0_YaxisButtonGroupSelectionChanged(app, event)
            selectedButton = app.k0_YaxisButtonGroup.SelectedObject;
            update_k0_tab(app)

        end

        % Button pushed function: CalReportButton
        function CalReportButtonPushed(app, event)
            DefaultText  = app.CalReportButton.Text;
            DefaultColor = app.CalReportButton.FontColor;

            app.CalReportButton.Text = 'Building Report....';
            app.CalReportButton.FontColor = [0 153 0]/256;

            % CHECK FOR DF DIRECTORY IF NOT THERE CREATE
            DF_dir = sprintf('%s_%s_MSC%s', app.k2_data.DF_TYPE,app.info.DF_SN, app.info.MSC);
            DF_dir_fp = fullfile(app.dirs.save, DF_dir);
            if ~isfolder(DF_dir_fp)
                mkdir(DF_dir_fp)
            end

            % CHECK FOR k0 DATA & GENERATE APPROPRIATE TEXT FILE
             tmpk0 = app.k0_data; 
%             tmpk2 = app.k2_data; % TESTING
%             tmp_info = app.info; % TESTING
%             save('C:\temp\ph_gui_play','tmpk0','tmpk2','tmp_info') % TESTING

            if isfield(tmpk0,'Results')
                pH_cal_report(app.k2_data, app.k0_data, ...
                    app.info, DF_dir_fp);
            else
                pH_cal_report(app.k2_data, [], ...
                    app.info, DF_dir_fp);
            end

            % PRINT SCREEN CAPTURES OF ALL POPULATED TABS
            tabs       = app.TabGroup.Children; % get tab handles
            CurrentTab = app.TabGroup.SelectedTab; % go back here once finished printing pdf's

            % Step through tabs & save an image
            pdf_merge_list = cell(size(tabs,1)); % predim list of fnames for each tab
            pdf_merge_tf   = ones(size(tabs,1),1); % logical for excluding k0 if need be
%             merge_fn       = ['DF', app.info.DF_SN,'_Calibration_', ...
%                 datestr(now,'yyyymmdd'),'.pdf'];% outpout file name

           merge_fn = [app.k2_data.DF_TYPE,app.k2_data.DF_SN, ...
               '_Calibration_',datestr(now,'yyyymmdd'),'.pdf']; % outpout file name



            % step through tabs & bring each to view & print
            for ict = 1:size(tabs,1)
                TabTitle = tabs(ict).Title;
                tmp_fn   = sprintf('tmp_pHcal_pdf%0.0f.pdf',ict);
                if strcmp(TabTitle,'k0') && ~isfield(tmpk0,'Results')
                    pdf_merge_tf(ict) = 0; % no k0 tab yet so remove from list
                    continue
                end
                app.TabGroup.SelectedTab = tabs(ict);
                pdf_merge_list{ict} = fullfile(DF_dir_fp, tmp_fn);
                exportapp(app.UIFigure, pdf_merge_list{ict});
            end
            pdf_merge_list = pdf_merge_list(logical(pdf_merge_tf));
            
            % JP 04/01/25 Append individual tab imgages to one pdf file
            % using mergePdfs instead GhostScript based append_pdfs which
            % is platform limited to some extent
            if isfile(fullfile(DF_dir_fp, merge_fn)) % delete old if it exist
                delete(fullfile(DF_dir_fp, merge_fn));
            end 

            merge_fp = fullfile(DF_dir_fp, merge_fn);
            mergePdfs(pdf_merge_list, merge_fp);

            % Append individual tabs to one pdf file
            % this requires ghostscript & export_fig
            % if isfile([DF_dir_fp, merge_fn]) % delete old if it exist
            %     delete([DF_dir_fp, merge_fn]);
            % end
            
            % disp([DF_dir_fp, merge_fn]) % TESTING
            % 
            % append_pdfs([DF_dir_fp, merge_fn],pdf_merge_list)
            app.TabGroup.SelectedTab = CurrentTab; % back to invoking tab
            delete(fullfile(DF_dir_fp,'tmp_pHcal_pdf*pdf'));

            app.CalReportButton.Text = DefaultText;
            app.CalReportButton.FontColor = DefaultColor;


        end

        % Selection changed function: k0_k0YaxisButtonGroup
        function k0_k0YaxisButtonGroupSelectionChanged(app, event)
            selectedButton = app.k0_k0YaxisButtonGroup.SelectedObject;
            update_k0_tab(app)

        end

        % Value changed function: k2fP_polyEdit
        function k2fP_polyEditValueChanged(app, event)
            app.k2_data = calc_phcal_k2(app.PTdata, app.PThdr, app.PTinfo, ...
                app.tPT_SDN, app.tPdir, app.fP_polyEdit.Value, ...
                app.k2fP_polyEdit.Value);
            update_k2_tab(app)
            update_Pcoef_tab(app)

            if ~isempty(app.k0raw_hdr)
                update_k0_tab(app)
            end

            update_summary_tab(app)

        end

        % Value changed function: fP_SurfZoom_Slider
        function fP_SurfZoom_SliderValueChanged(app, event)
            NewValue = event.Value;
            if NewValue <= app.fP_SurfZoom_Slider.Limits(1) %max < min
                NewValue = app.fP_SurfZoom_Slider.Limits(1) + 50;
            end
            app.fP_SurfZoom_Slider.Value = NewValue;
            update_Pcoef_tab(app)

        end

        % Value changed function: k2_SurfZoom_Slider
        function k2_SurfZoom_SliderValueChanged(app, event)
            NewValue = event.Value;
            % if NewValue <= app.k2_SurfZoom_Slider.Limits(1) %max < min
            %     NewValue = app.k2_SurfZoom_Slider.Limits(1) + 50;
            % end
            app.k2_SurfZoom_Slider.Value = NewValue;
            
            update_k2_tab(app)
        end

        % Button pushed function: Upload_ph_log_to_penguin
        function Upload_ph_log_to_penguinButtonPushed(app, event)
            conn   = connect_penguin();
            k2data = app.k2_data;
        
            % --- Helper to pull a value from k2data.Results by row label ---
            R   = k2data.Results;
            get = @(lbl) R{find(strcmp(R(:,1), lbl), 1), 2};
        
            % --- pt_chamber from cal window row ---
            iCW        = find(strcmp(R(:,1), 'k2 Calibration window:'), 1);
            d1         = datevec(R{iCW,2}, 'mm/dd/yyyy HH:MM');
            d2         = datevec(R{iCW,3}, 'mm/dd/yyyy HH:MM');
            pt_chamber = sprintf('%02d/%02d-%02d/%02d/%04d', d1(2),d1(3),d2(2),d2(3),d2(1));
        
            % --- scalar values ---
            vrs_drift = str2double(get('Vrs drift rate:'));
            k0_hcl    = str2double(get('k0 HCL:'));
            r2_poly2  = str2double(get('f(P) R*R:'));
            df        = str2double(get('Durafet SN:'));
            ph_design = string(R{find(strcmp(R(:,1),'pH stem mfg:'),1), 3}); % 'DF'
            r2_poly1  = median(k2data.BinK2_data(:,6), 'omitnan');
        
            % --- k2 f(P) coefficients → 7 cols right-aligned (C6:C0) ---
            iK2    = find(~cellfun(@isempty, regexp(R(:,1), '^k2 f\(P\) c\d')));
            k2vals = str2double(R(iK2, 2));
            k2fp   = NaN(1,7);
            k2fp(end-numel(k2vals)+1:end) = flip(k2vals)';
        
            % --- f(P) coefficients → 9 cols right-aligned (k8:k0) ---
            iFP    = find(~cellfun(@isempty, regexp(R(:,1), '^f\(P\) c\d')));
            fpvals = str2double(R(iFP, 2));
            fpp    = NaN(1,9);
            fpp(end-numel(fpvals)+1:end) = flip(fpvals)';
        
            % --- ids: manual GUI input ---
            ids = app.idsEditField.Value;   % <-- update to your field name
        
            % --- Build table ---
            T = table( ...
                df,                        ...
                string(pt_chamber),        ...
                string(k2data.DF_CH),      ...
                NaN,                       ...  % pt_runs
                vrs_drift,                 ...
                k2fp(1),k2fp(2),k2fp(3),   ...  % k2_fp_c6/5/4
                k2fp(4),k2fp(5),k2fp(6),   ...  % k2_fp_c3/2/1
                k2fp(7),                   ...  % k2_fp_c0
                k0_hcl,                    ...
                r2_poly1,                  ...
                fpp(1),fpp(2),             ...  % fp_k8/k7
                fpp(3),fpp(4),fpp(5),      ...  % fp_k6/k5/k4
                fpp(6),fpp(7),fpp(8),      ...  % fp_k3/k2/k1
                fpp(9),                    ...  % fp_k0
                r2_poly2,                  ...
                ph_design,                 ...
                ids,                       ...
                'VariableNames', { ...
                    'df','pt_chamber','ch','pt_runs','vrs_drift', ...
                    'k2_fp_c6','k2_fp_c5','k2_fp_c4', ...
                    'k2_fp_c3','k2_fp_c2','k2_fp_c1','k2_fp_c0', ...
                    'k0_hcl','r2_poly1', ...
                    'fp_k8','fp_k7','fp_k6','fp_k5','fp_k4', ...
                    'fp_k3','fp_k2','fp_k1','fp_k0', ...
                    'r2_poly2','ph_design', ...
                    'ids'});
        
            try
                sqlwrite(conn, 'ph_log', T);
                fprintf('Uploaded DF#%s to penguin.ph_log\n', k2data.DF_SN);
            catch ME
                fprintf('Upload failed: %s\n', ME.message);
            end
        
            close(conn);
        end
    end

    % Component initialization
    methods (Access = private)

        % Create UIFigure and components
        function createComponents(app)

            % Create UIFigure and hide until all components are created
            app.UIFigure = uifigure('Visible', 'off');
            app.UIFigure.Position = [150 150 1400 802];
            app.UIFigure.Name = 'UI Figure';

            % Create TabGroup
            app.TabGroup = uitabgroup(app.UIFigure);
            app.TabGroup.Position = [1 3 1400 800];

            % Create PTraw_tab
            app.PTraw_tab = uitab(app.TabGroup);
            app.PTraw_tab.Title = 'raw PT data';

            % Create UIAxes_Vrs
            app.UIAxes_Vrs = uiaxes(app.PTraw_tab);
            title(app.UIAxes_Vrs, 'Title')
            xlabel(app.UIAxes_Vrs, 'X')
            ylabel(app.UIAxes_Vrs, 'Y')
            app.UIAxes_Vrs.PlotBoxAspectRatio = [5.42446043165468 1 1];
            app.UIAxes_Vrs.XTickLabelRotation = 0;
            app.UIAxes_Vrs.YTickLabelRotation = 0;
            app.UIAxes_Vrs.ZTickLabelRotation = 0;
            app.UIAxes_Vrs.Position = [180 520 800 190];

            % Create UIAxes_Vk
            app.UIAxes_Vk = uiaxes(app.PTraw_tab);
            xlabel(app.UIAxes_Vk, 'X')
            ylabel(app.UIAxes_Vk, 'Y')
            app.UIAxes_Vk.PlotBoxAspectRatio = [5.45652173913043 1 1];
            app.UIAxes_Vk.XTickLabelRotation = 0;
            app.UIAxes_Vk.YTickLabelRotation = 0;
            app.UIAxes_Vk.ZTickLabelRotation = 0;
            app.UIAxes_Vk.Position = [180 327 800 190];

            % Create UIAxes_IbIk
            app.UIAxes_IbIk = uiaxes(app.PTraw_tab);
            xlabel(app.UIAxes_IbIk, 'X')
            ylabel(app.UIAxes_IbIk, 'Y')
            app.UIAxes_IbIk.PlotBoxAspectRatio = [4.96052631578947 1 1];
            app.UIAxes_IbIk.XTickLabelRotation = 0;
            app.UIAxes_IbIk.YTick = [0 0.5 1];
            app.UIAxes_IbIk.YTickLabelRotation = 0;
            app.UIAxes_IbIk.ZTickLabelRotation = 0;
            app.UIAxes_IbIk.Position = [180 134 800 190];

            % Create Choose_PTfile_Button
            app.Choose_PTfile_Button = uibutton(app.PTraw_tab, 'push');
            app.Choose_PTfile_Button.ButtonPushedFcn = createCallbackFcn(app, @Choose_PTfile_ButtonPushed, true);
            app.Choose_PTfile_Button.Position = [20 734 334 28];
            app.Choose_PTfile_Button.Text = 'Choose k2 Press chamber file';

            % Create SliderLabel
            app.SliderLabel = uilabel(app.PTraw_tab);
            app.SliderLabel.HorizontalAlignment = 'right';
            app.SliderLabel.Position = [138 85 36 22];
            app.SliderLabel.Text = 'Slider';

            % Create MinSlider
            app.MinSlider = uislider(app.PTraw_tab);
            app.MinSlider.MajorTicks = [4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100];
            app.MinSlider.MajorTickLabels = {'4', '8', '12', '16', '20', '24', '28', '32', '36', '40', '44', '48', '52', '56', '60', '64', '68', '72', '76', '80', '84', '88', '92', '96', '100'};
            app.MinSlider.ValueChangedFcn = createCallbackFcn(app, @MinSliderValueChanged, true);
            app.MinSlider.ValueChangingFcn = createCallbackFcn(app, @MinSliderValueChanging, true);
            app.MinSlider.MinorTicks = [0 0.8 1.6 2.4 3.2 4 4.8 5.6 6.4 7.2 8 8.8 9.6 10.4 11.2 12 12.8 13.6 14.4 15.2 16 16.8 17.6 18.4 19.2 20 20.8 21.6 22.4 23.2 24 24.8 25.6 26.4 27.2 28 28.8 29.6 30.4 31.2 32 32.8 33.6 34.4 35.2 36 36.8 37.6 38.4 39.2 40 40.8 41.6 42.4 43.2 44 44.8 45.6 46.4 47.2 48 48.8 49.6 50.4 51.2 52 52.8 53.6 54.4 55.2 56 56.8 57.6 58.4 59.2 60 60.8 61.6 62.4 63.2 64 64.8 65.6 66.4 67.2 68 68.8 69.6 70.4 71.2 72 72.8 73.6 74.4 75.2 76 76.8 77.6 78.4 79.2 80 80.8 81.6 82.4 83.2 84 84.8 85.6 86.4 87.2 88 88.8 89.6 90.4 91.2 92 92.8 93.6 94.4 95.2 96 96.8 97.6 98.4 99.2 100];
            app.MinSlider.Position = [203 94 778 3];

            % Create Slider_2Label
            app.Slider_2Label = uilabel(app.PTraw_tab);
            app.Slider_2Label.HorizontalAlignment = 'right';
            app.Slider_2Label.Position = [138 55 36 22];
            app.Slider_2Label.Text = 'Slider';

            % Create MaxSlider
            app.MaxSlider = uislider(app.PTraw_tab);
            app.MaxSlider.MajorTicks = [4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100];
            app.MaxSlider.MajorTickLabels = {'4', '8', '12', '16', '20', '24', '28', '32', '36', '40', '44', '48', '52', '56', '60', '64', '68', '72', '76', '80', '84', '88', '92', '96', '100'};
            app.MaxSlider.ValueChangedFcn = createCallbackFcn(app, @MaxSliderValueChanged, true);
            app.MaxSlider.ValueChangingFcn = createCallbackFcn(app, @MaxSliderValueChanging, true);
            app.MaxSlider.MinorTicks = [0 0.8 1.6 2.4 3.2 4 4.8 5.6 6.4 7.2 8 8.8 9.6 10.4 11.2 12 12.8 13.6 14.4 15.2 16 16.8 17.6 18.4 19.2 20 20.8 21.6 22.4 23.2 24 24.8 25.6 26.4 27.2 28 28.8 29.6 30.4 31.2 32 32.8 33.6 34.4 35.2 36 36.8 37.6 38.4 39.2 40 40.8 41.6 42.4 43.2 44 44.8 45.6 46.4 47.2 48 48.8 49.6 50.4 51.2 52 52.8 53.6 54.4 55.2 56 56.8 57.6 58.4 59.2 60 60.8 61.6 62.4 63.2 64 64.8 65.6 66.4 67.2 68 68.8 69.6 70.4 71.2 72 72.8 73.6 74.4 75.2 76 76.8 77.6 78.4 79.2 80 80.8 81.6 82.4 83.2 84 84.8 85.6 86.4 87.2 88 88.8 89.6 90.4 91.2 92 92.8 93.6 94.4 95.2 96 96.8 97.6 98.4 99.2 100];
            app.MaxSlider.Position = [203 64 778 3];

            % Create raw_VkButtonGroup
            app.raw_VkButtonGroup = uibuttongroup(app.PTraw_tab);
            app.raw_VkButtonGroup.SelectionChangedFcn = createCallbackFcn(app, @raw_VkButtonGroupSelectionChanged, true);
            app.raw_VkButtonGroup.Title = 'Vk Y axis';
            app.raw_VkButtonGroup.Position = [43 386 100 72];

            % Create VkVButton
            app.VkVButton = uiradiobutton(app.raw_VkButtonGroup);
            app.VkVButton.Text = 'volts';
            app.VkVButton.Position = [11 26 58 22];
            app.VkVButton.Value = true;

            % Create VkSTDButton
            app.VkSTDButton = uiradiobutton(app.raw_VkButtonGroup);
            app.VkSTDButton.Text = 'std volts';
            app.VkSTDButton.Position = [11 4 66 22];

            % Create raw_VrsButtonGroup
            app.raw_VrsButtonGroup = uibuttongroup(app.PTraw_tab);
            app.raw_VrsButtonGroup.SelectionChangedFcn = createCallbackFcn(app, @raw_VrsButtonGroupSelectionChanged, true);
            app.raw_VrsButtonGroup.Title = 'Vrs Y axis';
            app.raw_VrsButtonGroup.Position = [54 587 100 72];

            % Create VrsVButton
            app.VrsVButton = uiradiobutton(app.raw_VrsButtonGroup);
            app.VrsVButton.Text = 'volts';
            app.VrsVButton.Position = [11 26 58 22];
            app.VrsVButton.Value = true;

            % Create VrsSTDButton
            app.VrsSTDButton = uiradiobutton(app.raw_VrsButtonGroup);
            app.VrsSTDButton.Text = 'std volts';
            app.VrsSTDButton.Position = [11 4 66 22];

            % Create k2_tab
            app.k2_tab = uitab(app.TabGroup);
            app.k2_tab.Title = 'k2';

            % Create k2_VrsDrift
            app.k2_VrsDrift = uiaxes(app.k2_tab);
            ylabel(app.k2_VrsDrift, 'Vrs (T~20,P<10)')
            app.k2_VrsDrift.PlotBoxAspectRatio = [3.60365853658537 1 1];
            app.k2_VrsDrift.XTickLabelRotation = 0;
            app.k2_VrsDrift.YTickLabelRotation = 0;
            app.k2_VrsDrift.ZTickLabelRotation = 0;
            app.k2_VrsDrift.Position = [140 542 638 206];

            % Create k2_VrsVc_vs_T
            app.k2_VrsVc_vs_T = uiaxes(app.k2_tab);
            xlabel(app.k2_VrsVc_vs_T, 'Temperature')
            ylabel(app.k2_VrsVc_vs_T, 'VrsCor - Vc')
            app.k2_VrsVc_vs_T.PlotBoxAspectRatio = [1.19421487603306 1 1];
            app.k2_VrsVc_vs_T.XTickLabelRotation = 0;
            app.k2_VrsVc_vs_T.YTickLabelRotation = 0;
            app.k2_VrsVc_vs_T.ZTickLabelRotation = 0;
            app.k2_VrsVc_vs_T.Position = [131 55 297 254];

            % Create k2_P_vs_k2
            app.k2_P_vs_k2 = uiaxes(app.k2_tab);
            xlabel(app.k2_P_vs_k2, 'k2')
            ylabel(app.k2_P_vs_k2, 'Pressure, dbar')
            app.k2_P_vs_k2.PlotBoxAspectRatio = [1.17355371900826 1 1];
            app.k2_P_vs_k2.XTickLabelRotation = 0;
            app.k2_P_vs_k2.YTickLabelRotation = 0;
            app.k2_P_vs_k2.ZTickLabelRotation = 0;
            app.k2_P_vs_k2.Position = [464 55 314 254];

            % Create k2_VrsCorr
            app.k2_VrsCorr = uiaxes(app.k2_tab);
            ylabel(app.k2_VrsCorr, 'Vrs (Drift corrected)')
            app.k2_VrsCorr.PlotBoxAspectRatio = [3.60365853658537 1 1];
            app.k2_VrsCorr.XTickLabelRotation = 0;
            app.k2_VrsCorr.YTickLabelRotation = 0;
            app.k2_VrsCorr.ZTickLabelRotation = 0;
            app.k2_VrsCorr.Position = [140 338 638 206];

            % Create PTrawSubset_ButtonGroup
            app.PTrawSubset_ButtonGroup = uibuttongroup(app.k2_tab);
            app.PTrawSubset_ButtonGroup.SelectionChangedFcn = createCallbackFcn(app, @PTrawSubset_ButtonGroupSelectionChanged, true);
            app.PTrawSubset_ButtonGroup.Title = 'Data subset';
            app.PTrawSubset_ButtonGroup.Position = [14 530 111 158];

            % Create allButton
            app.allButton = uiradiobutton(app.PTrawSubset_ButtonGroup);
            app.allButton.Text = 'all';
            app.allButton.Position = [11 112 58 22];
            app.allButton.Value = true;

            % Create PincreasingButton
            app.PincreasingButton = uiradiobutton(app.PTrawSubset_ButtonGroup);
            app.PincreasingButton.Text = 'P increasing';
            app.PincreasingButton.Position = [11 90 88 22];

            % Create PdecreasingButton
            app.PdecreasingButton = uiradiobutton(app.PTrawSubset_ButtonGroup);
            app.PdecreasingButton.Text = 'P decreasing';
            app.PdecreasingButton.Position = [11 68 92 22];

            % Create PstationaryButton
            app.PstationaryButton = uiradiobutton(app.PTrawSubset_ButtonGroup);
            app.PstationaryButton.Text = 'P stationary';
            app.PstationaryButton.Position = [11 39 85 22];

            % Create UITable_results
            app.UITable_results = uitable(app.k2_tab);
            app.UITable_results.ColumnName = {'Column 1'; 'Column 2'; 'Column 3'};
            app.UITable_results.RowName = {};
            app.UITable_results.Position = [816 110 540 630];

            % Create CalReportButton
            app.CalReportButton = uibutton(app.k2_tab, 'push');
            app.CalReportButton.ButtonPushedFcn = createCallbackFcn(app, @CalReportButtonPushed, true);
            app.CalReportButton.Position = [927 51 232 49];
            app.CalReportButton.Text = 'EXPORT CALIBRATION REPORT';

            % Create k2fppolyorderLabel
            app.k2fppolyorderLabel = uilabel(app.k2_tab);
            app.k2fppolyorderLabel.HorizontalAlignment = 'center';
            app.k2fppolyorderLabel.Position = [24 463 59 27];
            app.k2fppolyorderLabel.Text = {'k2 f(p)'; 'poly order'};

            % Create k2fP_polyEdit
            app.k2fP_polyEdit = uieditfield(app.k2_tab, 'numeric');
            app.k2fP_polyEdit.Limits = [0 6];
            app.k2fP_polyEdit.ValueDisplayFormat = '%0.0f';
            app.k2fP_polyEdit.ValueChangedFcn = createCallbackFcn(app, @k2fP_polyEditValueChanged, true);
            app.k2fP_polyEdit.Position = [95 459 26 34];

            % Create YaxissurfacezoomLabel_2
            app.YaxissurfacezoomLabel_2 = uilabel(app.k2_tab);
            app.YaxissurfacezoomLabel_2.HorizontalAlignment = 'right';
            app.YaxissurfacezoomLabel_2.Position = [577 37 113 22];
            app.YaxissurfacezoomLabel_2.Text = 'Y axis surface zoom';

            % Create k2_SurfZoom_Slider
            app.k2_SurfZoom_Slider = uislider(app.k2_tab);
            app.k2_SurfZoom_Slider.ValueChangedFcn = createCallbackFcn(app, @k2_SurfZoom_SliderValueChanged, true);
            app.k2_SurfZoom_Slider.Position = [507 37 253 3];

            % Create Upload_ph_log_to_penguin
            app.Upload_ph_log_to_penguin = uibutton(app.k2_tab, 'push');
            app.Upload_ph_log_to_penguin.ButtonPushedFcn = createCallbackFcn(app, @Upload_ph_log_to_penguinButtonPushed, true);
            app.Upload_ph_log_to_penguin.Position = [1184 51 149 49];
            app.Upload_ph_log_to_penguin.Text = 'UPLOAD TO PENGUIN';

            % Create idsEditFieldLabel
            app.idsEditFieldLabel = uilabel(app.k2_tab);
            app.idsEditFieldLabel.HorizontalAlignment = 'right';
            app.idsEditFieldLabel.Position = [1216 11 25 22];
            app.idsEditFieldLabel.Text = 'ids';

            % Create idsEditField
            app.idsEditField = uieditfield(app.k2_tab, 'numeric');
            app.idsEditField.Position = [1256 11 77 22];

            % Create Pcoefs_tab
            app.Pcoefs_tab = uitab(app.TabGroup);
            app.Pcoefs_tab.Title = 'Pcoefs';

            % Create Pcoefs_FvsP
            app.Pcoefs_FvsP = uiaxes(app.Pcoefs_tab);
            xlabel(app.Pcoefs_FvsP, 'Vrs - Vc - k2T     ( = f(P) )')
            ylabel(app.Pcoefs_FvsP, 'Pressure, dbar')
            app.Pcoefs_FvsP.PlotBoxAspectRatio = [1.04788732394366 1 1];
            app.Pcoefs_FvsP.XTickLabelRotation = 0;
            app.Pcoefs_FvsP.YTickLabelRotation = 0;
            app.Pcoefs_FvsP.ZTickLabelRotation = 0;
            app.Pcoefs_FvsP.Position = [249 319 419 411];

            % Create Pcoefs_FvsP_anom
            app.Pcoefs_FvsP_anom = uiaxes(app.Pcoefs_tab);
            xlabel(app.Pcoefs_FvsP_anom, '(Vrs - Vc - k2T )  - f(P) , uV')
            app.Pcoefs_FvsP_anom.PlotBoxAspectRatio = [1.04788732394366 1 1];
            app.Pcoefs_FvsP_anom.XTickLabelRotation = 0;
            app.Pcoefs_FvsP_anom.YTickLabelRotation = 0;
            app.Pcoefs_FvsP_anom.ZTickLabelRotation = 0;
            app.Pcoefs_FvsP_anom.Position = [729 319 419 411];

            % Create polyorderEditFieldLabel
            app.polyorderEditFieldLabel = uilabel(app.Pcoefs_tab);
            app.polyorderEditFieldLabel.HorizontalAlignment = 'right';
            app.polyorderEditFieldLabel.Position = [40 626 59 22];
            app.polyorderEditFieldLabel.Text = 'poly order';

            % Create fP_polyEdit
            app.fP_polyEdit = uieditfield(app.Pcoefs_tab, 'numeric');
            app.fP_polyEdit.ValueChangedFcn = createCallbackFcn(app, @fP_polyEditValueChanged, true);
            app.fP_polyEdit.Position = [114 626 25 22];
            app.fP_polyEdit.Value = 6;

            % Create Pcoefs_CAxisButtonGroup
            app.Pcoefs_CAxisButtonGroup = uibuttongroup(app.Pcoefs_tab);
            app.Pcoefs_CAxisButtonGroup.SelectionChangedFcn = createCallbackFcn(app, @Pcoefs_CAxisButtonGroupSelectionChanged, true);
            app.Pcoefs_CAxisButtonGroup.Title = 'Color Axis';
            app.Pcoefs_CAxisButtonGroup.Position = [31 457 123 135];

            % Create TemperatureButton
            app.TemperatureButton = uiradiobutton(app.Pcoefs_CAxisButtonGroup);
            app.TemperatureButton.Text = 'Temperature';
            app.TemperatureButton.Position = [11 89 89 22];
            app.TemperatureButton.Value = true;

            % Create TimeButton
            app.TimeButton = uiradiobutton(app.Pcoefs_CAxisButtonGroup);
            app.TimeButton.Text = 'Time';
            app.TimeButton.Position = [11 67 65 22];

            % Create VkButton
            app.VkButton = uiradiobutton(app.Pcoefs_CAxisButtonGroup);
            app.VkButton.Text = 'Vk';
            app.VkButton.Position = [11 45 65 22];

            % Create DirectionButton
            app.DirectionButton = uiradiobutton(app.Pcoefs_CAxisButtonGroup);
            app.DirectionButton.Text = 'Direction';
            app.DirectionButton.Position = [11 18 69 22];

            % Create YaxissurfacezoomLabel
            app.YaxissurfacezoomLabel = uilabel(app.Pcoefs_tab);
            app.YaxissurfacezoomLabel.HorizontalAlignment = 'right';
            app.YaxissurfacezoomLabel.Position = [434 260 113 22];
            app.YaxissurfacezoomLabel.Text = 'Y axis surface zoom';

            % Create fP_SurfZoom_Slider
            app.fP_SurfZoom_Slider = uislider(app.Pcoefs_tab);
            app.fP_SurfZoom_Slider.ValueChangedFcn = createCallbackFcn(app, @fP_SurfZoom_SliderValueChanged, true);
            app.fP_SurfZoom_Slider.Position = [288 244 364 3];

            % Create k0_tab
            app.k0_tab = uitab(app.TabGroup);
            app.k0_tab.Title = 'k0';

            % Create UIAxes_k0_pH
            app.UIAxes_k0_pH = uiaxes(app.k0_tab);
            title(app.UIAxes_k0_pH, 'Title')
            xlabel(app.UIAxes_k0_pH, 'X')
            ylabel(app.UIAxes_k0_pH, 'Y')
            app.UIAxes_k0_pH.PlotBoxAspectRatio = [5.42446043165468 1 1];
            app.UIAxes_k0_pH.XTickLabelRotation = 0;
            app.UIAxes_k0_pH.YTickLabelRotation = 0;
            app.UIAxes_k0_pH.ZTickLabelRotation = 0;
            app.UIAxes_k0_pH.Position = [180 520 800 190];

            % Create UIAxes_k0_k0
            app.UIAxes_k0_k0 = uiaxes(app.k0_tab);
            xlabel(app.UIAxes_k0_k0, 'X')
            ylabel(app.UIAxes_k0_k0, 'Y')
            app.UIAxes_k0_k0.PlotBoxAspectRatio = [5.45652173913043 1 1];
            app.UIAxes_k0_k0.XTickLabelRotation = 0;
            app.UIAxes_k0_k0.YTickLabelRotation = 0;
            app.UIAxes_k0_k0.ZTickLabelRotation = 0;
            app.UIAxes_k0_k0.Position = [180 327 800 190];

            % Create UIAxes_k0_Vk
            app.UIAxes_k0_Vk = uiaxes(app.k0_tab);
            xlabel(app.UIAxes_k0_Vk, 'X')
            ylabel(app.UIAxes_k0_Vk, 'Y')
            app.UIAxes_k0_Vk.PlotBoxAspectRatio = [4.96052631578947 1 1];
            app.UIAxes_k0_Vk.XTickLabelRotation = 0;
            app.UIAxes_k0_Vk.YTick = [0 0.5 1];
            app.UIAxes_k0_Vk.YTickLabelRotation = 0;
            app.UIAxes_k0_Vk.ZTickLabelRotation = 0;
            app.UIAxes_k0_Vk.Position = [180 134 800 190];

            % Create Choose_k0file_Button
            app.Choose_k0file_Button = uibutton(app.k0_tab, 'push');
            app.Choose_k0file_Button.ButtonPushedFcn = createCallbackFcn(app, @Choose_k0file_ButtonPushed, true);
            app.Choose_k0file_Button.Position = [20 734 334 28];
            app.Choose_k0file_Button.Text = 'Choose k0 sea water file';

            % Create MinSlider_k0
            app.MinSlider_k0 = uislider(app.k0_tab);
            app.MinSlider_k0.MajorTicks = [4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100];
            app.MinSlider_k0.MajorTickLabels = {'4', '8', '12', '16', '20', '24', '28', '32', '36', '40', '44', '48', '52', '56', '60', '64', '68', '72', '76', '80', '84', '88', '92', '96', '100'};
            app.MinSlider_k0.ValueChangedFcn = createCallbackFcn(app, @MinSlider_k0ValueChanged, true);
            app.MinSlider_k0.ValueChangingFcn = createCallbackFcn(app, @MinSlider_k0ValueChanging, true);
            app.MinSlider_k0.MinorTicks = [0 0.8 1.6 2.4 3.2 4 4.8 5.6 6.4 7.2 8 8.8 9.6 10.4 11.2 12 12.8 13.6 14.4 15.2 16 16.8 17.6 18.4 19.2 20 20.8 21.6 22.4 23.2 24 24.8 25.6 26.4 27.2 28 28.8 29.6 30.4 31.2 32 32.8 33.6 34.4 35.2 36 36.8 37.6 38.4 39.2 40 40.8 41.6 42.4 43.2 44 44.8 45.6 46.4 47.2 48 48.8 49.6 50.4 51.2 52 52.8 53.6 54.4 55.2 56 56.8 57.6 58.4 59.2 60 60.8 61.6 62.4 63.2 64 64.8 65.6 66.4 67.2 68 68.8 69.6 70.4 71.2 72 72.8 73.6 74.4 75.2 76 76.8 77.6 78.4 79.2 80 80.8 81.6 82.4 83.2 84 84.8 85.6 86.4 87.2 88 88.8 89.6 90.4 91.2 92 92.8 93.6 94.4 95.2 96 96.8 97.6 98.4 99.2 100];
            app.MinSlider_k0.Position = [203 94 778 3];

            % Create MaxSlider_k0
            app.MaxSlider_k0 = uislider(app.k0_tab);
            app.MaxSlider_k0.MajorTicks = [4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100];
            app.MaxSlider_k0.MajorTickLabels = {'4', '8', '12', '16', '20', '24', '28', '32', '36', '40', '44', '48', '52', '56', '60', '64', '68', '72', '76', '80', '84', '88', '92', '96', '100'};
            app.MaxSlider_k0.ValueChangedFcn = createCallbackFcn(app, @MaxSlider_k0ValueChanged, true);
            app.MaxSlider_k0.ValueChangingFcn = createCallbackFcn(app, @MaxSlider_k0ValueChanging, true);
            app.MaxSlider_k0.MinorTicks = [0 0.8 1.6 2.4 3.2 4 4.8 5.6 6.4 7.2 8 8.8 9.6 10.4 11.2 12 12.8 13.6 14.4 15.2 16 16.8 17.6 18.4 19.2 20 20.8 21.6 22.4 23.2 24 24.8 25.6 26.4 27.2 28 28.8 29.6 30.4 31.2 32 32.8 33.6 34.4 35.2 36 36.8 37.6 38.4 39.2 40 40.8 41.6 42.4 43.2 44 44.8 45.6 46.4 47.2 48 48.8 49.6 50.4 51.2 52 52.8 53.6 54.4 55.2 56 56.8 57.6 58.4 59.2 60 60.8 61.6 62.4 63.2 64 64.8 65.6 66.4 67.2 68 68.8 69.6 70.4 71.2 72 72.8 73.6 74.4 75.2 76 76.8 77.6 78.4 79.2 80 80.8 81.6 82.4 83.2 84 84.8 85.6 86.4 87.2 88 88.8 89.6 90.4 91.2 92 92.8 93.6 94.4 95.2 96 96.8 97.6 98.4 99.2 100];
            app.MaxSlider_k0.Position = [203 64 778 3];

            % Create k0_YaxisButtonGroup
            app.k0_YaxisButtonGroup = uibuttongroup(app.k0_tab);
            app.k0_YaxisButtonGroup.SelectionChangedFcn = createCallbackFcn(app, @k0_YaxisButtonGroupSelectionChanged, true);
            app.k0_YaxisButtonGroup.Title = 'Y axis';
            app.k0_YaxisButtonGroup.Position = [38 176 103 106];

            % Create k0_VkButton
            app.k0_VkButton = uiradiobutton(app.k0_YaxisButtonGroup);
            app.k0_VkButton.Text = 'Vk';
            app.k0_VkButton.Position = [11 60 58 22];

            % Create k0_stdVkButton
            app.k0_stdVkButton = uiradiobutton(app.k0_YaxisButtonGroup);
            app.k0_stdVkButton.Text = 'std Vk';
            app.k0_stdVkButton.Position = [11 38 65 22];

            % Create k0_TempButton
            app.k0_TempButton = uiradiobutton(app.k0_YaxisButtonGroup);
            app.k0_TempButton.Text = 'Temperature';
            app.k0_TempButton.Position = [11 16 89 22];
            app.k0_TempButton.Value = true;

            % Create TimeoffsetEditFieldLabel
            app.TimeoffsetEditFieldLabel = uilabel(app.k0_tab);
            app.TimeoffsetEditFieldLabel.HorizontalAlignment = 'right';
            app.TimeoffsetEditFieldLabel.Position = [20 666 79 22];
            app.TimeoffsetEditFieldLabel.Text = 'Time offset';

            % Create TimeoffsetEditField
            app.TimeoffsetEditField = uieditfield(app.k0_tab, 'text');
            app.TimeoffsetEditField.ValueChangedFcn = createCallbackFcn(app, @TimeoffsetEditFieldValueChanged, true);
            app.TimeoffsetEditField.Position = [115 666 38 22];
            app.TimeoffsetEditField.Value = '7';

            % Create polyfitorderEditFieldLabel
            app.polyfitorderEditFieldLabel = uilabel(app.k0_tab);
            app.polyfitorderEditFieldLabel.HorizontalAlignment = 'right';
            app.polyfitorderEditFieldLabel.Position = [20 632 79 22];
            app.polyfitorderEditFieldLabel.Text = 'poly fit order';

            % Create polyfitorderEditField
            app.polyfitorderEditField = uieditfield(app.k0_tab, 'text');
            app.polyfitorderEditField.ValueChangedFcn = createCallbackFcn(app, @polyfitorderEditFieldValueChanged, true);
            app.polyfitorderEditField.Position = [115 632 38 22];
            app.polyfitorderEditField.Value = '1';

            % Create k0_k0YaxisButtonGroup
            app.k0_k0YaxisButtonGroup = uibuttongroup(app.k0_tab);
            app.k0_k0YaxisButtonGroup.SelectionChangedFcn = createCallbackFcn(app, @k0_k0YaxisButtonGroupSelectionChanged, true);
            app.k0_k0YaxisButtonGroup.Title = 'k0 Y axis';
            app.k0_k0YaxisButtonGroup.Position = [38 401 115 74];

            % Create k0_k0Button
            app.k0_k0Button = uiradiobutton(app.k0_k0YaxisButtonGroup);
            app.k0_k0Button.Text = 'k0';
            app.k0_k0Button.Position = [11 28 58 22];
            app.k0_k0Button.Value = true;

            % Create k0_k0_medk0Button
            app.k0_k0_medk0Button = uiradiobutton(app.k0_k0YaxisButtonGroup);
            app.k0_k0_medk0Button.Text = 'k0 - median(k0)';
            app.k0_k0_medk0Button.Position = [11 6 105 22];

            % Create SummaryTab
            app.SummaryTab = uitab(app.TabGroup);
            app.SummaryTab.Title = 'Summary';

            % Create GridLayout
            app.GridLayout = uigridlayout(app.SummaryTab);
            app.GridLayout.ColumnWidth = {'2x', '2x', '2x', '2x', '3x'};
            app.GridLayout.RowHeight = {'3x', '3x', '4x'};

            % Create UIAxes_k2stats
            app.UIAxes_k2stats = uiaxes(app.GridLayout);
            xlabel(app.UIAxes_k2stats, 'Float count')
            ylabel(app.UIAxes_k2stats, 'k2 (Press = 0)')
            zlabel(app.UIAxes_k2stats, 'Z')
            app.UIAxes_k2stats.Layout.Row = 1;
            app.UIAxes_k2stats.Layout.Column = [1 4];

            % Create UIAxes_k0stats
            app.UIAxes_k0stats = uiaxes(app.GridLayout);
            xlabel(app.UIAxes_k0stats, 'Float couint')
            ylabel(app.UIAxes_k0stats, 'k0 pON (Volts)')
            zlabel(app.UIAxes_k0stats, 'Z')
            app.UIAxes_k0stats.Layout.Row = 2;
            app.UIAxes_k0stats.Layout.Column = [1 4];

            % Create UIAxes_k2_hist
            app.UIAxes_k2_hist = uiaxes(app.GridLayout);
            xlabel(app.UIAxes_k2_hist, 'k2 (press=0)')
            ylabel(app.UIAxes_k2_hist, 'Count')
            zlabel(app.UIAxes_k2_hist, 'Z')
            app.UIAxes_k2_hist.Layout.Row = 3;
            app.UIAxes_k2_hist.Layout.Column = 1;

            % Create UIAxes_k0_hist
            app.UIAxes_k0_hist = uiaxes(app.GridLayout);
            xlabel(app.UIAxes_k0_hist, 'k0 pON (Volts)')
            ylabel(app.UIAxes_k0_hist, 'Count')
            zlabel(app.UIAxes_k0_hist, 'Z')
            app.UIAxes_k0_hist.Layout.Row = 3;
            app.UIAxes_k0_hist.Layout.Column = 2;

            % Create UIAxes_k0OnOff_hist
            app.UIAxes_k0OnOff_hist = uiaxes(app.GridLayout);
            xlabel(app.UIAxes_k0OnOff_hist, 'k0 (pON-pOFF)')
            ylabel(app.UIAxes_k0OnOff_hist, 'Count')
            zlabel(app.UIAxes_k0OnOff_hist, 'Z')
            app.UIAxes_k0OnOff_hist.Layout.Row = 3;
            app.UIAxes_k0OnOff_hist.Layout.Column = 3;

            % Create UIAxes_fPstats
            app.UIAxes_fPstats = uiaxes(app.GridLayout);
            xlabel(app.UIAxes_fPstats, 'f(P)')
            ylabel(app.UIAxes_fPstats, 'Pressure')
            zlabel(app.UIAxes_fPstats, 'Z')
            app.UIAxes_fPstats.Layout.Row = [1 2];
            app.UIAxes_fPstats.Layout.Column = 5;

            % Create UIAxes_k0OnHCl_hist
            app.UIAxes_k0OnHCl_hist = uiaxes(app.GridLayout);
            xlabel(app.UIAxes_k0OnHCl_hist, 'k0 (pON - HCl)')
            ylabel(app.UIAxes_k0OnHCl_hist, 'Y')
            zlabel(app.UIAxes_k0OnHCl_hist, 'Z')
            app.UIAxes_k0OnHCl_hist.Layout.Row = 3;
            app.UIAxes_k0OnHCl_hist.Layout.Column = 4;

            % Create TextArea_summary
            app.TextArea_summary = uitextarea(app.GridLayout);
            app.TextArea_summary.Layout.Row = 3;
            app.TextArea_summary.Layout.Column = 5;

            % Show the figure after all components are created
            app.UIFigure.Visible = 'on';
        end
    end

    % App creation and deletion
    methods (Access = public)

        % Construct app
        function app = pH_calibration

            % Create UIFigure and components
            createComponents(app)

            % Register the app with App Designer
            registerApp(app, app.UIFigure)

            % Execute the startup function
            runStartupFcn(app, @startupFcn)

            if nargout == 0
                clear app
            end
        end

        % Code that executes before app deletion
        function delete(app)

            % Delete UIFigure when app is deleted
            delete(app.UIFigure)
        end
    end
end