Home > matpower5.1 > psse_parse_section.m

psse_parse_section

PURPOSE ^

PSSE_PARSE_SECTION Parses the data from a section of a PSS/E RAW data file

SYNOPSIS ^

function [data, warns] = psse_parse_section(warns, records, sections, s, verbose, label, template)

DESCRIPTION ^

PSSE_PARSE_SECTION  Parses the data from a section of a PSS/E RAW data file
   [DATA, WARNINGS] = PSSE_PARSE_SECTION(WARNINGS, RECORDS, SECTIONS, SIDX, ...
                                           VERBOSE, LABEL, TEMPLATE)
   [DATA, WARNINGS] = PSSE_PARSE_SECTION(WARNINGS, RECORDS, SECTIONS, SIDX, ...
                                           VERBOSE, LABEL)
   [DATA, WARNINGS] = PSSE_PARSE_SECTION(WARNINGS, RECORDS, SECTIONS, SIDX, ...
                                           VERBOSE)
   [DATA, WARNINGS] = PSSE_PARSE_SECTION(WARNINGS, RECORDS, SECTIONS, SIDX)
   [DATA, WARNINGS] = PSSE_PARSE_SECTION(WARNINGS, RECORDS, VERBOSE, LABEL, ...
                                           TEMPLATE)
   [DATA, WARNINGS] = PSSE_PARSE_SECTION(WARNINGS, RECORDS, VERBOSE, LABEL)
   [DATA, WARNINGS] = PSSE_PARSE_SECTION(WARNINGS, RECORDS, VERBOSE)
   [DATA, WARNINGS] = PSSE_PARSE_SECTION(WARNINGS, RECORDS)

   Inputs:
       WARNINGS :  cell array of strings containing accumulated
                   warning messages
       RECORDS :   a cell array of strings returned by PSSE_READ
       SECTIONS :  a struct array returned by PSSE_READ
       SIDX :      (optional) index if the section to be read
                   if included, the RECORD indices are taken from
                   SECTIONS(SIDX), otherwise use all RECORDS
       VERBOSE :   1 to display progress info, 0 (default) otherwise
       LABEL :     (optional) name for the section, to be compared with
                   the section name typically found in the
                   END OF <LABEL> DATA comment at the end of each section
       TEMPLATE :  (optional) string of characters indicating how to
                   interpret the type of the corresponding column, options
                   are as follows:
               d, f or g : integer floating point number to be converted
                   via SSCANF with %d, %f or %g, respectively.
               D, F or G : integer floating point number, possibly enclosed
                   in single or double quotes, to be converted via
                   SSCANF with %d, %f or %g, respectively.
               c or s : character or string, possibly enclosed in single
                   or double quotes, which are stripped from the string
           Note:   Data columns in RECORDS that have no valid corresponding
                   entry in TEMPLATE (beyond end of TEMPLATE, or a character
                   other than those listed, e.g. '.') are returned in DATA.txt
                   with no conversion. TEMPLATE entries for which there is
                   no corresponding column in RECORDS are returned as NaN and
                   empty, respectively, in DATA.num and DATA.txt.

   Output:
       DATA :      a struct with two fields:
           num :   matrix containing the numeric data for the section, for
                   columns with no numeric data, num contain NaNs.
           txt :   a cell array containing the non-numeric (char/string)
                   data for the section, for columns with numeric data,
                   txt entries are empty
       WARNINGS :  cell array of strings containing updated accumulated
                   warning messages

   See also PSSE2MPC, PSSE_PARSE

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function [data, warns] = psse_parse_section(warns, records, sections, s, verbose, label, template)
0002 %PSSE_PARSE_SECTION  Parses the data from a section of a PSS/E RAW data file
0003 %   [DATA, WARNINGS] = PSSE_PARSE_SECTION(WARNINGS, RECORDS, SECTIONS, SIDX, ...
0004 %                                           VERBOSE, LABEL, TEMPLATE)
0005 %   [DATA, WARNINGS] = PSSE_PARSE_SECTION(WARNINGS, RECORDS, SECTIONS, SIDX, ...
0006 %                                           VERBOSE, LABEL)
0007 %   [DATA, WARNINGS] = PSSE_PARSE_SECTION(WARNINGS, RECORDS, SECTIONS, SIDX, ...
0008 %                                           VERBOSE)
0009 %   [DATA, WARNINGS] = PSSE_PARSE_SECTION(WARNINGS, RECORDS, SECTIONS, SIDX)
0010 %   [DATA, WARNINGS] = PSSE_PARSE_SECTION(WARNINGS, RECORDS, VERBOSE, LABEL, ...
0011 %                                           TEMPLATE)
0012 %   [DATA, WARNINGS] = PSSE_PARSE_SECTION(WARNINGS, RECORDS, VERBOSE, LABEL)
0013 %   [DATA, WARNINGS] = PSSE_PARSE_SECTION(WARNINGS, RECORDS, VERBOSE)
0014 %   [DATA, WARNINGS] = PSSE_PARSE_SECTION(WARNINGS, RECORDS)
0015 %
0016 %   Inputs:
0017 %       WARNINGS :  cell array of strings containing accumulated
0018 %                   warning messages
0019 %       RECORDS :   a cell array of strings returned by PSSE_READ
0020 %       SECTIONS :  a struct array returned by PSSE_READ
0021 %       SIDX :      (optional) index if the section to be read
0022 %                   if included, the RECORD indices are taken from
0023 %                   SECTIONS(SIDX), otherwise use all RECORDS
0024 %       VERBOSE :   1 to display progress info, 0 (default) otherwise
0025 %       LABEL :     (optional) name for the section, to be compared with
0026 %                   the section name typically found in the
0027 %                   END OF <LABEL> DATA comment at the end of each section
0028 %       TEMPLATE :  (optional) string of characters indicating how to
0029 %                   interpret the type of the corresponding column, options
0030 %                   are as follows:
0031 %               d, f or g : integer floating point number to be converted
0032 %                   via SSCANF with %d, %f or %g, respectively.
0033 %               D, F or G : integer floating point number, possibly enclosed
0034 %                   in single or double quotes, to be converted via
0035 %                   SSCANF with %d, %f or %g, respectively.
0036 %               c or s : character or string, possibly enclosed in single
0037 %                   or double quotes, which are stripped from the string
0038 %           Note:   Data columns in RECORDS that have no valid corresponding
0039 %                   entry in TEMPLATE (beyond end of TEMPLATE, or a character
0040 %                   other than those listed, e.g. '.') are returned in DATA.txt
0041 %                   with no conversion. TEMPLATE entries for which there is
0042 %                   no corresponding column in RECORDS are returned as NaN and
0043 %                   empty, respectively, in DATA.num and DATA.txt.
0044 %
0045 %   Output:
0046 %       DATA :      a struct with two fields:
0047 %           num :   matrix containing the numeric data for the section, for
0048 %                   columns with no numeric data, num contain NaNs.
0049 %           txt :   a cell array containing the non-numeric (char/string)
0050 %                   data for the section, for columns with numeric data,
0051 %                   txt entries are empty
0052 %       WARNINGS :  cell array of strings containing updated accumulated
0053 %                   warning messages
0054 %
0055 %   See also PSSE2MPC, PSSE_PARSE
0056 
0057 %   MATPOWER
0058 %   Copyright (c) 2014-2015 by Power System Engineering Research Center (PSERC)
0059 %   by Ray Zimmerman, PSERC Cornell
0060 %
0061 %   $Id: psse_parse_section.m 2644 2015-03-11 19:34:22Z ray $
0062 %
0063 %   This file is part of MATPOWER.
0064 %   Covered by the 3-clause BSD License (see LICENSE file for details).
0065 %   See http://www.pserc.cornell.edu/matpower/ for more info.
0066 
0067 %% defaults
0068 if nargin < 3
0069     have_sections = 0;
0070     verbose = 0;
0071     template = '';
0072 elseif isstruct(sections)
0073     have_sections = 1;
0074     if nargin < 7
0075         template = '';
0076         if nargin < 6
0077             label = '';
0078             if nargin < 5
0079                 verbose = 0;
0080             else
0081                 error('psse_parse_section: too few input arguments');
0082             end
0083         end
0084     end
0085 else
0086     have_sections = 0;
0087     if nargin >= 5
0088         template = verbose;
0089     else
0090         template = '';
0091     end
0092     if nargin >= 4
0093         label = s;
0094     else
0095         label = '';
0096     end
0097     verbose = sections;
0098 end
0099 
0100 %% get relevant records, check section name
0101 nt = length(template);
0102 if have_sections
0103     nr = sections(s).last - sections(s).first + 1;
0104     recs = records(sections(s).first:sections(s).last);
0105     if ~isempty(sections(s).name) && ~strcmpi(label, sections(s).name)
0106         warns{end+1} = sprintf('Section label mismatch, found ''%s'', expected ''%s''', ...
0107             sections(s).name, upper(label));
0108         if verbose
0109             fprintf('-----  WARNING:  Found section labeled:    ''%s''\n', sections(s).name);
0110             fprintf('-----            Expected section labeled: ''%s''\n', upper(label));
0111         end
0112     end
0113 else
0114     nr = length(records);
0115     recs = records;
0116 end
0117 if verbose
0118     spacers = repmat('.', 1, 42-length(label));
0119     fprintf('Parsing %6d lines of %s data %s', nr, label, spacers);
0120 end
0121 
0122 if nr
0123     %% set up regexp to parse cols, comments of each record
0124     delim = '\s*(,|\s)\s*';     %% general delimiter
0125     repeatdelim = '\s*,\s*|\t'; %% delimiter that allows repeated delimiters
0126     non_quote_field = '[^''",\s/]+';
0127     single_quote_field = '''([^'']|'''')*''';
0128     double_quote_field = '"([^"]|"")*"';
0129     any_field = sprintf('(?<col>%s|%s|%s)', non_quote_field, single_quote_field, double_quote_field);
0130     pat = sprintf('%s%s|%s|%s|(?<comment>/.*)?', any_field, delim, repeatdelim, any_field);
0131     % pat = '(?<col>[^''",\s/]+|''([^'']|'''')*''|"([^"]|"")*")\s*(,|\s)\s*|\s*,\s*|\t|(?<col>[^''",\s/]+|''([^'']|'''')*''|"([^"]|"")*")|(?<comment>/.*)?';
0132 
0133     %% set up functions for use with cellfun
0134     if have_fcn('octave')
0135         parser  = @(ln){{regexp(ln, pat, 'names')}};  %% parse cols, comments of each rec
0136         numcols = @(ss)length(ss{1}.col);   %% number of columns in each record
0137     else
0138         parser  = @(ln){regexp(ln, pat, 'names')};  %% parse cols, comments of each rec
0139         numcols = @(ss)length(ss);      %% number of columns in each record
0140     end
0141 
0142     %% parse the table into cell array of structs (with col, comment fields)
0143     dd = cellfun(parser, recs);
0144 
0145 %     %% extract possible comments
0146 %     if nargout > 2
0147 %     %   extract_comment = @(n){n(end).comment};
0148 %         if have_fcn('octave')
0149 %             comment = cellfun(@(n){n{1}.comment(end)}, dd);
0150 %         else
0151 %             comment = cellfun(@(n){n(end).comment}, dd);
0152 %         end
0153 %     end
0154 
0155     %% find max number of columns
0156     nc = cellfun(numcols, dd);      %% number of columns
0157     ncmax = max(nc);
0158     ncmin = min(nc);
0159 
0160     %% extract data by column
0161     % nc = length(dd{1});
0162     % if nc && isempty(dd{1}(nc).col)   %% comment present
0163     %   nc = nc - 1;                %% reduce number of columns by 1 to discard
0164     % end
0165     data.num = NaN(nr, max(ncmax, nt));
0166     data.txt = cell(nr, max(ncmax, nt));
0167     for c = 1:ncmax
0168         %% template for conversion?
0169         if c <= nt
0170             t = template(c);
0171         else
0172             t = '';
0173         end
0174         if have_fcn('octave')   %% running under Octave
0175             switch t
0176                 case {'d', 'f', 'g', 'D', 'F', 'G'} %% numeric data
0177                     if t == upper(t)                %% possibly quoted
0178                         xc_fcn  = @(n)extract_col_qnum_octave(n, c, lower(t));
0179                     else                            %% not quoted (more efficient)
0180                         xc_fcn  = @(n)extract_col_num_octave(n, c, t);
0181                     end
0182                 case {'s', 'c'}
0183                     xc_fcn  = @(n){extract_col_dequote_octave(n, c)};
0184                 otherwise
0185                     if c <= ncmin
0186                         xc_fcn  = @(n)n{1}.col(c);
0187                     else
0188                         xc_fcn  = @(n){extract_col_octave(n, c)};
0189                     end
0190             end
0191         else                    %% running under Matlab
0192             switch t
0193                 case {'d', 'f', 'g', 'D', 'F', 'G'} %% numeric data
0194                     if t == upper(t)                %% possibly quoted
0195                         xc_fcn  = @(n)extract_col_qnum(n, c, lower(t));
0196                     else                            %% not quoted (more efficient)
0197                         xc_fcn  = @(n)extract_col_num(n, c, t);
0198                     end
0199                 case {'s', 'c'}
0200                     xc_fcn  = @(n){extract_col_dequote(n, c)};
0201                 otherwise
0202                     if c <= ncmin
0203                         xc_fcn  = @(n){n(c).col};
0204                     else
0205                         xc_fcn  = @(n){extract_col(n, c)};
0206                     end
0207             end
0208         end
0209         switch upper(t)
0210             case {'D', 'F', 'G'}
0211                 data.num(:, c) = cellfun(xc_fcn, dd);
0212             otherwise
0213                 data.txt(:, c) = cellfun(xc_fcn, dd);
0214         end
0215     end
0216 else
0217     data.num = NaN(nr, nt);
0218     data.txt = cell(nr, nt);
0219 end
0220 if verbose
0221     fprintf(' done.\n');
0222 %     if have_sections
0223 %         fprintf('%s\n', upper(label));
0224 %         fprintf('%s\n', sections(s).name);
0225 %     end
0226 end
0227 
0228 %%---------------------------------------------------------------------
0229 function str = extract_col(n, c)
0230 if c <= length(n)
0231     str = n(c).col;
0232 else
0233     str = '';
0234 end
0235 
0236 %%---------------------------------------------------------------------
0237 function str = extract_col_octave(n, c)
0238 if c <= length(n{1}.col)
0239     str = n{1}.col{c};
0240 else
0241     str = '';
0242 end
0243 
0244 %%---------------------------------------------------------------------
0245 function str = extract_col_dequote(n, c)
0246 if c <= length(n)
0247     str = n(c).col;
0248     if ~isempty(str) && (str(1) == '''' || str(1) == '"')
0249         str = str(2:end-1);
0250     end
0251 else
0252     str = '';
0253 end
0254 
0255 %%---------------------------------------------------------------------
0256 function str = extract_col_dequote_octave(n, c)
0257 if c <= length(n{1}.col)
0258     str = n{1}.col{c};
0259     if ~isempty(str) && (str(1) == '''' || str(1) == '"')
0260         str = str(2:end-1);
0261     end
0262 else
0263     str = '';
0264 end
0265 
0266 %%---------------------------------------------------------------------
0267 function num = extract_col_num(n, c, t)
0268 if c <= length(n) && ~isempty(n(c).col)
0269     num = sscanf(n(c).col, ['%' t]);
0270 else
0271     num = NaN;
0272 end
0273 
0274 %%---------------------------------------------------------------------
0275 function num = extract_col_num_octave(n, c, t)
0276 if c <= length(n{1}.col) && ~isempty(n{1}.col{c})
0277     num = sscanf(n{1}.col{c}, ['%' t]);
0278 else
0279     num = NaN;
0280 end
0281 
0282 %%---------------------------------------------------------------------
0283 function num = extract_col_qnum(n, c, t)
0284 if c <= length(n)
0285     str = n(c).col;
0286     if isempty(str)
0287         num = NaN;
0288     elseif str(1) == '''' || str(1) == '"'
0289         str = str(2:end-1);
0290     end
0291     num = sscanf(str, ['%' t]);
0292 else
0293     num = NaN;
0294 end
0295 
0296 %%---------------------------------------------------------------------
0297 function num = extract_col_qnum_octave(n, c, t)
0298 if c <= length(n{1}.col)
0299     str = n{1}.col{c};
0300     if isempty(str)
0301         num = NaN;
0302     elseif str(1) == '''' || str(1) == '"'
0303         str = str(2:end-1);
0304     end
0305     num = sscanf(str, ['%' t]);
0306 else
0307     num = NaN;
0308 end

Generated on Fri 20-Mar-2015 18:23:34 by m2html © 2005