Home > vbmeg > functions > tool_box > dmri_processor > functions > util > saveascii.m

saveascii

PURPOSE ^

SAVEASCII Save/display a matrix with specific format for each column.

SYNOPSIS ^

function [X,FULLFMT] = saveascii(X,varargin)

DESCRIPTION ^

SAVEASCII   Save/display a matrix with specific format for each column.

   SYNTAX:
                   saveascii(X)                 % Displays
                   saveascii(X,...,FMT)
                   saveascii(X,...,DLM)
                   saveascii(X,FILE,...)        % Saves
                   saveascii(X,FILE,...,'a')    % Appends
     [Y,FULLFMT] = saveascii(...); 

   INPUT:
     X    - 2-dimensional numeric, logical or string array with Ncol
            columns to be saved/display, with/without NaNs, or a vector of
            cell of strings.
     DLM  - One or Ncol-1 strings on a cell specifying the delimiter(s)
            between every/each pair if columns.
            DEFAULT: {' '} or {''} (the latter if X is char)
     FMT  - One or Ncol integers in a vector specifying the PRECISION for
            every/each column, or One or Ncol strings in a cell specifying
            its format(s). See NOTE below.
            DEFAULT: '% 8.7e' or '%c' (the latter if X is char)
     FILE - File name or identifier specifying the output file.
            DEFAULT: not used (just displays)
     'a'  - Appends to the given FILE in text mode. Use 'w -i' to active a
            OVERWRITE warning. See NOTE below.
            DEFAULT: 'w' (creates/OVERWRITES! the given FILE in text mode)

   OUTPUT (all optional):
     Y       - Matrix X converted to a string with specified format(s) and
               delimiter(s). 
     FULLFMT - Format used to save/dislay the matrix. If X is a cell of
               strings, this is also a cell of strings without the End of
               Line.

   DESCRIPTION:
     This program saves/displays a matrix array by using SPRINTF/FPRINTF
     with specific format (FMT) and delimiter (DLM) for every or EACH
     column in a very handy way, which is the mayor difference with SAVE
     or DLMWRITE function.

     The point of this program is to allow the user to save/display any
     numeric or char matrix as easy as posible without messing with the
     appropiate format ('%...') to do it, only with the precision (if is
     numerical). See the EXAMPLE below.

   NOTE:
     * Optional inputs use its DEFAULT value when not given or [].
     * Optional outputs may or not be called.
     * FMT and DLM may be a single string.
     * When FMT is used as precision integers, negative ones indicates to
       treat column(s) of X as integers rounded up to those significant
       digits to the left!
     * ADDITIONAL NOTES are included inside this file.

   EXAMPLE:
     x = [    1    2    pi 
              4  NaN     6 
           75.4  Inf   8.5 ];
     % Display with 3 significant decimals.
       saveascii(x,3)
         % RETURNS:
         %  1.000  2.000  3.142
         %  4.000    NaN  6.000
         % 75.400    Inf  8.500
         %
     % Display with specific significant decimals.
       saveascii(x,[-1 2 0])
         % RETURNS:
         %  0 2.00 3
         %  0  NaN 6
         % 80  Inf 9
         %
     % Displays with ' hello ' and ' bye ' as delimiter.
       saveascii(x,{' hello ',' bye '},2)
         % RETURNS:
         %  1.00 hello  2.00 bye  3.14
         %  4.00 hello   NaN bye  6.00
         % 75.40 hello   Inf bye  8.50
         %
     % Saves on 'saveascii_demo.txt' with heading.
       FILE = 'saveascii_demo.txt';
       saveascii('% Demo file'                   ,FILE)
       saveascii(['%  Pi = ' saveascii(pi,3) ';'],FILE,'a')
       saveascii(x                               ,FILE,'a',0)
       edit(FILE)
       demo = load(FILE)
         % RETURNS:
         % demo =
         % 
         %      4   NaN     6
         %     75   Inf     9
         %
     % NOTE: see how the heading is ignored by the LOAD function.
        
   SEE ALSO:
     SAVE, FPRINTF, SPRINTF, DLMWRITE, CSVWRITE, FOPEN, STR2DOUBLE,
     STR2NUM, NUM2STR
     and
     READLINE by Carlos Vargas
     at http://www.mathworks.com/matlabcentral/fileexchange


   ---
   MFILE:   saveascii.m
   VERSION: 6.2 (Oct 30, 2009) (<a href="matlab:web('http://www.mathworks.com/matlabcentral/fileexchange/authors/11258')">download</a>)
   MATLAB:  7.7.0.471 (R2008b)
   AUTHOR:  Carlos Adrian Vargas Aguilera (MEXICO)
   CONTACT: nubeobscura@hotmail.com

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function [X,FULLFMT] = saveascii(X,varargin)
0002 %SAVEASCII   Save/display a matrix with specific format for each column.
0003 %
0004 %   SYNTAX:
0005 %                   saveascii(X)                 % Displays
0006 %                   saveascii(X,...,FMT)
0007 %                   saveascii(X,...,DLM)
0008 %                   saveascii(X,FILE,...)        % Saves
0009 %                   saveascii(X,FILE,...,'a')    % Appends
0010 %     [Y,FULLFMT] = saveascii(...);
0011 %
0012 %   INPUT:
0013 %     X    - 2-dimensional numeric, logical or string array with Ncol
0014 %            columns to be saved/display, with/without NaNs, or a vector of
0015 %            cell of strings.
0016 %     DLM  - One or Ncol-1 strings on a cell specifying the delimiter(s)
0017 %            between every/each pair if columns.
0018 %            DEFAULT: {' '} or {''} (the latter if X is char)
0019 %     FMT  - One or Ncol integers in a vector specifying the PRECISION for
0020 %            every/each column, or One or Ncol strings in a cell specifying
0021 %            its format(s). See NOTE below.
0022 %            DEFAULT: '% 8.7e' or '%c' (the latter if X is char)
0023 %     FILE - File name or identifier specifying the output file.
0024 %            DEFAULT: not used (just displays)
0025 %     'a'  - Appends to the given FILE in text mode. Use 'w -i' to active a
0026 %            OVERWRITE warning. See NOTE below.
0027 %            DEFAULT: 'w' (creates/OVERWRITES! the given FILE in text mode)
0028 %
0029 %   OUTPUT (all optional):
0030 %     Y       - Matrix X converted to a string with specified format(s) and
0031 %               delimiter(s).
0032 %     FULLFMT - Format used to save/dislay the matrix. If X is a cell of
0033 %               strings, this is also a cell of strings without the End of
0034 %               Line.
0035 %
0036 %   DESCRIPTION:
0037 %     This program saves/displays a matrix array by using SPRINTF/FPRINTF
0038 %     with specific format (FMT) and delimiter (DLM) for every or EACH
0039 %     column in a very handy way, which is the mayor difference with SAVE
0040 %     or DLMWRITE function.
0041 %
0042 %     The point of this program is to allow the user to save/display any
0043 %     numeric or char matrix as easy as posible without messing with the
0044 %     appropiate format ('%...') to do it, only with the precision (if is
0045 %     numerical). See the EXAMPLE below.
0046 %
0047 %   NOTE:
0048 %     * Optional inputs use its DEFAULT value when not given or [].
0049 %     * Optional outputs may or not be called.
0050 %     * FMT and DLM may be a single string.
0051 %     * When FMT is used as precision integers, negative ones indicates to
0052 %       treat column(s) of X as integers rounded up to those significant
0053 %       digits to the left!
0054 %     * ADDITIONAL NOTES are included inside this file.
0055 %
0056 %   EXAMPLE:
0057 %     x = [    1    2    pi
0058 %              4  NaN     6
0059 %           75.4  Inf   8.5 ];
0060 %     % Display with 3 significant decimals.
0061 %       saveascii(x,3)
0062 %         % RETURNS:
0063 %         %  1.000  2.000  3.142
0064 %         %  4.000    NaN  6.000
0065 %         % 75.400    Inf  8.500
0066 %         %
0067 %     % Display with specific significant decimals.
0068 %       saveascii(x,[-1 2 0])
0069 %         % RETURNS:
0070 %         %  0 2.00 3
0071 %         %  0  NaN 6
0072 %         % 80  Inf 9
0073 %         %
0074 %     % Displays with ' hello ' and ' bye ' as delimiter.
0075 %       saveascii(x,{' hello ',' bye '},2)
0076 %         % RETURNS:
0077 %         %  1.00 hello  2.00 bye  3.14
0078 %         %  4.00 hello   NaN bye  6.00
0079 %         % 75.40 hello   Inf bye  8.50
0080 %         %
0081 %     % Saves on 'saveascii_demo.txt' with heading.
0082 %       FILE = 'saveascii_demo.txt';
0083 %       saveascii('% Demo file'                   ,FILE)
0084 %       saveascii(['%  Pi = ' saveascii(pi,3) ';'],FILE,'a')
0085 %       saveascii(x                               ,FILE,'a',0)
0086 %       edit(FILE)
0087 %       demo = load(FILE)
0088 %         % RETURNS:
0089 %         % demo =
0090 %         %
0091 %         %      4   NaN     6
0092 %         %     75   Inf     9
0093 %         %
0094 %     % NOTE: see how the heading is ignored by the LOAD function.
0095 %
0096 %   SEE ALSO:
0097 %     SAVE, FPRINTF, SPRINTF, DLMWRITE, CSVWRITE, FOPEN, STR2DOUBLE,
0098 %     STR2NUM, NUM2STR
0099 %     and
0100 %     READLINE by Carlos Vargas
0101 %     at http://www.mathworks.com/matlabcentral/fileexchange
0102 %
0103 %
0104 %   ---
0105 %   MFILE:   saveascii.m
0106 %   VERSION: 6.2 (Oct 30, 2009) (<a href="matlab:web('http://www.mathworks.com/matlabcentral/fileexchange/authors/11258')">download</a>)
0107 %   MATLAB:  7.7.0.471 (R2008b)
0108 %   AUTHOR:  Carlos Adrian Vargas Aguilera (MEXICO)
0109 %   CONTACT: nubeobscura@hotmail.com
0110 
0111 %   ADDITIONAL NOTES:
0112 %     * X must be the first input always, and, if used, FILE must be the
0113 %       second one. Afterwards FMT, DLM and 'a' may be given in any order.
0114 %     * By default the program writes with in text mode by append a 't' in
0115 %       the open permission mode ('wt' or 'at') rather than in the default
0116 %       binary mode ('wb' or 'ab'). This allows Windows OS users to read
0117 %       the saved file with any ascii program. See FOPEN for more details.
0118 %     * By default, the program OVERWRITES without warning, to use a
0119 %       warning use the optional input 'w -i' instead of the default 'w'.
0120 %     * To create a NEWLINE the program uses: '\n'. I guess Mac OS users
0121 %       should change the program to use '\r' instead.
0122 %     * The program works faster when a single delimiter and format/
0123 %       precision are used for every column.
0124 %     * The FMT may be a FULL format, which is a single string with Ncol
0125 %       formats within as the FULLFMT output.
0126 
0127 %   REVISIONS:
0128 %   1.0      Released. (Mar 06, 2006)
0129 %   2.0      Allows delimiter and format for each column. (Sep 28, 2006)
0130 %   2.1      English translation from spanish. (Nov 13, 2006)
0131 %   3.0      Now allows input decimals for floating-point. 'wt' and 'at'
0132 %            for Windows users. Output to Command Window and check errors.
0133 %            (Feb 21, 2007)
0134 %   3.1      Now accepts zero and negative decimals. (Feb 26, 2007)
0135 %   3.1.1    Bug fixed with row vectors (thanks to Emilio Velazquez). (Mar
0136 %            01, 2007)
0137 %   3.1.2    Bug fixed on get_digits subfunction. Used SUM of logicals
0138 %            instead of ANY. (Mar 02, 2007)
0139 %   4.0      Cleaner and rewritten code (cells). Reduced running time and
0140 %            memmory usage. Fixed bugs. Accounts Inf and NaN's. Changed
0141 %            default delimiter '\t' to ' '. Changed beginner char '@' to
0142 %            '<'. Added ending option. Optionaly format string output. (Mar
0143 %            11, 2008)
0144 %   4.0.1    Fix little bug with INTEGER type. (Mar 13, 2008)
0145 %   4.0.2    Fixed bug with not numeric elements (NAN's, Inf's and -Inf's).
0146 %            (Mar 13, 2008)
0147 %   4.0.3    Fixed bug when the whole column is no finite (NaN, Inf, or
0148 %            -Inf's). (May 06, 2008)
0149 %   5.0      Rewritten help and code. Fixed minor bugs related with empty
0150 %            X. No more reversed outputs. No more Begginig and Ending
0151 %            string optional inputs allowed. No more inputs separated by
0152 %            commas for DLM, FMT or precision FMT are allowed, instead cell
0153 %            of strings or a vector of integers must be used. DLM optional
0154 %            input is forced to be a cell of strings. New overwrite warning
0155 %            added. (Jun 08, 2009)
0156 %   5.0.1    When FMT is numeric (precision) now the program rounds up to
0157 %            it before saving. This eliminates any negative zero output
0158 %            like '-0.00'. (Jun 19, 2009)
0159 %   6.0      Now save a cell of strings. Again accepts a single delimiter
0160 %            as string. (Sep 30, 2009)
0161 %   6.1      Ignores optional empty inputs. Added some title comments (Oct
0162 %            03, 2009)
0163 %   6.2      Fixed small bug with parse inputs. Now creates file directory
0164 %            if not exist. (Oct 30, 2009)
0165 
0166 %   DISCLAIMER:
0167 %   saveascii.m is provided "as is" without warranty of any kind, under the
0168 %   revised BSD license.
0169 
0170 %   Copyright (c) 2004,2006,2007,2008,2009 Carlos Adrian Vargas Aguilera
0171 
0172 
0173 % INPUTS CHECK-IN
0174 % -------------------------------------------------------------------------
0175 
0176 % Checks number of inputs and outputs.
0177 if     nargin<1
0178  error('CVARGAS:saveascii:notEnoughInputs',...
0179   'At least 1 input is required.')
0180 elseif nargin>5
0181  error('CVARGAS:saveascii:tooManyInputs',...
0182   'At most 5 inputs are allowed.')
0183 elseif nargout>2
0184  error('CVARGAS:saveascii:tooManyOutputs',...
0185   'At most 2 outputs are allowed.')
0186 end
0187 
0188 % Sets defaults:
0189 FILE = [];          % Function mode:
0190                     %              [] : display
0191                     %    filename/fid : save
0192 PER  = 'w';         % Open permission:
0193                     %    'w' : OVERWRITES without warning
0194                     %    'a' : ppends
0195 TOB  = 't';         % Write mode:
0196                     %    't' : text
0197                     %    'b' : binary (FOPEN default)
0198 WAR  = false;       % Overwrite warning:
0199                     %    false : do not warns
0200                     %    true  : do warns
0201 if ischar(X) ||...  % String matrix
0202   iscellstr(X)      % or cell of strings input:
0203  FMT = {'%c'};      %    Format string for each (every) column.
0204  DLM = {''};        %    If just text, nothing between chars.
0205 else                % Numeric (real) or logical matrix input:
0206  FMT = {'% 8.7e'};  %    Ugly, but MATLAB seems to like it, do you?
0207  DLM = {' '};       %    Single space. Try '\t' (tab).
0208 end                 %
0209 BOEL  = '';         % String at the Begining of Each line.
0210 EOEL  = '\n';       % String at the End Of Each Line
0211                     %    '\n' : for Windows and Unix OS users
0212                     %    '\r' : for Mac OS users (I guess, not tested)
0213 PRE  = [];          % Not used by default.
0214 WID  = [];          % Not used by default.
0215 SPC  = 'f';         % Floating-point specifier.
0216 
0217 
0218 % CHECKS X ================================================================
0219 % Checks X size.
0220 Nrow = size(X);
0221 if length(Nrow)>2
0222  error('CVARGAS:saveascii:incorrectXDimension',...
0223   'X must be a 2-dimensional matrix array.')
0224 else
0225  Ncol = Nrow(2);
0226  Nrow = Nrow(1);
0227 end
0228 % Checks X empty, type and complex.
0229 Xemp  = isempty(X);
0230 Xnum  = false;
0231 Xcell = false;
0232 if ~Xemp && (isnumeric(X) || islogical(X)) % Fixed BUG (May 07, 2009)
0233  if ~isreal(X)
0234   warning('CVARGAS:saveacii:complexInput',...
0235   'Imaginary parts on X were ignored.')
0236   X = real(X);
0237  end
0238  Xnum = true;
0239 elseif ischar(X) 
0240  % continue
0241 elseif iscellstr(X)
0242  Xcell = true;
0243  if Ncol>1
0244   if Nrow~=1
0245    error('CVARGAS:saveascii:incorrectXCellSize',...
0246     'X must be a vector of cell of strings, not a matrix.')
0247   end
0248   Nrow = Ncol;
0249   Ncol = 1;
0250  end
0251  X = X(:);
0252  Ncolcell = cellfun(@length,X);
0253  if Nrow==1
0254   % Cell of length 1?
0255   X     = X{1};
0256   Xcell = false;
0257  end
0258 elseif ~Xemp
0259  error('CVARGAS:saveascii:incorrectXType',...
0260   'X must be numerical, logical, string or cell of strings type.')
0261 end
0262 
0263 % CHECKS VARARGIN =========================================================
0264 % Checks number of optional inputs by type.
0265 % Fixed bug with empty inputs. Oct 2009
0266 Nopt   = length(varargin);
0267 inum   = false(1,Nopt);
0268 ichar  = inum;
0269 icell  = inum;
0270 iempty = inum;
0271 for k = 1:Nopt
0272  if     isempty(varargin{k})
0273   iempty(k) = true;
0274  elseif ischar(varargin{k})
0275   ichar(k)  = true;
0276  elseif iscellstr(varargin{k})
0277   icell(k)  = true; % Fixed bug, Oct 2009
0278  elseif isnumeric(varargin{k})
0279   inum(k)   = true;  % Fixed bug, Oct 2009
0280  else
0281   error('CVARGAS:saveascii:incorrectTypeInput',...
0282   'Optional inputs must be numerical, char or cell of strings type.')
0283  end
0284 end
0285 
0286 % Checks numeric inputs.
0287 [newFILE,PRE] = get_num(PRE,Ncol,varargin(inum),find(inum),find(iempty));
0288 clear inum iempty
0289 
0290 % Gets format.
0291 newFMT = [];
0292 if Xnum
0293  % Checks PRE.
0294  % Avoids a subfunction to optimize memory usage.
0295  if ~isempty(PRE)
0296   
0297   % Rounds down to positive PRE and up to negative PRE.
0298   ind = (PRE<0);
0299   if any(ind)
0300    % Negative PRE.
0301    if length(PRE)==1
0302     temp = 10^PRE;
0303     X    = round(X*temp)/temp;
0304    else
0305     temp     = repmat(10.^PRE(ind),Nrow,1);
0306     X(:,ind) = round(X(:,ind).*temp)./temp;
0307    end
0308    clear temp
0309    PRE(ind) = 0;
0310   end
0311   if any(~ind) % (Fixed BUG, Jun 19 2009)
0312    % Positive PRE.
0313    if length(PRE)==1
0314     temp = 10^PRE;
0315     X    = round(X*temp)/temp;
0316    else
0317     temp      = repmat(10.^PRE(~ind),Nrow,1);
0318     X(:,~ind) = round(X(:,~ind).*temp)./temp;
0319    end
0320    clear temp
0321   end
0322   X(X==0) = 0; % Forces positive zeros.
0323   
0324   % Generate format from precision.
0325   % First, creates a short matrix x3 to get the width and helps to save
0326   % memory, with only 3 rows:
0327   % 1. Maximum of X columns (ignoring Inf's)
0328   % 2. Flags if columns of X has: NaN->1; Inf->1; -Inf->-1; otherwise->0
0329   % 3. Minimum of X columns (ignoring -Inf's)
0330   iinf  = ~isfinite(X);          %  1's if NaN, Inf or -Inf, 0 otherwise.
0331   iinfn = find(iinf);            %  To get the -Inf indexes:
0332   iinfn(isnan(X(iinfn)) ) = [];  % ... deletes the NaN's. Bug fixed mar08
0333   iinfn(      X(iinfn)>0) = [];  % ... deletes the Inf's
0334   iinf = double(iinf);           % Turns them to double values
0335   iinf(iinfn) = -1;              % Put -Inf flags as -1.
0336   x3 = [maxinf(X,[],1); any(iinf,1)-2*any(iinf<0,1); mininf(X,[],1)];
0337   clear iinf iinfn
0338   % Creates the format string from precision options.
0339   newFMT = pre2fmt(PRE,WID,SPC,Ncol,x3);
0340   clear x3
0341  end
0342 else
0343  if ~isempty(PRE)
0344   error('CVARGAS:saveascii:incorrectFmtNumericalInput',...
0345    'FMT cannot be numerical because X is not numeric.')
0346  end
0347 end
0348 
0349 % Checks cell inputs:
0350 [newDLM,newFMT,EOEL,full1] = ...
0351                          get_cell([],newFMT,EOEL,Ncol,varargin(icell));
0352 clear icell
0353  
0354 % Checks string inputs.
0355 % Fixed bug to work with char DELIMITERS besides of cells. Sep 2009.
0356 [newFILE,PER,TOB,WAR,newDLM,newFMT,EOEL,full2] = get_char(newFILE,PER,...
0357               TOB,WAR,newDLM,newFMT,EOEL,Ncol,varargin(ichar),find(ichar));
0358 clear ichar varargin
0359 
0360 % CHECKS FORMAT ===========================================================
0361 % Given FMT?:
0362 if ~isempty(newFMT)
0363  if ~Xnum
0364   warning('CVARGAS:saveascii:incorrectFmtCharInput',...
0365    'Ignored specific format because X is char.')
0366  else
0367   FMT = newFMT;
0368  end
0369 end
0370 
0371 % Given DLM:
0372 if ~isempty(newDLM)
0373  if full1 || full2
0374   warning('CVARGAS:saveascii:ignoredDlmInput',...
0375    'DLM ignored because FMT is a full format.')
0376   DLM = {''};
0377  else
0378   DLM = newDLM;
0379  end
0380 end
0381 
0382 % Generates full format:
0383 if ~Xemp
0384  if ~Xcell
0385   FULLFMT = [BOEL get_strform(DLM,FMT,Ncol) EOEL];
0386  else
0387   FULLFMT = cell(Nrow,1);
0388   eoel = EOEL;
0389   if ~isempty(EOEL)
0390    for k = 1:2
0391     if     strcmp(eoel(end-1:end),'\n') 
0392      eoel(end-1:end) = []; 
0393     elseif strcmp(eoel(end-1:end),'\r')
0394      eoel(end-1:end) = []; 
0395     end
0396     if isempty(eoel), break, end
0397    end
0398   elseif length(FMT)>1
0399    for k = 1:2
0400     if isempty(FMT), break, end
0401     if     strcmp(FMT(end-1:end),'\n')
0402      EOEL = FMT(end-1:end);
0403      FMT(end-1:end) = []; 
0404     elseif strcmp(FMT(end-1:end),'\r')
0405      EOEL = FMT(end-1:end);
0406      FMT(end-1:end) = []; 
0407     end
0408    end
0409   end
0410   for k = 1:Nrow
0411    FULLFMT{k}    = [BOEL get_strform(DLM,FMT,Ncolcell(k))    eoel];
0412   end
0413  end
0414 else
0415  % Empty array.
0416  X       = '';   % Fixed BUG (May 07, 2009)
0417  FULLFMT = '';
0418 end
0419 clear BOEL WID FMT DLM SPC Ncol
0420 
0421 % CHECKS FILE =============================================================
0422 % Given FILE?:
0423 if ~isempty(newFILE)
0424  FILE = newFILE;
0425  % Warning for the file id used. To check that FILE is a fid and not a
0426  % precision.
0427  if isempty(PRE) && isempty(newFMT) && isnumeric(FILE)
0428   if ~isempty(fopen(FILE))
0429    warning('CVARGAS:saveascii:usedFileNumericalInput',...
0430     'Filename used was ''%s'' with file identifier %.0f.',fopen(FILE),FILE)
0431    % To ignore this warning use
0432    % >> warning('off','CVARGAS:saveascii:usedFileNumericalInput')
0433    % before calling this program.
0434   else
0435    error('CVARGAS:saveascii:invalidNumericalSecondInput',...
0436     ['Numerical second input must be a valid File Identifier. If it is '...
0437      'PRECISION, give an empty, [], as second input.'])
0438   end
0439  end
0440 end
0441 if ~isempty(FILE) && isnumeric(FILE)
0442  % File id:
0443  fid  = FILE;
0444  [FILE,per] = fopen(fid);
0445  if ~ismember(per(1),'aAwW')
0446   error('CVARGAS:saveascii:noWrittingPermission',...
0447     ['Filename ''%s'' with file identifier %.0f does not have writting ' ...
0448      'permision. See FOPEN for details.'],fopen(FILE),FILE)
0449  end
0450  if Xcell && ~ismember(per(1),'aA')
0451   error('CVARGAS:saveascii:noAppendPermission',...
0452     ['Filename ''%s'' with file identifier %.0f does not have append ' ...
0453      'permision. Elements of cell X will overwrite the file each time.']...
0454      ,fopen(FILE),FILE)
0455  end
0456 else
0457  fid = [];
0458 end
0459 Femp = isempty(FILE);
0460 if (~Femp && WAR) && ((isempty(fileparts(FILE)) && ...
0461   (exist(fullfile(pwd,FILE),'file')==2)) || (exist(FILE,'file')==2))
0462  % Overwrite warning.
0463  h = questdlg({'Is it OK to overwrite the file:'; [FILE '?']},...
0464                'saveascii.m','Yes','Cancel','Cancel');
0465  if isempty(h) || ~strcmp(h,'Yes')
0466   if nargout==0
0467    clear X
0468    return
0469   end
0470   Femp = true;
0471  end
0472 end
0473 clear newFILE
0474 clear newFMT
0475 
0476 
0477 % -------------------------------------------------------------------------
0478 % MAIN
0479 % -------------------------------------------------------------------------
0480 
0481 % SAVES IN FILE ===========================================================
0482 if ~Femp
0483  % Saves the matrix to the ascii file using FPRINTF.
0484  if ~isempty(fid)
0485   if ~Xcell
0486    fprintf(fid,FULLFMT,X.');
0487   else
0488    for k = 1:Nrow
0489     fprintf(fid,FULLFMT{k},X{k}.');
0490    end
0491   end
0492  else
0493   % Fixed bug. Oct 2009
0494   [DIR FILE EXT] = fileparts(FILE);
0495   if ~isempty(DIR)
0496    if ~(exist(DIR,'dir')==7)
0497     [flag,temp] = mkdir(DIR);
0498     if ~flag
0499      error('CVARGAS:saveascii:invalidDirectoryName',...
0500       'Unable to create the output directory ''%s''.',DIR)
0501     end
0502    end
0503   end
0504   FILE = fullfile(DIR,[FILE EXT]);
0505   fid  = fopen(FILE,[PER TOB]);      % 1.
0506   if fid<0
0507    error('CVARGAS:incorrectFileStringInput',...
0508     ['FILE was not a valid file name. If it is a DELIMITER put it ' ...
0509     'between brackets, {}, or put an empty, [], in the second input.'])
0510   end
0511   if ~Xcell
0512    fprintf(fid,FULLFMT,X.');         % 2.
0513    fclose(fid);                      % 3. lines of the SAVEASCII v1.0
0514   else
0515    % Writes first element and then appends the others.
0516    fprintf(fid,[FULLFMT{1} EOEL],X{1}.');
0517    fclose(fid);
0518    fid = fopen(FILE,['a' TOB]);
0519    for k = 2:Nrow
0520     fprintf(fid,[FULLFMT{k} EOEL],X{k}.');
0521    end
0522    fclose(fid);
0523   end
0524  end
0525  if (nargout==0)
0526   clear X
0527   return
0528  end
0529 end
0530 
0531 % DISPLAYS IN COMMAND WINDOW ==============================================
0532 if nargout==0
0533  if ~Xcell
0534   % Display string matrix.
0535   if ~Xnum && (Xemp || isempty(newDLM))         % Fixed BUG (May 07, 2009)
0536    disp(X)
0537    clear X
0538    return
0539   end
0540   X = sprintf(FULLFMT,X.');
0541   if isempty(X)
0542    % Incorrect FULLFMT.
0543    error('CVARGAS:saveascii:incorrectFormat',...
0544     'Incorrect format.')
0545   end
0546   Ncol2 = numel(X)/Nrow;
0547   if isnatural(Ncol2) % Reshapes it into a string matrix.
0548    Y  = reshape(X,Ncol2,Nrow);
0549    Yn = double(Y(end,1));
0550    if all(Yn==double(sprintf(FULLFMT(end-1:end))))
0551     Y = Y(1:end-1,:)';
0552     X = Y;
0553    else
0554     warning('CVARGAS:saveascii:matrixNotSquare',...
0555     ['The displayed string matrix is a vector because the array ' ...
0556      'cannot be squared with this format.'])
0557    % NOTE: SAVEASCII tries to convert the output from SPRINTF, which is a
0558    %       vector string, to a matrix string but fails, probably due to an
0559    %       incorrect format row.
0560    end
0561   elseif ~isempty(X)
0562    warning('CVARGAS:saveascii:matrixNotSquare',...
0563     ['The displayed string matrix is a vector because the array ' ...
0564      'cannot be squared with this format.'])
0565    % NOTE: SAVEASCII tries to convert the output from SPRINTF, which is a
0566    %       vector string, to a matrix string but fails, probably due to an
0567    %       incorrect format row.
0568   end
0569   disp(X)
0570  else
0571   for k = 1:Nrow
0572    fprintf(1,[FULLFMT{k} EOEL],X{k}.')
0573   end
0574  end
0575  clear X
0576  return
0577 end
0578 
0579 % OUTPUTS VARIABLE ========================================================
0580 % Output or displays the result.
0581 % Displays the result matrix string on the Command Window or as an output
0582 % argument using SPRINTF and DISP.
0583 
0584 % Fixed BUG (May 07, 2009).
0585 if ~Xnum && (Xemp || (isempty(newDLM) && ~Xcell)) 
0586  return
0587 end
0588 
0589 % Output string matrix.
0590 if ~Xcell
0591  X     = sprintf(FULLFMT,X.'); 
0592  Ncol2 = numel(X)/Nrow;
0593  if isnatural(Ncol2) % Reshapes it into a string matrix.
0594   Y  = reshape(X,Ncol2,Nrow);
0595   Yn = double(Y(end,1));
0596   if all(Yn==double(sprintf(FULLFMT(end-1:end))))
0597    Y = Y(1:end-1,:)';
0598    X = Y;
0599   else
0600    warning('CVARGAS:saveascii:matrixNotSquare',...
0601    ['The displayed string matrix is a vector because the array ' ...
0602     'cannot be squared with this format.'])
0603   % NOTE: SAVEASCII tries to convert the output from SPRINTF, which is a
0604   %       vector string, to a matrix string but fails, probably due to an
0605   %       incorrect format row.
0606   end
0607  elseif ~isempty(X)
0608   warning('CVARGAS:saveascii:matrixNotSquare',...
0609    ['The output string matrix is a vector because the array ' ...
0610     'cannot be squared with this format.'])
0611   % NOTE: SAVEASCII tries to convert the output from SPRINTF, which is a
0612   %       vector string, to a matrix string but fails, probably due to an
0613   %       incorrect format row.
0614  end
0615 else
0616  Y = cell(Nrow,1);
0617  for k = 1:Nrow
0618   Y{k} = sprintf(FULLFMT{k},X{1}.');
0619   X(1) = [];
0620  end
0621  Mcolcell = cellfun(@length,Y);
0622  X = repmat(' ',Nrow,max(Mcolcell));
0623  for k = 1:Nrow
0624   X(k,1:Mcolcell(k)) = Y{1};
0625   Y(1) = [];
0626  end
0627 end
0628 
0629 
0630 % =========================================================================
0631 % SUBFUNCTIONS
0632 % -------------------------------------------------------------------------
0633 
0634 function [fid,PRE] = get_num(PRE,Ncol,numopt,inum,iempty) 
0635 % Extract precision from options in a vector array.
0636 % New input "iempty". Oct 2009.
0637 
0638 % Forces row PRE:
0639 PRE = round(PRE(:).');
0640 fid = [];
0641 
0642 % Checks no input.
0643 if isempty(numopt)
0644  return
0645 end
0646 
0647 % Checks FILE id input.
0648 % Fixed bug to accept 1 and 2 file identifiers. Oct 2009.
0649 if isempty(iempty) && inum(1)==1 && (numel(numopt{1})==1) && ...
0650   (numopt{1}>0) && isnatural(numopt{1}) && ~isempty(fopen(numopt{1}))
0651  fid       = numopt{1};
0652  numopt(1) = [];
0653  if isempty(numopt)
0654   return
0655  end
0656 end
0657 
0658 % Checks X empty:
0659 if Ncol==0
0660  return
0661 end
0662 
0663 % Checks many inputs.
0664 if length(numopt)>1
0665  error('CVARGAS:saveascii:tooManyFmtInput',...
0666   'More than one FMT precision given.')
0667 end
0668 % Checks values:
0669 if any(~isfinite(numopt{1}))
0670  error('CVARGAS:saveascii:notFiniteFmtInput',...
0671   'Precision FMT must be all finite.')
0672 end
0673 % Checks size:
0674 nPRE = numel(numopt{1});
0675 if (nPRE~=1) && (nPRE~=Ncol)
0676  error('CVARGAS:saveascii:incorrectFmtLongInput',...
0677   'Precision FMT vector must have 1 or Ncol integers.')
0678 end
0679 % Checks integer:
0680 if any(~isnatural(numopt{1}))
0681  error('CVARGAS:saveascii:notIntegerFmtInput',...
0682   'Precision FMT must be integers.')
0683 end
0684 % Forces integers and row vector:
0685 PRE = numopt{1}(:).';
0686 
0687 function FMT = pre2fmt(PRE,WID,SPC,Ncol,x3)
0688 % Calculates the width for each column and creates the format string for
0689 % each column with that width, precision and delimiter.
0690 
0691 % Reduce the size of x3 if a single precision is given.
0692 if length(PRE)==1
0693  x3 = [max(x3(1,:)); any(x3(2,:),2)-2*any(x3(2,:)<0,2); min(x3(3,:))];
0694 end
0695 if isempty(WID)
0696  WID = get_wid(PRE,x3([1 3],:));
0697  % Check at least 3 digits when NaN's or INF's:
0698  isbad = logical(x3(2,:));
0699  isbad(isbad) = (WID(isbad)<=3);
0700  WID(isbad) = 3 + any(x3(2,isbad)<0,1);
0701  % Converst from numeric format to format string:
0702 end
0703 FMT = pre2fmtcol(PRE,WID,SPC,Ncol);
0704 
0705 function FMT = pre2fmtcol(PRE,WID,SPC,Ncol)
0706 % Creates the format string for each (or every) column from precision,
0707 % width and specifier.
0708 
0709 % Added to reduce running time by reducing the usage of INT2STR. Feb 2008
0710 [w,w,iw] = unique(WID);
0711 [p,p,ip] = unique(PRE);
0712 Nw = length(w);
0713 Np = length(p);
0714 Sw = cell(1,Nw);
0715 Sp = cell(1,Np);
0716 for k = 1:Nw
0717  Sw{k} = int2str(WID(w(k)));
0718 end
0719 for k = 1:Np
0720  Sp{k} = int2str(PRE(p(k)));
0721 end
0722 % Checks flag on specifier:
0723 if length(SPC)==2
0724  flag = SPC(1);
0725  SPC(1) = [];
0726 else
0727  flag = '';
0728 end
0729 % Writes the format strings:
0730 FMT = cell(1,1+(Ncol-1)*(Nw*Np~=1));
0731 FMT{1} = ['%' flag Sw{iw(1)} '.' Sp{ip(1)} SPC];
0732 if Nw*Np~=1
0733  for k = 2:Ncol
0734   FMT{k} = [ '%' flag Sw{iw(k)} '.' Sp{ip(k)} SPC];
0735  end
0736 end
0737 
0738 function WID = get_wid(PRE,x)
0739 % Calculates the maximum number of digits for each (or every) column of x.
0740 
0741 M      = get_order(x);
0742 M(M<0) = 0;                       % M=0 if 0<x<1
0743 M      = M+1;                     % Adds the first digit.
0744 M      = M+(x<0);                 % Adds the negative character.
0745 % Get the maximum number of characters in each column:
0746 WID = max(M,[],1);              % Max of digits to the right of the dot.
0747 % Adds the precision and the dot characters:
0748 WID = WID + (PRE+1).*(PRE>0);
0749 % If NaN, InF or -Inf sets at least 3, 3 or 4 digits respectively.
0750 isbad        = any(~isfinite(x),1);
0751 isbad(isbad) = (WID(isbad)<=3) | ~isfinite(WID(isbad));
0752 WID(isbad)   = 3 + any(x(:,isbad)<0,1);
0753 
0754 function [DLM,FMT,EOEL,full] = get_cell(DLM,FMT,EOEL,Ncol,cellopt)
0755 % Reads cell optional inputs.
0756 
0757 % Initializes.
0758 nDLM = 0;
0759 nFMT = double(~isempty(FMT));
0760 full = false;
0761 
0762 while ~isempty(cellopt)
0763  n   = length(cellopt{1});
0764  ind = regexp([' ' cellopt{1}{1} ' '],'[^%]%[^%]');
0765  m   = length(ind);
0766  if     (n==1   ) && ((m~=0) && (((m==1) || (m==Ncol)) || (Ncol==0)))
0767   % FMT for every column.
0768   FMT = cellopt{1};  nFMT = nFMT+1;
0769   full = (m==Ncol);
0770  elseif (m==1) && ((n~=0) && ((n==Ncol) || (Ncol==0)))
0771   % FMT for each column.
0772   for k = 2:Ncol
0773    % Checks if all of them are formats.
0774    ind = regexp([' ' cellopt{1}{k} ' '],'[^%]%[^%]');
0775    if length(ind)~=1
0776     error('CVARGAS:saveascii:incorrectFmtCellInput',...
0777      'Incorrect FMT cell of strings input.')
0778    end
0779   end
0780   FMT = cellopt{1};  nFMT = nFMT+1;
0781  elseif (n==1) && (m==0)
0782   % DLM for every column.
0783   DLM = cellopt{1};  nDLM = nDLM+1;
0784  elseif (m==0) && ((n==(Ncol-1)) || (Ncol==0))
0785   % DLM for each column.
0786   DLM = cellopt{1};  nDLM = nDLM+1;
0787  else
0788   if m==0
0789    error('CVARGAS:saveascii:incorrectCellLengthInput',...
0790     'DLM cell of string must be of length 1 or Ncol-1.')
0791   else
0792    error('CVARGAS:saveascii:incorrectFmtLengthInput',...
0793     'FMT cell of string must be of length 1 or Ncol.')
0794   end
0795  end
0796  cellopt(1) = [];
0797 end
0798 
0799 % Checks for errors:
0800 if nDLM>1
0801  error('CVARGAS:saveascii:tooManyDlmInput',...
0802   'More than one DLM given.')
0803 end
0804 if nFMT>1
0805  error('CVARGAS:saveascii:tooManyFmtInput',...
0806   'More than one FMT given.')
0807 end
0808 
0809 % Checks ending of full format:
0810 if full && (length(FMT{1})>1) && (strcmp(FMT{1}(end-1:end),'\n') || ...
0811   strcmp(FMT{1}(end-1:end),'\r'))
0812  EOEL = '';
0813 end
0814 
0815 function [FILE,PER,TOB,WAR,DLM,FMT,EOEL,full] = ...
0816                   get_char(FILE,PER,TOB,WAR,DLM,FMT,EOEL,Ncol,stropt,ichar)
0817 % Reads string optional inputs.
0818 
0819 % Initializes.
0820 nFILE = double(~isempty(FILE));
0821 nPER  = 0;
0822 nDLM  = ~isempty(DLM);
0823 nFMT  = double(~isempty(FMT));
0824 full  = false;
0825 
0826 % Checks strings inputs
0827 while ~isempty(stropt) 
0828  % Looks for '%' chars.
0829  ind = regexp([' ' stropt{1} ' '],'[^%]%[^%]');
0830  m   = length(ind);
0831  if m~=0 && (((m==1) || (m==Ncol)) || (Ncol==0))
0832   % Sets FMT:
0833   FMT  = stropt(1);  nFMT  = nFMT+1;
0834   full = (m==Ncol);
0835  else
0836   % Looks for PER or FILE:
0837   switch stropt{1}
0838    case {'w','a'}
0839     PER  = stropt{1};     nPER  = nPER+1;
0840    case {'wt','at','wb','ab'}
0841     PER  = stropt{1}(1);  nPER  = nPER+1;
0842     TOB  = stropt{1}(2);
0843    case {'w -i'}
0844     PER  = stropt{1}(1);  nPER  = nPER+1;
0845     WAR  = true;
0846    case {'wt -i','wb -i'}
0847     PER  = stropt{1}(1);  nPER  = nPER+1;
0848     TOB  = stropt{1}(2);
0849     WAR  = true;
0850    otherwise
0851     if ichar(1)==1
0852      FILE = stropt{1};     nFILE = nFILE+1;
0853     else
0854      if nDLM
0855       error('CVARGAS:saveascii:incorrectCharInput', ...
0856        ['Incorrect char input. \n\n' ...
0857         'Must be a valid OPEN MODE (''a'',''w'') or a valid FILE NAME ' ...
0858         '(as second input). '])
0859      end
0860      DLM = {stropt{1}};
0861     end
0862   end
0863  end 
0864  stropt(1) = [];
0865  ichar(1)  = [];
0866 end
0867 
0868 % Checks for errors:
0869 if nFILE>1
0870  error('CVARGAS:saveascii:tooManyFileInput',...
0871   'More than one FILE given.')
0872 end
0873 if nPER>1
0874  error('CVARGAS:saveascii:tooManyPermissionsInput',...
0875   'More than one open file permission given.')
0876 end
0877 if nFMT>1
0878  error('CVARGAS:saveascii:tooManyFmtInput',...
0879   'More than one FMT given.')
0880 end
0881 if (nPER==1) && (nFILE==0)
0882  warning('CVARGAS:saveascii:ignoredPermissionInput',...
0883   'Ignored Permission input because no FILE given.')
0884 end
0885 
0886 % Checks ending of full format:
0887 if full && (length(FMT{1})>1) && (strcmp(FMT{1}(end-1:end),'\n') || ...
0888   strcmp(FMT{1}(end-1:end),'\r'))
0889  EOEL = '';
0890 end
0891  
0892 function FULLFMT = get_strform(DLM,FMT,Ncol)
0893 % Generates the whole format string from the options or defaults.
0894 
0895 FULLFMT = '';
0896 Nf = length(FMT);
0897 % a) Super format:
0898 if Nf==1 
0899  Nf = numel(strfind(FMT{1},'%')); 
0900  if Nf==Ncol
0901   FULLFMT = FMT{1};
0902  elseif Nf~=1       % Error in the full format string option.
0903   error('CVARGAS:saveascii:invalidStrOptionsSize',...
0904    'Number of format strings must be 0, 1 or Ncol.')
0905  end
0906 end
0907 % b) Piecewise format:
0908 if isempty(FULLFMT)
0909  FULLFMT = FMT{1};
0910  Nd = length(DLM);
0911  if Nd==1           % Single delimiter?
0912   if Nf==1          %  + single format?
0913    FULLFMT = [FULLFMT repmat([DLM{1} FMT{1}],1,Ncol-1)];
0914   else              %  + Ncol formats?
0915    for k = 2:Ncol
0916     FULLFMT = [FULLFMT DLM{1} FMT{k}];
0917    end
0918   end
0919  elseif Nd==(Ncol-1)  % Ncol-1 delimiters?
0920   if Nf==1            %   + single format?
0921    for k = 2:Ncol
0922     FULLFMT = [FULLFMT DLM{k-1} FMT{1}];
0923    end
0924   else              %   + Ncol formats?
0925    for k = 2:Ncol
0926     FULLFMT = [FULLFMT DLM{k-1} FMT{k}];
0927    end
0928   end
0929  else               %   No delimiters (all failed)
0930   if Nf==1          %   + single format?
0931    FULLFMT = repmat(FULLFMT,1,Ncol);
0932   else              %   + Ncol formats?
0933    for k = 2:Ncol
0934     FULLFMT = [FULLFMT FMT{k}];
0935    end
0936   end
0937  end
0938 end
0939 
0940 function M = get_order(x)
0941 % Gets the order of magnitud in 10 base, i.e., in scientific notation:
0942 %   M = get_order(y)   =>   y = X.XXXXXX x 10^M
0943 
0944 if isinteger(x) % Allows integer input: uint8, etc.
0945  x = double(x); % bug fixed Mar 08
0946 end
0947 temp = warning('off','MATLAB:log:logOfZero');
0948 M = floor(log10(abs(x)));       % In cientific notation x = XXX x 10^M.
0949 M(x==0) = 0; % M=0 if x=0. (Bug fixed 10/jan/2008) (bug fixed 05/may/2008)
0950 warning(temp.state,'MATLAB:log:logOfZero')
0951 
0952 function y = maxinf(x,varargin)
0953 %MAXINF   Largest component ignoring INF's as posible.
0954 %
0955 %    Y = MAXINF(X) is equivalent to MAX but ignoring INF's. If there is no
0956 %    finite elements, then the INF or -INF value is returned; NaN's are
0957 %    return if all the elements are NaN's.
0958 
0959 y = max(x,varargin{:});
0960 iinf = isinf(y);
0961 if any(iinf(:))
0962  xinf = y(iinf);
0963  x(~isfinite(x)) = NaN;
0964  y = max(x,varargin{:});
0965  inan = isnan(y(iinf));
0966  if any(inan(:))
0967   y(iinf(inan)) = xinf(inan);
0968  end
0969 end
0970 
0971 function y = mininf(x,varargin)
0972 %MININF   Smallest component ignoring -INF's as posible.
0973 %
0974 %    Y = MININF(X) is equivalent to MIN but ignoring -INF's. If there is no
0975 %    finite elements, then the INF or -INF value is returned; NaN's are
0976 %    return if all the elements are NaN's.
0977 
0978 y = min(x,varargin{:});
0979 iinf = isinf(y);
0980 if any(iinf(:))
0981  xinf = y(iinf);
0982  x(~isfinite(x)) = NaN;
0983  y = min(x,varargin{:});
0984  inan = isnan(y(iinf));
0985  if any(inan(:))
0986   y(iinf(inan)) = xinf(inan);
0987  end
0988 end
0989 
0990 function n = isnatural(n)
0991 %ISNATURAL   Checks if an array has natural numbers.
0992 %   Y = ISNATURAL(X) returns a logical array of the same size as X with
0993 %   ones in the elements of X that are natural numbers
0994 %   (...-2,-1,0,1,2,...), and zeros where not.
0995 
0996 %   Written by
0997 %   M.S. Carlos AdriáÏ Vargas Aguilera
0998 %   Physical Oceanography PhD candidate
0999 %   CICESE
1000 %   Mexico, November 2006
1001 %
1002 %   nubeobscura@hotmail.com
1003 
1004 n = (n==floor(n)) & isreal(n)  & isnumeric(n) & isfinite(n);
1005 
1006 
1007 % [EOF]   saveascii.m

Generated on Mon 22-May-2023 06:53:56 by m2html © 2005