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 % $Id: psse_parse_line.m 2319 2014-05-06 19:58:12Z ray $ 0038 % by Ray Zimmerman, PSERC Cornell 0039 % Copyright (c) 2014 by Power System Engineering Research Center (PSERC) 0040 % 0041 % This file is part of MATPOWER. 0042 % See http://www.pserc.cornell.edu/matpower/ for more info. 0043 % 0044 % MATPOWER is free software: you can redistribute it and/or modify 0045 % it under the terms of the GNU General Public License as published 0046 % by the Free Software Foundation, either version 3 of the License, 0047 % or (at your option) any later version. 0048 % 0049 % MATPOWER is distributed in the hope that it will be useful, 0050 % but WITHOUT ANY WARRANTY; without even the implied warranty of 0051 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0052 % GNU General Public License for more details. 0053 % 0054 % You should have received a copy of the GNU General Public License 0055 % along with MATPOWER. If not, see <http://www.gnu.org/licenses/>. 0056 % 0057 % Additional permission under GNU GPL version 3 section 7 0058 % 0059 % If you modify MATPOWER, or any covered work, to interface with 0060 % other modules (such as MATLAB code and MEX-files) available in a 0061 % MATLAB(R) or comparable environment containing parts covered 0062 % under other licensing terms, the licensors of MATPOWER grant 0063 % you additional permission to convey the resulting work. 0064 0065 %% read the line 0066 if ischar(str) 0067 ln = str; 0068 else 0069 ln = fgets(str); 0070 end 0071 0072 if ischar(ln) 0073 %% parse the line 0074 delim = '\s*(,|\s)\s*'; %% general delimiter 0075 repeatdelim = '\s*,\s*|\t'; %% delimiter that allows repeated delimiters 0076 non_quote_field = '[^''",\s/]+'; 0077 single_quote_field = '''([^'']|'''')*'''; 0078 double_quote_field = '"([^"]|"")*"'; 0079 any_field = sprintf('(?<col>%s|%s|%s)', non_quote_field, single_quote_field, double_quote_field); 0080 pat = sprintf('%s%s|%s|%s|(?<comment>/.*)?', any_field, delim, repeatdelim, any_field); 0081 % pat = '(?<col>[^''",\s/]+|''([^'']|'''')*''|"([^"]|"")*")\s*(,|\s)\s*|\s*,\s*|\t|(?<col>[^''",\s/]+|''([^'']|'''')*''|"([^"]|"")*")|(?<comment>/.*)?'; 0082 n = regexp(ln, pat, 'names'); 0083 0084 %% extract data 0085 if have_fcn('octave') 0086 nc = length(n.col); 0087 if nc && isempty(n.col{nc}) 0088 data = n.col(1:nc-1); 0089 if ~isempty(n.comment{nc}) 0090 comment = strtrim(n.comment{nc}(2:end)); 0091 else 0092 comment = ''; 0093 end 0094 nc = nc - 1; 0095 else 0096 data = n.col; 0097 comment = ''; 0098 end 0099 else 0100 nc = length(n); 0101 if nc && isempty(n(nc).col) 0102 [data{1:nc-1}] = deal(n(1:nc-1).col); 0103 if ~isempty(n(nc).comment) 0104 comment = strtrim(n(nc).comment(2:end)); 0105 else 0106 comment = ''; 0107 end 0108 nc = nc - 1; 0109 else 0110 [data{1:nc}] = deal(n.col); 0111 comment = ''; 0112 end 0113 end 0114 0115 %% check for section end and Q record 0116 if length(data) == 1 && length(data{1}) == 1 0117 if data{1}(1) == '0' 0118 data{1} = 0; 0119 elseif data{1}(1) == 'Q' 0120 data = {}; 0121 end 0122 end 0123 else 0124 data = {}; 0125 comment = ''; 0126 end 0127 0128 %% clean/convert data (convert numeric, strip quotes from strings) 0129 if nargin > 1 && ~isempty(t) && ~isempty(data) && ... 0130 (length(data) ~= 1 || ~isnumeric(data{1}) || data{1} ~= 0) 0131 nt = length(t); 0132 for k = 1:min(nc, nt) 0133 switch t(k) 0134 case {'D', 'F', 'G', 's', 'c'} 0135 if ~isempty(data{k}) && (data{k}(1) == '''' || data{k}(1) == '"') 0136 data{k} = data{k}(2:end-1); 0137 end 0138 % otherwise %% do nothing 0139 end 0140 switch upper(t(k)) 0141 case {'D', 'F', 'G'} 0142 data{k} = sscanf(data{k}, ['%' lower(t(k))]); 0143 % otherwise %% do nothing 0144 end 0145 end 0146 if nc < nt 0147 data(nc+1:nt) = cell(1,nt-nc); 0148 end 0149 end