function SN
% SN   Processing of SN-curves groups
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The function SN operates in interaction with a user. It enables to process 
% datawith exponential character, namely of SN curves obtained during long
% term fatigue life measurements of following types:
%   - S-N curves of standard uniaxial harmonic tests
%   - RMS(S)-Nb curves of random uniaxial tests, S = process or its peaks
%   - RMS(S)-Nb curves of random multiaxial tests, S = sigma-d or its peaks
%   - more SN curves, parallel or crossed.
%
% The function requires the following functions:
%   inp         for keyboard imput with default value(s):
%                 www.mathworks.com/matlabcentral/fileexchange/9033
%   fig         for progamm placing figure window:
%                 www.mathworks.com/matlabcentral/fileexchange/9035
%   separator   for creating separating lines in a record:
%                 www.mathworks.com/matlabcentral/fileexchange/11725
%   closejob    for saving protocol an figures
%                 www.mathworks.com/matlabcentral/fileexchange/22261
%   deal2       for multiple parameter assignments
%                 www.mathworks.com/matlabcentral/fileexchange/32547

% Miroslav Balda
% miroslav AT balda DOT cz
% 2009-07-08    v 1.0   SNplotregtest pro zkoušky SNplotreg
% 2009-11-24    v 1.1   zmìnìno na obecné zadání skupin SN køivek SNmgroups
% 2009-11-27    v 1.2   modifikace na ekvidistantní pøímky v loglog souø.
% 2010-03-05    v 1.3   zlepšení grafického výstupu, zmìna datové struktury
% 2010-04-20    v 1.4   Introduced group-colors, legend NE-outside.
% 2010-06-01    v 1.5   More user's keyboard control.
% 2011-04-20    v 2.0   Total reconstruction of the program for processing
%                       both parallel or crossed SN curves
% 2011-05-09    v 2.1   Formal changes of text outputs.
% 2011-05-19    v 2.2   Changes in data format for slab a Nlab
% 2011-07-26    v 2.3   Changed into the primarily function and
%                       subfunctions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

clc
clear all
close all
diary on
diary off
if exist('diary.','file'), delete('diary'); end

act  = pwd;                         %   actual directory
name = inp('Task name ',' ');       %   short name of the current task
Titl = [name '_ '];
colr = inp('barvy rgb ','brgmck');  %   barvy svazkù
ncol = 1;                           %   index barvy svazkù
diary on;                           %   Start recording 
separator([name, '   ' date],'@',30')

cros = strcmpi(inp('crossed SN','yes'),'yes');
figpos = inp('fig pos   ',4,'%3d');

fig(figpos);                %   SET FIGURE POSITION AT RIGHT-BOTTOM
drawnow
commandwindow                       %   display command window
legd = {};                          %   cell array of legend item names
m = 0;                              %   row #-1 for storing [s,N]
A = zeros(0,1);                     %   Prázdná matice s 1 sloupcem
b = zeros(0,1);                     %   prázdný sloupec pravých stran
C = zeros (2,0);                    %   store for c
nc = 0;

while 1                     %   ********* CYKLUS SVAZKÙ SN *********
    k = 0;
    l = 1;
    clr = colr(ncol);
    while l                     %   ***** CYKLUS SN VE SVAZKU *****
        cd('Data');
        pth  = 0;                   %   path initiation
        while pth==0                %   wait for a file
            [file,pth] = uigetfile({'*.m'},'Pick a file');
            %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        end
        cd(act)
        if strcmp(file,'ZZ.m'), pth=0; break, end
%                                   %   vyprázdni parametry;
        [sa,Na,str,xlab,ylab,stick,Ntick,slab,Nlab] = deal2;
        typ = 'LS fit';
        eval('run([pth file])');    %   ***** input data file *****
%       ~~~~~~~~~~~~~~~~~~~~~~~     %   naplní parametry daty
        if ~isempty(str)
            if length(str)==1
                str = [str clr];    %   barevný marker
            end
        end
    
        l = length(sa);             %   poèet øádek v daném mìøení
        if l>0
            sa = sa(:);
            Na = Na(:);
            saNa(k+1:k+l,:) = [sa,Na];% doplnìní dílèí matice
            k = k+l;
            c = SNdraw([sa,ones(l,1)],Na,str);  %   pot points & regression
%           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            legd = [legd, {typ}];
            if any(sa<0),
                legd = [legd, {typ ' out'}];
            end
        else                        %   konec svazku SN køivek
%                               GRID    ----------------------
            if ~isempty(stick)
                set(gca,'XMinorGrid','off',...
                        'XMinorTick','off',...
                        'MinorGridLineStyle','none');
                slim = [stick{1}(1), stick{end}(end)];
                Nlim = [Ntick{1}(1), Ntick{end}(end)];
                set(gca,'XLim',Nlim, 'XTick',[Ntick{:}],...
                        'YLim',slim, 'YTick',[stick{:}]);

                slab = testcell(slab,stick);
                if ~isempty(slab), set(gca,'YTickLabel',slab), end
                Nlab = testcell(Nlab,Ntick);
                if ~isempty(Nlab), set(gca,'XTickLabel',Nlab), end
    
                labF = fsfw(11,'bold');     %   Font size & font weight
                if ~exist('xlab','var') || isempty('xlab')
                    xlab = 'N  [-]'; 
                end
                xlabel(xlab,labF{:});
                if ~exist('ylab','var') || isempty('ylab')
                    ylab = '\sigma   [MPa]'; 
                end
                ylabel(ylab,labF{:});

                A  = blkdiag(A,ones(k,1));  %   => zaèátek pro regresi
                A(m+1:m+k,1) = saNa(1:k,1);
                b(m+1:m+k)   = saNa(1:k,2);
                m = m+k;
                c = SNdraw(A,b,str);        %   pot points & regression
%               ~~~~~~~~~~~~~~~~~~~
                if cros
                    nc = nc+1;
                    C(1,nc) = c(1);
                    C(2,nc) = c(2);
                else
                    nc= size(A,2)-1;
                    C(1,1:nc) = c(1);
                    C(2,1:nc) = c(2:end);
                end
            end
            legd = [legd, {typ}];   %   doplnìní jména položky do legd
        end % if

        if typ(1)=='L', typ = 'regr'; end
        for j = 2:length(c)         %   Výstup regresních funkcí
            fprintf('\n  %s     log N = %7.4f%+8.4f.log sigma_d\n',...
                typ, c(j),c(1));
        end
        separator(file,'-',30);
        drawnow
        if cros
            A = zeros(0,1);
            b = A;
            m = 0;
        end
    end                         %   ***** KONEC CYKLU SN VE SVAZKU *****
    if pth==0, break, end

    Xlim = get(gca,'Xlim');     %   Falešná èára pro legendu
    Ylim = get(gca,'Ylim');
    loglog([Xlim(1)+.1,Ylim(1)-.1],[Xlim(1)+.2,Ylim(1)-.1],clr,...
        'LineWidth',1.5)
    ncol = ncol+1;              %   Inkrementace barvy
    if ~strcmp(inp('Continue?   ','yes'),'yes'), break, end
    
end                         %   ********* KONEC CYKLU SVAZKÙ SN *********
if pth==0, return, end

nk = size(C,2);
for k = 1:nk                %   CYCLE OF SN CURVES
    N  = @(ss) 10.^C(2,k)*ss.^C(1,k); %   Anonym. function for N(s)
    Ylim = get(gca,'Ylim');
    sr = [Ylim(1);Ylim(end)];
    loglog(N(sr),sr,colr(k),'LineWidth',1.5);%  regression line
    legend(gca,'toggle')
end                         %   END OF THE CYCLE OF SN CURVES
grid on;
hold on;
                            %   TITLE:
titF = fsfw(11,'bold');     %   Font size & weight for title
if strcmp(inp('Write eqns? ','yes'),'yes')
    if cros
        lc = size(C,2)+1;
    else
        lc = length(c);
    end
    Titl = [Titl,' - ',date];
    for k = 2:lc
        if cros
          Titl = [Titl,...
          [sprintf('\nlog N = %7.4f%+8.4f',...
            C(2,k-1),C(1,k-1)) '.log \sigma_{d}']];
        else
          Titl = [Titl,...
          [sprintf('\nlog N = %7.4f%+8.4f',c(k),c(1)) '.log \sigma_{d}']];
        end
    end
    title(Titl,titF{:});
end
                            %   LEGEND:
where = inp('where legend','NorthEastOutside');
legend(legd, 'Location', where) % LEGENDA
cd(act)
                            %   SN TEXT:
while 1
    txt = inp('Insert text ','0'); % text k èáøe SN
    if txt=='0', break, end
    gtext(txt,titF{:})
end
                            %   SAVE
txt = ['{' '''fig''' ',' '''png''' ',' '''eps''' ',' '''pdf''' '}'];
job = inp('save fig    ',txt);    %   enter cell array OR real vector
if length(job)>1
    job = eval(job);
    if ~ischar([job{:}])
        txt = eval(txt);
        job = txt([job{:}]);
    end
end
diary off
if length([job{:}]>1)
    closejob(name,{gcf},job,'RecFig','RecFig');
    %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
end
%--------------------------------------------------------------
function [c,L] = SNdraw(varargin)
%   SNDRAW   Plot points of SNcurve with markers
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%   The function is designated for processing of fatigue test data into a
%   diagram in log-log axes and finding regression coefficiets of a fitted
%   straight lineof the form
%       log10(N) = c(2) +c(1)*log10(sa),
%   which corresponds to the function
%       N = 10^c(2)*sa.^c(1);
%
% Input parameters (in varargin):
%   A       Matrix [sa, ones(length(sa),1)], where
%       sa  vector of either stress|strain amplitudes or their RMS values
%   b       = Na,  where
%       Na  vector of numbers of cycles or blocks of cycles to failure
%   str     string of max 3 chars for line type as in plot function
%
% Ouput parameter:
%   c       vector of SN curve parameters:  
%
% Other requirements:
%   deal2       function for transfering of variables, FEX file at
%               www.mathworks.com/matlabcentral/fileexchange/@@@@@@@@@@@@
%   fsfw        user's function for setting font parameters
%
% Syntax:
%   SNdraw;                    %   display help   
%   c = SNdraw(sa,Na);         %   plot points (N,sa) and regr. line
%   c = SNdraw(sa,Na,str);     %   ditto with the use of str

% Miroslav Balda
% miroslav AT balda DOT cz
% 2008-05-22    v 1.0   unnpublished script SNcurve.m
% 2009-07-08    v 1.1   function SNdiags.m with many improvements
% 2009-11-30	v 1.2	function SNdraw.m for more bunches of SN curves
% 2010-03-06    v 1.3   Complete reconstruction of the function
% 2010-04-20    v 1.4   Introduced group-colors
% 2011-04-20    v 1.5   Simplified version of SNdraw
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

c=[];
if nargin==0, help SNdraw, return, end
if nargin<2
    error('The function should have at least 2 input parameters!')
end

[A,b,str] = deal2(varargin{:});
%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
L  = A(:,1)>0;
sa = abs(A(:,1));
Na = b(:);
if ~isempty(str) %              PLOTTING    ------------------- points
    loglog(Na(L),sa(L),str, Na(~L),sa(~L),['>' str(2)]);
    hold on
end
%                               REGRESSION  -------------------   c
A(:,1) = log10(sa);
b = log10(Na);
c = A(L,:)\b(L);                    %   Regression coeffs
N = @(ss) 10.^c(2:end)*ss.^c(1);    %   Anonym. function for N(s)
   
%                               TABLE       -------------------
fprintf('    k        sa          Na          Nr           dN       %%\n\n');
for k = 1:length(Na)
    if L(k)
        Nrk = A(k,2:end)*N(sa(k));
    else
        Nrk = NaN;
    end
    dN  = Nrk-Na(k);
    fprintf('%5g %11.2f %11.2f %11.2f %11.2f %8.2f\n',...
        k, sa(k), Na(k), Nrk, dN, dN/Nrk*100);
end
%--------------------------------------------------------------
function c = testcell(a,b)
%   TESTCELL Compare cell arrays a and b and complement missing items by ''
c = a; 
A = [a{:}];
B = [b{:}];
if length(a)~=length(b)
    [w,I] = ismember(A,B);
    c = {''};  e = {''};
    for k=1:length(B)
        if ismember(k,I)
            c=[c {B(k)}];
        else
            c=[c e];
        end
    end
end
%--------------------------------------------------------------
function fopt = fsfw(size,weight)
%   FSFW    Set font size and weight
fopt = {'FontSize',size,'FontWeight',weight};
%--------------------------------------------------------------
