function TDS
%   TDS measure evaluation tool
%   Detailed explanation goes here

    % Clear variables, define global variables, define default values,
    % reset persistent variables....
clear;
txt_cortval_default = 0.9; txt_bNoiseTimeVal_default = 30;
txt_tempTimeEq_default = getdefTT('deftemptime.txt');

measureOrig = [];
masses = [];
MIpeaks = readPeaks('peaks.csv');
recalcm('norm', 0, 1);
recalcm('mass', 1, 1);
recalcm('output', 'sig', 1);
recalcm('cycle', 1, 1);
recalcm('corint', [0,0], 1);
recalcm('threshold', txt_cortval_default, 1);

%% Create GUI
   scrSize = get(0, 'ScreenSize');
   figSize = [900,670];
   set(0, 'DefaultFigureHandleVisibility','callback');
   set(0, 'DefaultUImenuHandleVisibility','callback');
   set(0, 'DefaultUIcontrolHandleVisibility','callback');
   set(0, 'DefaultAxesHandleVisibility','callback');
   if figSize(1) > scrSize(3) || figSize(2) > scrSize(4)
       waitfor(warndlg('Figure bigger than screen resolution.', 'Warning!'));
   end
   fig_Main = figure('Name','TDS Data Evaluation tool', 'Visible','off', ...
       'MenuBar','none', 'NumberTitle','off', ...
       'Color', [.7 .7 .7], 'Position',[1,1,figSize(1),figSize(2)]);
   movegui(fig_Main, 'center');
   
        % Buttons
   btn_OpenFile =   uicontrol('Parent',fig_Main, ...
                              'Style','pushbutton', ...
                              'String','Open ASCII file', ...
                              'Position',[15,figSize(2)-40-0*30,110,25], ...
                              'Callback',{@btn_OpenFile_Callback});
   btn_clg =        uicontrol('Parent',fig_Main, ...
                              'Style','pushbutton', ...
                              'String','Close file', ...
                              'Position',[15,figSize(2)-40-2*30-20,110,25], ...
                              'Callback',{@btn_clg_Callback});
   btn_clc =        uicontrol('Parent',fig_Main, ...
                              'Style','pushbutton', ...
                              'String','Clear CW', ...
                              'Position',[15,figSize(2)-40-1*30-10,110,25], ...
                              'Visible','off', ...
                              'Callback',{@btn_clc_Callback});
   btn_Close =      uicontrol('Parent',fig_Main, ...
                              'Style','pushbutton', ...
                              'String','Quit', ...
                              'Position',[15,figSize(2)-40-4*30,110,25], ...
                              'Callback',{@btn_Close_Callback});
        % Static text boxes
   txtColor =  get(fig_Main,'Color')+.05;
   txtY = 35;
   txtSizeV = 15;
   txtDist = txtSizeV + 5;
   txt_MeasDate = uicontrol('Parent',fig_Main, ...
                            'Style','text', ...
                            'String','Measure date: ', ...
                            'HorizontalAlignment','left', ...
                            'BackgroundColor',txtColor, ...
                  'Position',[150,figSize(2)-txtY-0*txtDist,105,txtSizeV]);
   txt_MeasTime = uicontrol('Parent',fig_Main, ...
                            'Style','text', ...
                            'String','Measure time: ', ...
                            'HorizontalAlignment','left', ...
                            'BackgroundColor',txtColor, ...
                  'Position',[150,figSize(2)-txtY-1*txtDist,105,txtSizeV]);
   txt_cCycles =     uicontrol('Parent',fig_Main, ...
                            'Style','text', ...
                            'String','Converted cycles: ', ...
                            'HorizontalAlignment','left', ...
                            'BackgroundColor',txtColor, ...
                  'Position',[150,figSize(2)-txtY-2*txtDist,105,txtSizeV]);
   txt_MeasDateVal = uicontrol('Parent',fig_Main, ...
                               'Style','text', ...
                               'String','', ...
                               'HorizontalAlignment','right', ...
                               'BackgroundColor',txtColor, ...
                   'Position',[260,figSize(2)-txtY-0*txtDist,70,txtSizeV]);
   txt_MeasTimeVal = uicontrol('Parent',fig_Main, ...
                               'Style','text', ...
                               'String','', ...
                               'HorizontalAlignment','right', ...
                               'BackgroundColor',txtColor, ...
                   'Position',[260,figSize(2)-txtY-1*txtDist,70,txtSizeV]);
   txt_cCyclesVal =     uicontrol('Parent',fig_Main, ...
                               'Style','text', ...
                               'String','', ...
                               'HorizontalAlignment','right', ...
                               'BackgroundColor',txtColor, ...
                   'Position',[260,figSize(2)-txtY-2*txtDist,70,txtSizeV]);
   txt_bNoiseTime = uicontrol('Parent',fig_Main, ...
                             'Style','text', ...
                             'String',sprintf('Background noise \ncalibration time [s]:  '), ...
                             'HorizontalAlignment','left', ...
                             'BackgroundColor',txtColor, ...
                   'Position',[360,figSize(2)-txtY-1*txtDist+10,110,txtSizeV*2]);
   txt_bNoiseTimeVal = uicontrol('Parent',fig_Main, ...
                             'Style','edit', ...
                             'String',txt_bNoiseTimeVal_default, ...
                             'HorizontalAlignment','right', ...
                             'BackgroundColor',[1 1 1], ...
                             'Callback',{@txt_bNoiseTimeVal_Callback}, ...
                   'Position',[480,figSize(2)-txtY-1*txtDist-1+(txtSizeV+2)/2+10,30,txtSizeV+2]);
   txt_tempTime =     uicontrol('Parent',fig_Main, ...
                            'Style','text', ...
                            'String','Temperature-time function:', ...
                            'HorizontalAlignment','left', ...
                            'BackgroundColor',txtColor, ...
                  'Position',[360,figSize(2)-txtY-2*txtDist+10,155,txtSizeV]);
   chk_tempTime =     uicontrol('Parent',fig_Main, ...
                             'Style','checkbox', ...
                             'Callback',{@chk_tempTime_Callback}, ...
                   'Position',[525,figSize(2)-txtY-2*txtDist-1+10,15,txtSizeV+2]);
   txt_tempTimeEq =   uicontrol('Parent',fig_Main, ...
                               'Style','edit', ...
                               'String',txt_tempTimeEq_default, ...
                               'Callback',{@txt_tempTimeEq_Callback}, ...
                               'HorizontalAlignment','right', ...
                               'BackgroundColor',[1 1 1], ...
                   'Position',[360,figSize(2)-txtY-2*txtDist-7,180,txtSizeV]);
   set([txt_tempTime,chk_tempTime,txt_tempTimeEq], 'TooltipString', ...
       sprintf('Temperature(time) function format:\n... + d*t.^3 + c*t.^2 + b*t + a'));
               
   txt_norm = uicontrol('Parent',fig_Main, ...
                             'Style','text', ...
                             'String','Normalize signal to 1  ', ...
                             'HorizontalAlignment','left', ...
                             'BackgroundColor',txtColor, ...
                   'Position',[580,figSize(2)-txtY-2*txtDist-7,120,txtSizeV]);
   chk_norm = uicontrol('Parent',fig_Main, ...
                             'Style','checkbox', ...
                             'Callback',{@chk_norm_Callback}, ...
                   'Position',[705,figSize(2)-txtY-2*txtDist-1-7,15,txtSizeV+2]);
   txt_log = uicontrol('Parent',fig_Main, ...
                             'Style','text', ...
                             'String','Logarithmic scaling  ', ...
                             'HorizontalAlignment','left', ...
                             'BackgroundColor',txtColor, ...
                   'Position',[735,figSize(2)-txtY-2*txtDist-7,115,txtSizeV]);
   chk_log = uicontrol('Parent',fig_Main, ...
                             'Style','checkbox', ...
                             'Callback',{@chk_log_Callback}, ...
                   'Position',[855,figSize(2)-txtY-2*txtDist-1-7,15,txtSizeV+2]);
               
        % Button group
        backclr = [.8 .8 .8];
        bgSize = [735,565];
    bg_main = uibuttongroup('Parent', fig_Main, ...
                            'BackgroundColor', backclr,...
                            'BorderType', 'line', ...
                            'BorderWidth', 2, ...
                            'Units', 'pixels', ...
                            'SelectionChangeFcn',{@bg_main_SelectionChangeFcn}, ...
                            'Position', [150,15,bgSize(1),bgSize(2)]);
    btn_sig = uicontrol('Parent',bg_main, ...
                        'Style','togglebutton', ...
                        'String','Signal', ...
                        'Tag','sig', ...
                        'Visible','on', ...
                   'Position',[1*bgSize(1)/4-80,bgSize(2)-30,160,23]);
    btn_cor = uicontrol('Parent',bg_main, ...
                        'Style','togglebutton', ...
                        'String','Correlation', ...
                        'Tag','cor', ...
                        'Visible','on', ...
                   'Position',[2*bgSize(1)/4-80,bgSize(2)-30,160,23]);
    btn_mol = uicontrol('Parent',bg_main, ...
                        'Style','togglebutton', ...
                        'String','Molecular intensity', ...
                        'Tag','mol', ...
                        'Visible','on', ...
                   'Position',[3*bgSize(1)/4-80,bgSize(2)-30,160,23]);
    panel1 = uipanel('Parent', fig_Main, ...
                    'BackgroundColor', backclr,...
                    'BorderWidth', 2, ...
                    'BorderType', 'line', ...
                    'Units', 'pixels', ...
                   'Position', [15,150,137,340]);
    panel2 = uipanel('Parent', fig_Main, ...
                    'BackgroundColor', backclr,...
                    'BorderWidth', 2, ...
                    'BorderType', 'line', ...
                    'Units', 'pixels', ...
                   'Position', [560,578,325,80]);
               
        % Listbox
   txt_mass = uicontrol('Parent',fig_Main, ...
                            'Style','text', ...
                            'String','Mass/charge ratio', ...
                            'BackgroundColor',txtColor, ...
                  'Position',[23,figSize(2)-210,120,txtSizeV]);
    
   lst_mass = uicontrol('Parent',fig_Main, ...
                             'Style','listbox', ...
                             'Callback',{@lst_mass_Callback}, ...
                             'Min',0, 'Max',2, ...
                   'Position',[53,200,60,250]);
   chk_cormass = uicontrol('Parent',fig_Main, ...
                           'Style','checkbox', ...
                           'Callback',{@chk_cormass_Callback}, ...
                           'Enable','off', ...
                   'Position',[28,167,15,txtSizeV+2]);
   txt_cormass = uicontrol('Parent',fig_Main, ...
                          'Style','text', ...
                          'String',sprintf('Also select cor-\nrelated masses'), ...
                          'Enable','off', ...
                          'HorizontalAlignment','left', ...
                          'BackgroundColor',txtColor, ...
                          'Position',[48,160,90,txtSizeV*2]);

    
        % Axes 
    ax_plot = axes('Parent',fig_Main, ...
                   'Units','pixels', ...
                   'Position',[220,figSize(2)-575, 625,420]);
        cm = uicontextmenu('Parent', fig_Main);
        cm_save = uimenu(cm, 'Label', 'Save As Image', ...
            'Callback', {@cm_save_Callback});
        cm_exportfile = uimenu(cm, 'Label', 'Export Data to File', ...
            'Callback', {@cm_exportfile_Callback});
        cm_exportws = uimenu(cm, 'Label', 'Export Data to Matlab Workspace', ...
            'Callback', {@cm_exportws_Callback});
        figssize = get(ax_plot, 'OuterPosition');
        fig_Save = figure('Name','Save figure...', 'Visible','off', ...
            'MenuBar','none', 'NumberTitle','off', 'Color',[1,1,1], ...
            'Position',[1,1,figssize([3 4])]);
        movegui(fig_Save, 'center');
        ax_save = axes('Parent',fig_Save, ...
                   'Units','normalized', ...
                   'OuterPosition',[0 0 1 1]);
               
               % Slider
   txt_sltime = uicontrol('Parent',fig_Main, ...
                          'Style','text', ...
                          'String','Time:', ...
                          'Visible','off', ...
                          'HorizontalAlignment','left', ...
                          'BackgroundColor',txtColor, ...
                          'Position',[170,27,40,txtSizeV]);
   sl_time = uicontrol('Parent', fig_Main, ...
                       'Style', 'slider', ...
                       'Visible', 'off', ...
                       'Position', [220,25, 590,20]);
if verLessThan('matlab', '7.12')
   sl_lis = addlistener(sl_time, 'ActionEvent', ...
                                                    @sl_time_Callback);
else
   sl_lis = addlistener(sl_time, 'ContinuousValueChange', ...
                                                    @sl_time_Callback);
end
   txt_sltimeval = uicontrol('Parent',fig_Main, ...
                          'Style','text', ...
                          'String','', ...
                          'Visible','off', ...
                          'HorizontalAlignment','right', ...
                          'BackgroundColor',txtColor, ...
                          'Position',[820,27,45,txtSizeV]);
    txt_mol = uicontrol('Parent',fig_Main, ...
                            'Style','text', ...
                            'String',sprintf('Select potentially \ndesorbed molecules'), ...
                            'Visible', 'off', ...
                            'BackgroundColor',txtColor, ...
                  'Position',[23,figSize(2)-210-txtSizeV,120,txtSizeV*2]);
    txt_slmode = uicontrol('Parent',fig_Main, ...
                          'Style','text', ...
                          'String','Select plot mode', ...
                          'Visible','off', ...
                          'HorizontalAlignment','left', ...
                          'BackgroundColor',txtColor, ...
                          'Position',[580,figSize(2)-txtY-0.5*txtDist-5,100,txtSizeV]);
    bg_molmode = uibuttongroup('Parent', fig_Main, ...
                               'BackgroundColor', backclr,...
                               ...'BorderType', 'line', ...
                               'BorderWidth', 0, ...
                               'Visible', 'off', ...
                               'Units', 'pixels', ...
                               'SelectionChangeFcn',{@bg_molmode_SelectionChangeFcn}, ...
                'Position', [680,figSize(2)-63,140,45]);
    btn_mm2 = uicontrol('Parent',bg_molmode, ...
                        'Style','radiobutton', ...
                        'BackgroundColor', backclr,...
                        'String','Intensity - time', ...
                        'Tag','it', ...
                   'Position',[10,25,120,15]);            
    btn_mm1 = uicontrol('Parent',bg_molmode, ...
                        'Style','radiobutton', ...
                        'BackgroundColor', backclr,...
                        'String','Intensity - molecules', ...
                        'Tag','im', ...
                        'Position', [10,5,120,15]);

           % Table
    tab_cor = uitable('Parent',fig_Main, ...
                      'Visible', 'off', ...
                      'ColumnWidth',{27}, ...
                      'Position',[175,figSize(2)-635,685,500]);
    txt_timeint = uicontrol('Parent',fig_Main, ...
                          'Style','text', ...
                          'String','Time interval [s]', ...
                          'Visible','on', ...
                          'HorizontalAlignment','left', ...
                          'BackgroundColor',txtColor, ...
                          'Position',[580,figSize(2)-txtY-0.5*txtDist,90,txtSizeV]);
    txt_int(1) = uicontrol('Parent', fig_Main, ...
                         'Style', 'edit', ...
                         'String', '0', ...
                         'HorizontalAlignment','right', ...
                         'BackgroundColor',[1 1 1], ...
                         'Callback',{@txt_int_Callback}, ...
                   'Position',[680,figSize(2)-txtY-0*txtDist-1,40,txtSizeV+2]);
    txt_int(2) = uicontrol('Parent', fig_Main, ...
                         'Style', 'edit', ...
                         'String', '0', ...
                         'HorizontalAlignment','right', ...
                         'BackgroundColor',[1 1 1], ...
                         'Callback',{@txt_int_Callback}, ...
                   'Position',[680,figSize(2)-txtY-1*txtDist-1,40,txtSizeV+2]);
    txt_corlim = uicontrol('Parent',fig_Main, ...
                          'Style','text', ...
                          'String','Limit to interval', ...
                          'Visible','off', ...
                          'HorizontalAlignment','left', ...
                          'BackgroundColor',txtColor, ...
                          'Position',[740,figSize(2)-txtY-0.5*txtDist,85,txtSizeV]);
    chk_corlim = uicontrol('Parent',fig_Main, ...
                             'Style','checkbox', ...
                             'Callback',{@chk_corlim_Callback}, ...
                             'Visible', 'off', ...
                   'Position',[830,figSize(2)-txtY-0.5*txtDist-1,15,txtSizeV+2]);
    txt_cort = uicontrol('Parent',fig_Main, ...
                            'Style','text', ...
                            'String','Threshold value:', ...
                            'HorizontalAlignment', 'left', ...
                            'Visible', 'off', ...
                            'BackgroundColor',txtColor, ...
                  'Position', [580,figSize(2)-txtY-2*txtDist-5,90,txtSizeV]);
    txt_cortval = uicontrol('Parent', fig_Main, ...
                         'Style', 'edit', ...
                         'String', txt_cortval_default, ...
                         'Visible', 'off', ...
                         'HorizontalAlignment','right', ...
                         'BackgroundColor',[1 1 1], ...
                         'Callback',{@txt_cortval_Callback}, ...
                   'Position',[690,figSize(2)-txtY-2*txtDist-1-5,30,txtSizeV+2]);
    txt_coref = uicontrol('Parent',fig_Main, ...
                            'Style','text', ...
                            'String','Enable filter  ', ...
                            'Visible', 'off', ...
                            'HorizontalAlignment','left', ...
                            'BackgroundColor',txtColor, ...
                  'Position',[740,figSize(2)-txtY-2*txtDist-5,80,txtSizeV]);
    chk_coref = uicontrol('Parent',fig_Main, ...
                             'Style','checkbox', ...
                             'Callback',{@chk_coref_Callback}, ...
                             'Visible', 'off', ...
                   'Position',[830,figSize(2)-txtY-2*txtDist-1-5,15,txtSizeV+2]);

    [molecules, molecOk] = drawmolcontrols;
               
    sighandles = [ax_plot, txt_norm, chk_norm, txt_log, chk_log, ...
                    txt_timeint, txt_int, lst_mass, txt_mass, ...
                    chk_cormass, txt_cormass];
    corhandles = [txt_cort, txt_cortval, txt_coref, chk_coref, txt_mol, ...
                    txt_corlim, chk_corlim, txt_timeint, txt_int, ...
                    tab_cor, molecules(:)', molecOk];
    molhandles = [ax_plot, txt_mol, txt_sltime, sl_time, txt_sltimeval, ...
                    txt_slmode, bg_molmode, molecules(:)', molecOk];
    mol1handles= [txt_sltime, sl_time, txt_sltimeval];

    
    set(findall(fig_Main, 'Style', 'text'), ...
        'FontUnits', 'normalized', 'FontSize', .8);     % Enlarge font size
    set([txt_bNoiseTime, txt_mol, txt_cormass], 'FontSize', .4);
    set([molecules(:,2)], 'FontSize', .7);
    set(findall(fig_Main, 'Style', 'edit'), 'FontUnits', 'normalized');
    set(findall(fig_Main, 'Style', 'pushbutton'), 'FontUnits', 'normalized');
    set(findall(fig_Main, 'Style', 'togglebutton'), 'FontUnits', 'normalized');
    set(findall(fig_Main, 'Style', 'radiobutton'), 'FontUnits', 'normalized');
    
   % Change units to normalized so components resize automatically
   set(findall(fig_Main, '-property', 'Units'), 'Units', 'normalized');
   
   % Make the GUI visible.
   set(fig_Main, 'Visible','on');
    set(0, 'DefaultFigureHandleVisibility','on');
    set(0, 'DefaultUImenuHandleVisibility','on');
    set(0, 'DefaultUIcontrolHandleVisibility','on');
    set(0, 'DefaultAxesHandleVisibility','on');   
%% -------- end of GUI creation


%% Init commands
    %clc
    %btn_OpenFile_Callback(0, 0, 'D:\VUT\Bakalarka\Matlab\TDS.asc')
%% -------- end of init commands


%% Callbacks

    function btn_OpenFile_Callback(hObject, eventdata, file)
        if ~exist('file', 'var')
            [name,path] = uigetfile({'*.asc', 'ASCII file (*.asc)'; ...
                                     '*.*',   'All files (*.*)'});
            file = [path,name];
            if ~name, return; end
        else
            pos = strfind(file,'\');
            name = file(pos(end)+1:end);
        end
        ResetGUIelements;
        
        [r,measureDate,measureTime,cCycles] = ReadHeader(file);
        if ~r
            waitfor(warndlg('No header found.', 'Warning!'));
        else
            if r<7, waitfor(warndlg('Header parts corrupt or missing.', ...
                    'Warning!')); end
            if r >= 4
                set(txt_MeasDateVal, 'String', [measureDate ' ']);
                r = r - 4;
            end
            if r >= 2
                set(txt_MeasTimeVal, 'String', [measureTime ' ']);
                r = r - 2;
            end
            if r >= 1
                set(txt_cCyclesVal, 'String', [cCycles ' ']);
                r = r - 1;
            end               
        end
                
        datablocks = ReadMatrix(1, file);
        if isempty(datablocks)
            waitfor(errordlg('Datablocks matrix not found.', 'Error!'));
        end
        masses = getmass(datablocks);
        set(lst_mass, 'String', masses);
        set(lst_mass,'TooltipString',...
            'You can select multiple items using the <Shift> or <Ctrl> keys.');

        measurecell = ReadMatrix(2, file);
        if isempty(measurecell)
            waitfor(errordlg('Measure data not found.', 'Error!'));
            return;
        end
               
        [measureOrig,dbn] = cell2num(measurecell);
        if isempty(measureOrig)
            waitfor(errordlg('Error in data conversion.', 'Error!'));
            return;
        end
        if dbn ~= length(masses)
            measureOrig = measureOrig(:,1:length(masses)+1);
        end
        
        txt_tempTimeEq_Callback;
        peakpos = findpeak(measureOrig(:,2));
        set(txt_int(2), 'String', round(measureOrig(peakpos+10,1)));
        set(txt_int(1), 'String', round(measureOrig(peakpos-10,1)));
        recalcm('corint', [round(measureOrig(peakpos-10,1)), ...
            round(measureOrig(peakpos+10,1))], 1);
        set(fig_Main, 'Name', ['TDS Data Evaluation tool : ' name]);
        txt_bNoiseTimeVal_Callback;
    end

    function txt_bNoiseTimeVal_Callback(hObject, eventdata)
        tmp = textscan(get(txt_bNoiseTimeVal,'String'), '%d');
        if isempty(tmp{1}), return; end
        val = tmp{1};
        set(txt_bNoiseTimeVal, 'String', val);
        if val < 0 || val > 300
            warndlg('Value should be between 0 and 300', 'Warning');
        end
        recalcm('noise', val);
    end

    function txt_tempTimeEq_Callback(hObject, eventdata)
        if ~isempty(measureOrig)
            str = get(txt_tempTimeEq, 'String');
            t = measureOrig(:,1);
            try
                tempArray = eval(vectorize(str));
                set(txt_tempTimeEq, 'UserData', tempArray);
            catch err
                errordlg('Error evaluating Temperature-time function.','Error');
                return;
            end
        end
        if get(chk_tempTime, 'Value')
            recalcm('','');
        end
    end

    function chk_tempTime_Callback(hObject, eventdata)
        val = get(hObject, 'Value');
        if val
            txt_tempTimeEq_Callback;
            pause(.01);
        else
            recalcm('','');
        end
    end

    function chk_norm_Callback(hObject, eventdata)
        val = get(hObject, 'Value');
        %val = 2*val-1;  % [0,1] --> [-1,1]
        recalcm('norm',val);
    end

    function chk_log_Callback(hObject, eventdata)
        val = get(hObject, 'Value');
        recalcm('log',val);
    end

    function chk_cormass_Callback(hObject, eventdata)
        val = get(hObject, 'Value');
        if val
            lst_mass_Callback(lst_mass, 0)
        end
    end

    function txt_int_Callback(hObject, eventdata)
        interval = str2num(cell2str(get(txt_int, 'String')))';
        if isempty(interval)
            warndlg('Interval endpoints must be numeric', 'Warning!');
            return
        end
        if interval(1) > interval(2)    % Ensure that the first value ...
            switch hObject              %  is <= than the second value
                case txt_int(1)
                    set(txt_int(2), 'String', interval(1));
                case txt_int(2)
                    set(txt_int(1), 'String', interval(2));
            end
        end
        if interval(1) < 0, set(txt_int(1), 'String', 0); end
        if ~isempty(measureOrig) && interval(2) > measureOrig(end,1)
            set(txt_int(2), 'String', round(measureOrig(end,1)));
        end
        recalcm('corint', interval, ~get(chk_corlim, 'Value'));
    end

    function chk_corlim_Callback(hObject, eventdata)
        recalcm('corlim','');
    end

    function txt_cortval_Callback(hObject, eventdata)
        val = str2double(get(hObject, 'String'));
        if isnan(val)
            warndlg('Threshold value must be numeric.', 'Warning!');
            return
        end        
        if val > 1, set(hObject, 'String', 1); val = 1; end
        if val < 0, set(hObject, 'String', 0); val = 0; end
        recalcm('threshold', val);
    end

    function chk_coref_Callback(hObject, eventdata)
        val = get(hObject, 'Value');
        switch val
            case 1
                set([chk_cormass, txt_cormass], 'Enable', 'on');
            case 0
                set([chk_cormass, txt_cormass], 'Enable', 'off');
        end
        recalcm('coref',val);  % argument not used
    end

    function bg_main_SelectionChangeFcn(hObject, eventdata, tag)
        if exist('tag', 'var')
            selection = tag;
        else
            selection = get(eventdata.NewValue,'Tag');
        end
        plotch = get(ax_plot, 'Children')';
        switch  selection
            case 'sig'
                set([corhandles, molhandles], 'Visible', 'off');
                
                set(sighandles, 'Visible', 'on');
                set(cm_save, 'Enable', 'on');
                if ~isempty(plotch), legend(ax_plot, 'show'); end
                recalcm('out', 'sig');
            case 'cor'
                set([sighandles, plotch, molhandles], 'Visible', 'off');
                legend(ax_plot, 'hide');
                
                recalcm('out', 'table');
                set(cm_save, 'Enable', 'off');
                set(corhandles, 'Visible', 'on');
            case 'mol'
                set([sighandles, corhandles], 'Visible', 'off');
                
                [slmin,slmax] = deal(1,size(measureOrig,1));
                if ~slmax
                    slmax = 2;
                end
                set(sl_time, 'Min', slmin);
                set(sl_time, 'Max', slmax);
                set(sl_time, 'SliderStep', [1,10]/(slmax-slmin));
                set(sl_time, 'Value', slmin);
                set(molhandles, 'Visible', 'on');
                set(cm_save, 'Enable', 'on');
                if get(btn_mm1, 'Value') == get(btn_mm1, 'Max')
                    bg_molmode_SelectionChangeFcn(0, 0, 'im');
                else
                    bg_molmode_SelectionChangeFcn(0, 0, 'it');
                end
        end
    end

    function bg_molmode_SelectionChangeFcn(hObject, eventdata, tag)
        if exist('tag', 'var')
            selection = tag;
        else
            selection = get(eventdata.NewValue,'Tag');
        end
        switch selection
            case 'im'
                set(mol1handles, 'Visible', 'on');
                recalcm('out', 'mol');
                set([txt_log, chk_log], 'Visible', 'off');
            case 'it'
                set(mol1handles, 'Visible', 'off');
                recalcm('out', 'mol2');
                set([txt_log, chk_log], 'Visible', 'on');
        end
    end

    function lst_mass_Callback(hObject, eventdata)
        val = get(hObject, 'Value');
        cormasses = get(hObject, 'UserData');
        alsocor = get(chk_cormass, 'Value');
        if ~isempty(cormasses) && alsocor
            listboxtop = get(hObject, 'ListboxTop');
            val = cormasses{val(1)};
            set(hObject, 'Value', val);
            pause(0.01);
            set(hObject, 'ListboxTop', listboxtop);
        end
        recalcm('mass', val);
    end

    function sl_time_Callback(hObject, eventdata)
        val = round(get(hObject, 'Value'));
        recalcm('cycle', val);
    end

    function chk_molecules_Callback(hObject, eventdata)
        val = cell2mat(get(molecules(:,1), 'Value'))';
        recalcm('mols',val);
    end

    function cm_save_Callback(hObject, eventdata)
        [file,path] = uiputfile({'*.png', 'Portable Network Graphics (*.png)';...
                                 '*.bmp', 'Bitmap (*.bmp)'; ...
                                 '*.jpg', 'JPEG Image (*.jpg)';...
                                 });
        if file == 0
            return
        end
        Frm = getframe(fig_Save);
        %image(F.cdata);
        imwrite(Frm.cdata, [path, file]);
        set(fig_Save, 'Visible', 'off');
    end

    function cm_exportfile_Callback(hObject, eventdata)
        [file,path] = uiputfile({'*.csv', 'Comma Separated Values (*.csv)';...
                                 '*.*',   'All files (*.*)';...
                                 });
        if file == 0
            return
        end        
        recalcm('export', [path, file]);
    end

    function cm_exportws_Callback(hObject, eventdata)
        recalcm('export', 'matlabWS');
    end

    function btn_clg_Callback(hObject, eventdata)
       ResetGUIelements;
    end

    function btn_clc_Callback(hObject, eventdata)
       clc;
    end

    function btn_Close_Callback(hObject, eventdata)
        delete(fig_Main);
    end

%% -------- end of callback functions

%% Functions with access to GUI controls and variables

    function ResetGUIelements
     % clears global measure variables; resets GUI elements to default
     % values
        measureOrig = [];
        masses = [];
        recalcm('clear');
        set(fig_Main, 'Name', 'TDS Data Evaluation tool');
        
        set([txt_MeasDateVal,txt_MeasTimeVal,txt_cCyclesVal], 'String','');
        set(txt_bNoiseTimeVal, 'String', txt_bNoiseTimeVal_default);
        set(txt_tempTimeEq, 'String', txt_tempTimeEq_default);
        set(chk_norm, 'Value', 0);recalcm('norm',0,1);
        set(chk_log, 'Value', 0);
        set(txt_int, 'String', 0);
        set([chk_corlim, chk_coref], 'Value', 0);
        set(txt_cortval, 'String', txt_cortval_default);
        set(chk_cormass, 'Value', 0);
        set([chk_cormass, txt_cormass], 'Enable', 'off');
        set(lst_mass, 'String', '');recalcm('mass',1,1);
        set(lst_mass, 'TooltipString', '');
        set(molecules(:,1), 'Value', 1);
        plot(ax_plot,[0],[0]); legend(ax_plot);
        plot(ax_save,[0],[0]); legend(ax_save);
        set([ax_plot, tab_cor], 'UIContextMenu', []);
        cla(ax_plot);xlim(ax_plot, 'default');ylim(ax_plot, 'default');
        cla(ax_save);xlim(ax_save, 'default');ylim(ax_save, 'default');
        set(tab_cor, 'Data', []);
        set(txt_sltimeval, 'String', '');
        set(sl_time, 'Min', 'default');
        set(sl_time, 'Max', 'default');
        set(sl_time, 'SliderStep', 'default');
        set(sl_time, 'Value', 'default'); 
        set(btn_sig, 'Value', get(btn_sig, 'Max'));
        set(btn_mm2, 'Value', get(btn_mm2, 'Max'));
        bg_main_SelectionChangeFcn(0,0,'sig');
    end

    function recalcm(var, val, nocalc, noout)
     % main function; collects settings from uicontrols and uses them to
     % calculate data to plot, save etc.
     
      %% definitions
      persistent noiseint; persistent norm; persistent mass; 
      persistent output; persistent cycle; persistent corint;
      persistent threshold;
        if ~exist('nocalc', 'var'), nocalc = 0; end
        if ~exist('noout', 'var'), noout = 0; end
      
      persistent measure; persistent measureN;
      persistent cormatrix; persistent corfmatrix;
      persistent MIcell;
      noiserecalc = 0; correcalc = 0; persistent thresholdprev; mols = 0;
      molrecalc = 0; str = ''; tim=[];temp=[];
      
      %% switch var
        switch var
            case 'log'
                switch val
                    case 0
                        set([ax_plot, ax_save], 'YScale', 'linear');
                    case 1
                        set([ax_plot, ax_save], 'YScale', 'log');
                end
                return
            case 'noise'
                noiseint = val;
                noiserecalc = 1;
            case 'norm'
                norm = val;
            case 'mass'
                mass = val;
            case 'out'
                output = val;
                correcalc = 1;
            case 'cycle'
                cycle = val;
            case 'corint'
                corint = val;
                correcalc = 1;
            case 'corlim'
                correcalc = 1;
            case 'threshold'
                threshold = val;
            case 'mols'
                mols = val;
                molrecalc = 1;
            case 'export'
                switch output(1:3)
                    case 'sig'
                      if strcmp(val,'matlabWS')
                        assignin('base', 'masses', masses');
                        assignin('base', 'measure', measure');
                        disp(['Variables ''masses'' and ''measure'' ' ...
                            'exported to Matlab workspace.']);
                      else
                        [m n] = size(measure);
                        fid = fopen(val, 'w');
                        for i = 0:m
                            if i==0
                                fprintf(fid, 'Time    , ');
                                for j = 1:n-2
                                    fprintf(fid, '%13.0d, ', masses(j));
                                end
                                fprintf(fid, '%13.0d\r\n', masses(n-1));
                            else
                                fprintf(fid, '%8.3f, ', measure(i,1));
                                for j = 2:n-1
                                    fprintf(fid, '%e, ', measure(i,j));
                                end
                                fprintf(fid, '%e\r\n', measure(i,n));
                            end
                        end
                        fclose(fid);
                      end
                    case 'tab'
                        l = length(masses);
                        tmp_cormatrix = cell(l+1,l+1);
                        tmp_cormatrix{1,1} = 'Correlation';
                        tmp_cormatrix(1,2:end) = num2cell(masses');
                        tmp_cormatrix(2:end,1) = num2cell(masses);
                        tmp_cormatrix(2:end,2:end) = cormatrix;
                      if strcmp(val,'matlabWS')
                        assignin('base', 'cormatrix', tmp_cormatrix);
                        disp(['Variable ''cormatrix'' ' ...
                            'exported to Matlab workspace.']);
                      else
                        fid = fopen(val, 'w');
                        fprintf(fid, '%12s, ', tmp_cormatrix{1,1});
                        for j = 2:l
                            fprintf(fid, '%5.0d, ', tmp_cormatrix{1,j});
                        end
                        fprintf(fid, '%5.0d\r\n', tmp_cormatrix{1,l+1});
                        
                        for i = 2:l+1
                            fprintf(fid, '%12.0d, ', tmp_cormatrix{i,1});
                            for j = 2:l
                                fprintf(fid, '%5s, ', tmp_cormatrix{i,j});
                            end
                            fprintf(fid, '%5s\r\n', tmp_cormatrix{i,l+1});
                        end
                        fclose(fid);
                      end
                    case 'mol'
                        [m n] = size(MIcell);
                        tmp_MIcell = cell(m, n+1);
                        tmp_MIcell{1,1} = 'Time';
                        tmp_MIcell(2:end,1) = num2cell(measure(:,1));
                        tmp_MIcell(:,2:end) = MIcell;
                      if strcmp(val,'matlabWS')
                        assignin('base', 'MIcell', tmp_MIcell);
                        disp(['Variable ''MIcell'' ' ...
                            'exported to Matlab workspace.']);
                      else
                        fid = fopen(val, 'w');
                        fprintf(fid, '%8s, ', tmp_MIcell{1,1});
                        for j = 2:n
                            fprintf(fid, '%13s, ', tmp_MIcell{1,j});
                        end
                        fprintf(fid, '%13s\r\n', tmp_MIcell{1,n+1});
                        
                        for i = 2:m
                            fprintf(fid, '%8.3f, ', tmp_MIcell{i,1});
                            for j = 2:n
                                fprintf(fid, '%e, ', tmp_MIcell{i,j});
                            end
                            fprintf(fid, '%e\r\n', tmp_MIcell{i,n+1});
                        end
                        fclose(fid);
                      end
                end
                return
            case 'clear'
                [measure, measureN] = deal([]);
                [cormatrix, corfmatrix, MIcell] = deal({});
                [thresholdprev] = deal(0);
                return
        end
        correcalc = correcalc + noiserecalc;
        molrecalc = molrecalc + noiserecalc;
        
      %% calculations
        if ~nocalc && ~isempty(measureOrig) && ~isempty(masses)
            if noiserecalc || isempty(measure)
                [measure, k] = nonoise(measureOrig, noiseint);
                %measure(find(measure<0)) = 0;   % replace negative values with zeros
                measureN = normal(measure, 1);
            end
            
            switch output(1:3)
                case 'sig'      % Signal
            if ~noout
              if norm
                %PlotMeasure(measureN(k+1:end,:), mass, 'sig');
                PlotMeasure(measureN, mass, 'sig');
              else
                %PlotMeasure(measure(k+1:end,:), mass, 'sig');
                PlotMeasure(measure, mass, 'sig');
              end
            end
            
                case 'tab'    % Correlation
          if correcalc || isempty(cormatrix)
            if  get(chk_corlim, 'Value') && ~isequal(corint, [0,0])
                [leftb,lpos] = min(abs(measureN(:,1)-corint(1)));
                [rightb,rpos] = min(abs(measureN(:,1)-corint(2)));
                interv = [lpos, rpos];
                cormeasure = measureN(interv(1):interv(2),2:end);
            else
                cormeasure = measureN(:,2:end);
            end
            cormatrix = roundto(corrcoef(cormeasure),2);
          end
            corfilter = get(chk_coref, 'Value');
            if (corfilter && (~isequal(threshold, thresholdprev))) || ...
                    isempty(corfmatrix) || correcalc
              [m n] = size(cormatrix);
              corfmatrix = cormatrix;
              for i = 1:m
                  for j = 1:n
                      item = str2double(corfmatrix{i,j});
                      if item >= threshold
                          corfmatrix{i,j} = 'XX';
                      else
                          corfmatrix{i,j} = '';
                      end
                  end
              end
                % create correlation map:
              cormap = cell(m,1);
              for i = 1:m
                  tmp = [];
                  for j = 1:n
                      if isequal(corfmatrix{i,j}, 'XX')
                          tmp = [tmp, j];
                      end
                  end
                  cormap{i} = tmp;
              end
              set(lst_mass, 'UserData', cormap);
              set(chk_cormass, 'Value', 0);
              thresholdprev = threshold;
            end
            if ~noout
                if ~corfilter
                    set(tab_cor, 'ColumnWidth',{27});
                    set(tab_cor, 'Data', cormatrix);
                    set(tab_cor, 'UIContextMenu', cm);
                else
                    set(tab_cor, 'ColumnWidth',{16});
                    set(tab_cor, 'Data', corfmatrix);
                end
                set(tab_cor, 'RowName', masses);
                set(tab_cor, 'ColumnName', masses);
            end
            
                case 'mol'      % Molecular intensity
                    if ~isempty(MIpeaks)
            if isempty(mols) || isequal(mols, 0)
                mols = cell2mat(get(molecules(:,1), 'Value'))';
            end
            if molrecalc || isempty(MIcell)
                MIcell = calcMI(measure, MIpeaks([1, find(mols)+1],:), masses);
            end
            if ~noout && ~isempty(MIcell)
                if ~isequal(output, 'mol2')
                    PlotMeasure(MIcell, cycle, 'mol');
                    timestr = [num2str(round(measureOrig(cycle,1))),' s'];
                    set(txt_sltimeval, 'String', timestr);
                    switch get(chk_tempTime, 'Value')
                      case 0
                        legend(ax_plot, ['Relative time: ' timestr]);
                        legend(ax_save, ['Relative time: ' timestr]);
                      case 1
                        tempArray = get(txt_tempTimeEq, 'UserData');
                        legend(ax_plot, ['Temperature: ' ...
                            num2str(round(tempArray(cycle))) '°C']);
                        legend(ax_save, ['Temperature: ' ...
                            num2str(round(tempArray(cycle))) '°C']);
                    end
                else
                    PlotMeasure(MIcell, [], 'mol2');
                end
            end
                    elseif ~noout
            cla(ax_plot);xlim(ax_plot, 'default');ylim(ax_plot, 'default');
            cla(ax_save);xlim(ax_save, 'default');ylim(ax_save, 'default');
            plot(ax_plot,[0],[0]); plot(ax_save,[0],[0]);            
            legend(ax_plot, 'Peak database not available.', 'Location', 'Best');
            legend(ax_save, 'Peak database not available.', 'Location', 'Best');
                    end
            end
        end
    end

    function PlotMeasure(measureMatrix, cr, type)
     % plots desired data
        ax_handle =  [ax_plot, ax_save];
        if get(chk_tempTime, 'Value')
            tempArray = get(txt_tempTimeEq, 'UserData');
            xlab = 'Temperature (°C)';
        else
            tempArray = measureOrig(:,1);
            xlab = 'Time (s)';
        end
        
        switch type
            case 'sig'      % Signal
      for i = 1:length(ax_handle)
        plot(ax_handle(i), tempArray, measureMatrix(:,cr+1));
        set(get(ax_handle(i),'XLabel'),'String',xlab);
        set(get(ax_handle(i),'YLabel'),'String','Current (A)');
        if max(max(measureMatrix(:,2:end)))==1
            set(get(ax_handle(i),'YLabel'),'String','Normalized current');
        end
        xm = tempArray(end,1);
        ym = max(max(measureMatrix(:,cr+1)))+eps;
        xlim(ax_handle(i), [0,xm]);
        ylim(ax_handle(i), [0,ym*1.1]);
        legend(ax_handle(i), num2str(masses(cr)));
        if ax_handle(i) == ax_plot
            set(ax_handle(i), 'UIContextMenu', cm);
        end
        val = get(chk_log, 'Value');     % check whether to use log scaling
        switch val
            case 0
                set(ax_handle(i), 'YScale', 'linear');
            case 1
                set(ax_handle(i), 'YScale', 'log');
        end
      end

            case 'mol'      % Molecular intensity
      for i = 1:length(ax_handle)
          tmp = cell2str(measureMatrix(1,:));
          [m n] = size(tmp);
          xlab = '';
          for j = 1:m
              xlab = [xlab, strtrim(tmp(j,:)), '; '];
          end
          xlab = xlab(1:end-2);
        bar(ax_handle(i), cell2mat(measureMatrix(cr+1,:)));
        set(get(ax_handle(i),'XLabel'),'String',xlab)
        set(get(ax_handle(i),'YLabel'),'String','Intensity (arb. unit)');
        ym = max(cell2mat(measureMatrix(cr+1,:)))+eps;
        %ym = max(max(cell2mat(measureMatrix(2:end,:))))+eps;    %uncomment
                                    %for constant ylim (regardless of time)
        ylim(ax_handle(i), [0,ym*1.1]);
      end

            case 'mol2'
      for i = 1:length(ax_handle)
        plot(ax_handle(i), tempArray, cell2mat(measureMatrix(2:end,:))');
        set(get(ax_handle(i),'XLabel'),'String',xlab)
        set(get(ax_handle(i),'YLabel'),'String','Intensity (arb. unit)');
        ym = max(max(cell2mat(measureMatrix(2:end,:))))+eps;
        xm = tempArray(end);
        ylim(ax_handle(i), [0,ym*1.1]);
        xlim(ax_handle(i), [0,xm]);
        legend(ax_handle(i), measureMatrix(1,:));
        val = get(chk_log, 'Value');     % check whether to use log scaling
        switch val
            case 0
                set(ax_handle(i), 'YScale', 'linear');
            case 1
                set(ax_handle(i), 'YScale', 'log');
        end
      end
        end  
    end

    function [checkhandles okhandle] = drawmolcontrols
     % draws checkboxes, texts and pushbutton in molecular intensity tab
        if isempty(MIpeaks)
            checkhandles = [];
            okhandle = [];
            return;
        else
            [m n] = size(MIpeaks);
            checkhandles = zeros(m-1,2);
            c1 = round((m-1)/2);
            for j = 0:1
              for i = 1:c1
                  if j*c1+i+1 <= m
               checkhandles(i+j*c1,1) = uicontrol('Parent', fig_Main, ...
                        'Style','checkbox', ...
                        'Visible','off', ...
                        'Value', 1, ...
                        'Position',[22+j*65,figSize(2)-235-1-i*20,15,txtSizeV+2]);
               checkhandles(i+j*c1,2) = uicontrol('Parent',fig_Main, ...
                        'Style','text', ...
                        'String',MIpeaks{j*c1+i+1,1}, ...
                        'Visible','off', ...
                        'HorizontalAlignment','left', ...
                        'BackgroundColor',txtColor, ...
                   'Position',[40+j*65,figSize(2)-235-i*20,40,txtSizeV]);
                  end
              end
            end
            okhandle = uicontrol('Parent', fig_Main, ...
                        'Style','pushbutton', ...
                        'Visible','off', ...
                        'String', 'Ok', ...
                        'Callback',{@chk_molecules_Callback}, ...
                        'Position',[43,figSize(2)-265-1-i*20,80,22]);
        end
    end
%% -------------------------------------
end


%% Other functions

function [ret, measureDate, measureTime, cCycles] = ReadHeader(file)
% reads measureDate, measureTime, cCycles from file
  ret = 0;
  [measureDate, measureTime, cCycles] = deal('');
  fid = fopen(file);
    cline = ' '; c = [];
    while ischar(cline) && isempty(c)
        cline = fgetl(fid);
        c = strfind(upper(cline), 'DATE');
    end
    if length(c) == 1  && length(cline) >= c + 12
        p = get_pos(cline(c:end))+c-1;
        if ~isempty(p)
            measureDate = strtrim(cline(p(1):p(2)));  % Measure Date
            ret = ret + 1;
        end
    end
    
    frewind(fid);cline = ' ';c = [];
    while ischar(cline) && isempty(c)
        cline = fgetl(fid);
        c = strfind(upper(cline), 'TIME');
    end
    if length(c) == 1 && length(cline) >= c + 11
        p = get_pos(cline(c:end))+c-1;
        if ~isempty(p)
            measureTime = strtrim(cline(p(1):p(2)));  % Measure Time
            ret = ret + 2;
        end
    end

    frewind(fid);cline = ' ';c = [];
    while ischar(cline) && isempty(c)
        cline = fgetl(fid);
        c = strfind(upper(cline), 'CONVERTED CYCLES');
    end
    if length(c) == 1
        p = get_pos(cline(c:end))+c-1;
        if ~isempty(p) 
            cCycles = strtrim(cline(p(1):p(2)));      % Converted cycles
            ret = ret + 4;
        end
    end
  fclose(fid);
end

function pos = get_pos(str)
% returns specific character positions in str (for file header analysis)
    p = strfind(str, char(9));
    if ~numel(p)
        pos = [];
        return
    end
    i=1;
    while numel(p)>i && p(i+1)==p(i)+1, i=i+1; end       
       % p(i) = last tab char. position of the first whitespace char. group
    q = [strfind(str(p(i)+1:end), char(9)) ...
        strfind(str(p(i)+1:end), char(13)) ...
        strfind(str(p(i)+1:end), char(32))];
    if isempty(q), q = length(str)-p(i); end
    q = sort(q);  % p(i)+1 + q(1) = first whitespace/newline char. after p(i)
    pos = [p(i)+1, p(i)+q(1)];
end

function cellArray = ReadMatrix(i, file)
% reads matrices (datablocks, measure) from file
% returns read data as cell arrays
    cellArray = [];
    fid = fopen(file);
        cline = ' ';
        switch i                % get cell matrix position in file
            case 1
                while ischar(cline) && (length(cline) < 5 || ...
                        ~strcmp(cline(1:5), '''0/0'''))
                    cline = fgetl(fid);
                end
            case 2
                while ischar(cline) && (length(cline) < 20 || ...
                        ~strcmp(cline(1:2), ['1' char(9)]))
                    cline = fgetl(fid);
                end
            otherwise
                fclose(fid);
                return
        end
        
        r = 1;
        while ischar(cline) && ~strcmp(cline, '')
            if i == 1 && ~strcmp(cline(1:3), '''0/'), break; end
            cellArray{r,1} = cline;
            r = r + 1;
            cline = fgetl(fid);
        end
    fclose(fid);
end

function peaks = readPeaks(file)
% returns peak database info for molecular intesity calculations
    fid = fopen(file);
    if fid ~= -1
        r = 1;
        cline = fgetl(fid);
        cols = strfind(cline, ',');
        pattern = '%s';
        for i = 1:length(cols)
            pattern = [pattern '%f'];
        end
        while ischar(cline) && ~strcmp(cline, '')
            ccline = textscan(cline, pattern, 'delimiter',',');
            for i = 1:length(cols)+1
                peaks{r,i} = ccline{i};
            end
            r = r + 1;
            cline = fgetl(fid);
        end
        fclose(fid);
    else
        warndlg(['File ' file ' not found. Could not read data for molecular intensity calculations.'],'Warning');
        peaks = [];
    end
end

function massArray = getmass(DBmatrix)
% calculates mass array from datablocks cell array
    [m n] = size(DBmatrix);
    massArray = zeros(m,1);
    warn = 0;
    for i = 1:m
        p = strfind(DBmatrix{i,1}, char(9));
        if length(p)<2 && ~warn
            waitfor(warndlg('Could not load mass/charge values.','Warning!'));
            warn = 1;
        else
            str = DBmatrix{i,1}(p(1)+1:p(2)-1);
            massArray(i) = cell2mat(textscan(str, '%f'));
        end
    end
        
end

function [matrix, dbn] = cell2num(cellArray)
% converts cellArray to numeric array (matrix)
    [m,n] = size(cellArray);
    m = max(m,n);
    tabsprev = strfind(cellArray{1,1}, char(9));
    for i = 1:m
        tabs = strfind(cellArray{i,1}, char(9));
        if length(tabs)~=length(tabsprev)
            matrix = [];
            return
        end
        tabsprev = tabs;
    end
    pattern = '%*d%*s%*s';
    for i = 1:length(tabs)-3
        pattern = [pattern '%f'];
    end
    
    mat{m, 1} = 0;
    for i = 1:m
        mat{i,1} = textscan(cellArray{i,1}, pattern, 'delimiter','\t');
    end
    matrix = zeros(m,length(tabs)-3);
    for i = 1:m
        matrix(i,:) = cell2mat(mat{i,1});
    end
    dbn = length(tabs)-4;
end

function [measureout, k] = nonoise(measurein, int) 
% calculates and subtracts noise from measurein matrix
    i = 1;
    [m n] = size(measurein);
    while measurein(i,1) < int
        i = i+1;
        if i > m
            i = i+1;
            break
        end
    end
    
    k=i-2;
    measureout = measurein;
    if int <= 0
        if int==0
            k=0;
        end
        return;
    end

    bNoise = zeros(1,n);
    for i = 2:n
        bNoise(i) = mean(measurein(1:k,i));
    end
    for i = 1:m
        measureout(i,:) = measureout(i,:) - bNoise;
    end
end

function measurenorm = normal(measurein, inv)
% normalizes measurein matrix (inverse normalization optional)
    persistent ampl
    
    [m n] = size(measurein);
    measurenorm = measurein;
    if inv == 1 && max(max(measurein(:,2:end)))~=1
        ampl = max(measurein);      %1D array of max values of each column
        for i = 2:n
            measurenorm(:,i) = measurein(:,i)./(ampl(i));
        end
    elseif inv==-1 && max(max(measurein(:,2:end)))==1
        if isempty(ampl) || ~(all(ampl >= 0))
            waitfor(errordlg('Error in inverse normalization', 'Error!'));
            return;
        else
            measurenorm(:,2) = measurein(:,2).*(ampl(2));
        end
    end
    
end

function MIcell = calcMI(measureMatrix, MIpeaks, masses)
% calculates molecular intensity matrix
    if isempty(masses)
        waitfor(errordlg(['Mass/charge ratio not available. ', ...
            'Cannot calculate molecular intensity.'],'Error'));
        MIcell = [];
        return
    end
    [m n] = size(MIpeaks);
    if m<=1
        waitfor(errordlg(['Peak data not available / no molecules ', ...
            'selected.'],'Error'));
        MIcell = [];
        return
    end   

    MIpeaksm = cell2mat(MIpeaks(2:end,2:end));
    for i = 1:n-1                       % Normalize MIpeaksm columns
        s = sum(MIpeaksm(:,i));
        if s, MIpeaksm(:,i) = MIpeaksm(:,i)./s; end
    end
    pos = zeros(1,n-1);
    for i = 2:n
        for j = 1:length(masses)
            if masses(j) == MIpeaks{1,i}
                pos(i-1) = j;
                break
            end
        end
    end
    if nnz(pos) ~= n-1
        %warndlg(['Measure data does not contain all relevant masses. ', ...
                %'Molecular intensity map might be inaccurate.'], 'Warning');
    end
    [p q] = size(measureMatrix);
    MIcell = cell(p+1, m-1);
    for i = 1:m-1
        MIcell{1,i} = MIpeaks{i+1,1}{1};
    end
    for j = 2:p+1
        for i = 1:m-1
            MIcell{j,i} = dot(measureMatrix(j-1,nonzeros(pos)+1),MIpeaksm(i,find(pos)));
        end
    end
end

function rounded = roundto(matrix, k)
% rounds all elements of input matrix to k decimals
    [m n] = size(matrix);
    format = ['%0.',num2str(k),'f'];
    rounded = cell(m,n);
    for i = 1:m
        for j = 1:n
            if matrix(i,j) == 1
                rounded{i,j} = '1';
            else
                rounded{i,j} = sprintf(format, matrix(i,j));
            end
        end
    end
end

function str = cell2str(cellArray)
% converts cell array to array of strings
    [m,n] = size(cellArray);
    if isempty(cellArray)
        str = '';
        return
    elseif m~=1 && n~=1
        str = 0;
        return
    end
    maxLen = 0;
    for i = 1:max(m,n)
        l = length(cellArray{i});
        if l > maxLen maxLen=l; end
    end
    str = zeros(max(m,n),maxLen);
    for i = 1:max(m,n)
        str(i,:) = [cellArray{i} blanks(maxLen-length(cellArray{i}))];
    end
    str = char(str);
end

function peakpos = findpeak(desorptionArray)
% returns peak position in desorptionArray
    desorptionArray = desorptionArray(1:round(2*end/3));
    m = max(desorptionArray);
    peakpos = find(desorptionArray >= m);
end 

function defEq = getdefTT(file)
% gets default Temperature-time function from file
% if not found use hardcoded default
    default = '775/3600*t+25';
    fid = fopen(file);
    if fid ~= -1
        cline = fgetl(fid);
        if ischar(cline)
            defEq = cline;
            fclose(fid);
            return;
        end
        fclose(fid)
    end
    defEq = default;
end
%% ---------------