PSSE_PARSE_LINE Reads and parses a single line from a PSS/E RAW data file [DATA, COMMENT] = PSSE_PARSE_LINE(FID) [DATA, COMMENT] = PSSE_PARSE_LINE(FID, TEMPLATE) [DATA, COMMENT] = PSSE_PARSE_LINE(STR) [DATA, COMMENT] = PSSE_PARSE_LINE(STR, TEMPLATE) Parses a single line from a PSS/E RAW data file, either directly read from the file, or passed as a string. Inputs: FID : (optional) file id of file from which to read the line STR : string containing the line to be parsed 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 STR that have no valid corresponding entry in TEMPLATE (beyond end of TEMPLATE, or a character other than those listed, e.g. '.') are returned as a string with no conversion. TEMPLATE entries for which there is no corresponding column are returned as NaN or empty string, depending on the type. Outputs: DATA : a cell array whose elements contain the contents of the corresponding column in the data, converted according to the TEMPLATE. COMMENT : (optional) possible comment at the end of the line
0001 function [data, comment] = psse_parse_line(str, t) 0002 %PSSE_PARSE_LINE Reads and parses a single line from a PSS/E RAW data file 0003 % [DATA, COMMENT] = PSSE_PARSE_LINE(FID) 0004 % [DATA, COMMENT] = PSSE_PARSE_LINE(FID, TEMPLATE) 0005 % [DATA, COMMENT] = PSSE_PARSE_LINE(STR) 0006 % [DATA, COMMENT] = PSSE_PARSE_LINE(STR, TEMPLATE) 0007 % 0008 % Parses a single line from a PSS/E RAW data file, either directly read 0009 % from the file, or passed as a string. 0010 % 0011 % Inputs: 0012 % FID : (optional) file id of file from which to read the line 0013 % STR : string containing the line to be parsed 0014 % TEMPLATE : (optional) string of characters indicating how to 0015 % interpret the type of the corresponding column, options 0016 % are as follows: 0017 % d, f or g : integer floating point number to be converted 0018 % via SSCANF with %d, %f or %g, respectively. 0019 % D, F or G : integer floating point number, possibly enclosed 0020 % in single or double quotes, to be converted via 0021 % SSCANF with %d, %f or %g, respectively. 0022 % c or s : character or string, possibly enclosed in single 0023 % or double quotes, which are stripped from the string 0024 % Note: Data columns in STR that have no valid corresponding 0025 % entry in TEMPLATE (beyond end of TEMPLATE, or a character 0026 % other than those listed, e.g. '.') are returned as a 0027 % string with no conversion. TEMPLATE entries for which 0028 % there is no corresponding column are returned as NaN or 0029 % empty string, depending on the type. 0030 % Outputs: 0031 % DATA : a cell array whose elements contain the contents of 0032 % the corresponding column in the data, converted 0033 % according to the TEMPLATE. 0034 % COMMENT : (optional) possible comment at the end of the line 0035 0036 % MATPOWER 0037 % Copyright (c) 2014-2015 by Power System Engineering Research Center (PSERC) 0038 % by Ray Zimmerman, PSERC Cornell 0039 % 0040 % $Id: psse_parse_line.m 2644 2015-03-11 19:34:22Z ray $ 0041 % 0042 % This file is part of MATPOWER. 0043 % Covered by the 3-clause BSD License (see LICENSE file for details). 0044 % See http://www.pserc.cornell.edu/matpower/ for more info. 0045 0046 %% read the line 0047 if ischar(str) 0048 ln = str; 0049 else 0050 ln = fgets(str); 0051 end 0052 0053 if ischar(ln) 0054 %% parse the line 0055 delim = '\s*(,|\s)\s*'; %% general delimiter 0056 repeatdelim = '\s*,\s*|\t'; %% delimiter that allows repeated delimiters 0057 non_quote_field = '[^''",\s/]+'; 0058 single_quote_field = '''([^'']|'''')*'''; 0059 double_quote_field = '"([^"]|"")*"'; 0060 any_field = sprintf('(?<col>%s|%s|%s)', non_quote_field, single_quote_field, double_quote_field); 0061 pat = sprintf('%s%s|%s|%s|(?<comment>/.*)?', any_field, delim, repeatdelim, any_field); 0062 % pat = '(?<col>[^''",\s/]+|''([^'']|'''')*''|"([^"]|"")*")\s*(,|\s)\s*|\s*,\s*|\t|(?<col>[^''",\s/]+|''([^'']|'''')*''|"([^"]|"")*")|(?<comment>/.*)?'; 0063 n = regexp(ln, pat, 'names'); 0064 0065 %% extract data 0066 if have_fcn('octave') 0067 nc = length(n.col); 0068 if nc && isempty(n.col{nc}) 0069 data = n.col(1:nc-1); 0070 if ~isempty(n.comment{nc}) 0071 comment = strtrim(n.comment{nc}(2:end)); 0072 else 0073 comment = ''; 0074 end 0075 nc = nc - 1; 0076 else 0077 data = n.col; 0078 comment = ''; 0079 end 0080 else 0081 nc = length(n); 0082 if nc && isempty(n(nc).col) 0083 [data{1:nc-1}] = deal(n(1:nc-1).col); 0084 if ~isempty(n(nc).comment) 0085 comment = strtrim(n(nc).comment(2:end)); 0086 else 0087 comment = ''; 0088 end 0089 nc = nc - 1; 0090 else 0091 [data{1:nc}] = deal(n.col); 0092 comment = ''; 0093 end 0094 end 0095 0096 %% check for section end and Q record 0097 if length(data) == 1 && length(data{1}) == 1 0098 if data{1}(1) == '0' 0099 data{1} = 0; 0100 elseif data{1}(1) == 'Q' 0101 data = {}; 0102 end 0103 end 0104 else 0105 data = {}; 0106 comment = ''; 0107 end 0108 0109 %% clean/convert data (convert numeric, strip quotes from strings) 0110 if nargin > 1 && ~isempty(t) && ~isempty(data) && ... 0111 (length(data) ~= 1 || ~isnumeric(data{1}) || data{1} ~= 0) 0112 nt = length(t); 0113 for k = 1:min(nc, nt) 0114 switch t(k) 0115 case {'D', 'F', 'G', 's', 'c'} 0116 if ~isempty(data{k}) && (data{k}(1) == '''' || data{k}(1) == '"') 0117 data{k} = data{k}(2:end-1); 0118 end 0119 % otherwise %% do nothing 0120 end 0121 switch upper(t(k)) 0122 case {'D', 'F', 'G'} 0123 data{k} = sscanf(data{k}, ['%' lower(t(k))]); 0124 % otherwise %% do nothing 0125 end 0126 end 0127 if nc < nt 0128 data(nc+1:nt) = cell(1,nt-nc); 0129 end 0130 end