Home > matpower5.0 > 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 %   $Id: psse_parse_section.m 2319 2014-05-06 19:58:12Z ray $
0059 %   by Ray Zimmerman, PSERC Cornell
0060 %   Copyright (c) 2014 by Power System Engineering Research Center (PSERC)
0061 %
0062 %   This file is part of MATPOWER.
0063 %   See http://www.pserc.cornell.edu/matpower/ for more info.
0064 %
0065 %   MATPOWER is free software: you can redistribute it and/or modify
0066 %   it under the terms of the GNU General Public License as published
0067 %   by the Free Software Foundation, either version 3 of the License,
0068 %   or (at your option) any later version.
0069 %
0070 %   MATPOWER is distributed in the hope that it will be useful,
0071 %   but WITHOUT ANY WARRANTY; without even the implied warranty of
0072 %   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0073 %   GNU General Public License for more details.
0074 %
0075 %   You should have received a copy of the GNU General Public License
0076 %   along with MATPOWER. If not, see <http://www.gnu.org/licenses/>.
0077 %
0078 %   Additional permission under GNU GPL version 3 section 7
0079 %
0080 %   If you modify MATPOWER, or any covered work, to interface with
0081 %   other modules (such as MATLAB code and MEX-files) available in a
0082 %   MATLAB(R) or comparable environment containing parts covered
0083 %   under other licensing terms, the licensors of MATPOWER grant
0084 %   you additional permission to convey the resulting work.
0085 
0086 %% defaults
0087 if nargin < 3
0088     have_sections = 0;
0089     verbose = 0;
0090     template = '';
0091 elseif isstruct(sections)
0092     have_sections = 1;
0093     if nargin < 7
0094         template = '';
0095         if nargin < 6
0096             label = '';
0097             if nargin < 5
0098                 verbose = 0;
0099             else
0100                 error('psse_parse_section: too few input arguments');
0101             end
0102         end
0103     end
0104 else
0105     have_sections = 0;
0106     if nargin >= 5
0107         template = verbose;
0108     else
0109         template = '';
0110     end
0111     if nargin >= 4
0112         label = s;
0113     else
0114         label = '';
0115     end
0116     verbose = sections;
0117 end
0118 
0119 %% get relevant records, check section name
0120 nt = length(template);
0121 if have_sections
0122     nr = sections(s).last - sections(s).first + 1;
0123     recs = records(sections(s).first:sections(s).last);
0124     if ~isempty(sections(s).name) && ~strcmpi(label, sections(s).name)
0125         warns{end+1} = sprintf('Section label mismatch, found ''%s'', expected ''%s''', ...
0126             sections(s).name, upper(label));
0127         if verbose
0128             fprintf('-----  WARNING:  Found section labeled:    ''%s''\n', sections(s).name);
0129             fprintf('-----            Expected section labeled: ''%s''\n', upper(label));
0130         end
0131     end
0132 else
0133     nr = length(records);
0134     recs = records;
0135 end
0136 if verbose
0137     spacers = repmat('.', 1, 42-length(label));
0138     fprintf('Parsing %6d lines of %s data %s', nr, label, spacers);
0139 end
0140 
0141 if nr
0142     %% set up regexp to parse cols, comments of each record
0143     delim = '\s*(,|\s)\s*';     %% general delimiter
0144     repeatdelim = '\s*,\s*|\t'; %% delimiter that allows repeated delimiters
0145     non_quote_field = '[^''",\s/]+';
0146     single_quote_field = '''([^'']|'''')*''';
0147     double_quote_field = '"([^"]|"")*"';
0148     any_field = sprintf('(?<col>%s|%s|%s)', non_quote_field, single_quote_field, double_quote_field);
0149     pat = sprintf('%s%s|%s|%s|(?<comment>/.*)?', any_field, delim, repeatdelim, any_field);
0150     % pat = '(?<col>[^''",\s/]+|''([^'']|'''')*''|"([^"]|"")*")\s*(,|\s)\s*|\s*,\s*|\t|(?<col>[^''",\s/]+|''([^'']|'''')*''|"([^"]|"")*")|(?<comment>/.*)?';
0151 
0152     %% set up functions for use with cellfun
0153     if have_fcn('octave')
0154         parser  = @(ln){{regexp(ln, pat, 'names')}};  %% parse cols, comments of each rec
0155         numcols = @(ss)length(ss{1}.col);   %% number of columns in each record
0156     else
0157         parser  = @(ln){regexp(ln, pat, 'names')};  %% parse cols, comments of each rec
0158         numcols = @(ss)length(ss);      %% number of columns in each record
0159     end
0160 
0161     %% parse the table into cell array of structs (with col, comment fields)
0162     dd = cellfun(parser, recs);
0163 
0164 %     %% extract possible comments
0165 %     if nargout > 2
0166 %     %   extract_comment = @(n){n(end).comment};
0167 %         if have_fcn('octave')
0168 %             comment = cellfun(@(n){n{1}.comment(end)}, dd);
0169 %         else
0170 %             comment = cellfun(@(n){n(end).comment}, dd);
0171 %         end
0172 %     end
0173 
0174     %% find max number of columns
0175     nc = cellfun(numcols, dd);      %% number of columns
0176     ncmax = max(nc);
0177     ncmin = min(nc);
0178 
0179     %% extract data by column
0180     % nc = length(dd{1});
0181     % if nc && isempty(dd{1}(nc).col)   %% comment present
0182     %   nc = nc - 1;                %% reduce number of columns by 1 to discard
0183     % end
0184     data.num = NaN(nr, max(ncmax, nt));
0185     data.txt = cell(nr, max(ncmax, nt));
0186     for c = 1:ncmax
0187         %% template for conversion?
0188         if c <= nt
0189             t = template(c);
0190         else
0191             t = '';
0192         end
0193         if have_fcn('octave')   %% running under Octave
0194             switch t
0195                 case {'d', 'f', 'g', 'D', 'F', 'G'} %% numeric data
0196                     if t == upper(t)                %% possibly quoted
0197                         xc_fcn  = @(n)extract_col_qnum_octave(n, c, lower(t));
0198                     else                            %% not quoted (more efficient)
0199                         xc_fcn  = @(n)extract_col_num_octave(n, c, t);
0200                     end
0201                 case {'s', 'c'}
0202                     xc_fcn  = @(n){extract_col_dequote_octave(n, c)};
0203                 otherwise
0204                     if c <= ncmin
0205                         xc_fcn  = @(n)n{1}.col(c);
0206                     else
0207                         xc_fcn  = @(n){extract_col_octave(n, c)};
0208                     end
0209             end
0210         else                    %% running under Matlab
0211             switch t
0212                 case {'d', 'f', 'g', 'D', 'F', 'G'} %% numeric data
0213                     if t == upper(t)                %% possibly quoted
0214                         xc_fcn  = @(n)extract_col_qnum(n, c, lower(t));
0215                     else                            %% not quoted (more efficient)
0216                         xc_fcn  = @(n)extract_col_num(n, c, t);
0217                     end
0218                 case {'s', 'c'}
0219                     xc_fcn  = @(n){extract_col_dequote(n, c)};
0220                 otherwise
0221                     if c <= ncmin
0222                         xc_fcn  = @(n){n(c).col};
0223                     else
0224                         xc_fcn  = @(n){extract_col(n, c)};
0225                     end
0226             end
0227         end
0228         switch upper(t)
0229             case {'D', 'F', 'G'}
0230                 data.num(:, c) = cellfun(xc_fcn, dd);
0231             otherwise
0232                 data.txt(:, c) = cellfun(xc_fcn, dd);
0233         end
0234     end
0235 else
0236     data.num = NaN(nr, nt);
0237     data.txt = cell(nr, nt);
0238 end
0239 if verbose
0240     fprintf(' done.\n');
0241 %     if have_sections
0242 %         fprintf('%s\n', upper(label));
0243 %         fprintf('%s\n', sections(s).name);
0244 %     end
0245 end
0246 
0247 %%---------------------------------------------------------------------
0248 function str = extract_col(n, c)
0249 if c <= length(n)
0250     str = n(c).col;
0251 else
0252     str = '';
0253 end
0254 
0255 %%---------------------------------------------------------------------
0256 function str = extract_col_octave(n, c)
0257 if c <= length(n{1}.col)
0258     str = n{1}.col{c};
0259 else
0260     str = '';
0261 end
0262 
0263 %%---------------------------------------------------------------------
0264 function str = extract_col_dequote(n, c)
0265 if c <= length(n)
0266     str = n(c).col;
0267     if ~isempty(str) && (str(1) == '''' || str(1) == '"')
0268         str = str(2:end-1);
0269     end
0270 else
0271     str = '';
0272 end
0273 
0274 %%---------------------------------------------------------------------
0275 function str = extract_col_dequote_octave(n, c)
0276 if c <= length(n{1}.col)
0277     str = n{1}.col{c};
0278     if ~isempty(str) && (str(1) == '''' || str(1) == '"')
0279         str = str(2:end-1);
0280     end
0281 else
0282     str = '';
0283 end
0284 
0285 %%---------------------------------------------------------------------
0286 function num = extract_col_num(n, c, t)
0287 if c <= length(n) && ~isempty(n(c).col)
0288     num = sscanf(n(c).col, ['%' t]);
0289 else
0290     num = NaN;
0291 end
0292 
0293 %%---------------------------------------------------------------------
0294 function num = extract_col_num_octave(n, c, t)
0295 if c <= length(n{1}.col) && ~isempty(n{1}.col{c})
0296     num = sscanf(n{1}.col{c}, ['%' t]);
0297 else
0298     num = NaN;
0299 end
0300 
0301 %%---------------------------------------------------------------------
0302 function num = extract_col_qnum(n, c, t)
0303 if c <= length(n)
0304     str = n(c).col;
0305     if isempty(str)
0306         num = NaN;
0307     elseif str(1) == '''' || str(1) == '"'
0308         str = str(2:end-1);
0309     end
0310     num = sscanf(str, ['%' t]);
0311 else
0312     num = NaN;
0313 end
0314 
0315 %%---------------------------------------------------------------------
0316 function num = extract_col_qnum_octave(n, c, t)
0317 if c <= length(n{1}.col)
0318     str = n{1}.col{c};
0319     if isempty(str)
0320         num = NaN;
0321     elseif str(1) == '''' || str(1) == '"'
0322         str = str(2:end-1);
0323     end
0324     num = sscanf(str, ['%' t]);
0325 else
0326     num = NaN;
0327 end

Generated on Mon 26-Jan-2015 15:21:31 by m2html © 2005