📄 readdiffile.m
字号:
function DIF_struct = readDIFfile( DIF_full_filename, code )
index = 0;
if nargin>1 && strcmp(code,'index')
index = 1;
end
% DIF_full_filename a string containing the output filename (including path)
% Prompt user to select filename if unspecified:
if ~exist('DIF_full_filename') || isempty(DIF_full_filename)
% Load pathname for DIF file used in last analysis, if available, otherwise create empty string:
if exist('tmp_DIF_path.mat','file'), load('tmp_DIF_path'); end
if ~exist('DIF_path','var') || ~isstr(DIF_path), DIF_path = ''; end
% Assemble filename:
[DIF_filename, DIF_path]= uigetfile({'*.csv','CSV (Comma delimited)(*.csv)'},'Select DIF file', DIF_path);
if any(DIF_filename~=0)
DIF_full_filename = fullfile( DIF_path, DIF_filename);
save('tmp_DIF_path','DIF_path');
else
DIF_struct.error = 1; return;
end
end
DIF_struct.d = []; % initialize data structure
err_dlgname = 'Error reading DIF file';
% open specified building input file:
fid = fopen( DIF_full_filename );
if fid==-1
err = errordlg('Unable to open file. Check file path and permissions.', err_dlgname);
uiwait(err); DIF_struct.error = 1; return;
end
% read each row in the input file as a separate string:
file_contents = textscan( fid, '%s ', 'delimiter', '\n', 'commentStyle', '%');
% extract a cell array from the textscan output:
file_contents = file_contents{1};
% identify the rows containing keyword entries
key_ind = strmatch('*',file_contents);
if isempty(key_ind)
err = errordlg('No keywords (indicated by asterisks) were found in the input file', err_dlgname);
uiwait(err); DIF_struct.error = 1; return;
end
% total lines in file:
file_lines = length(file_contents);
% loop through keyword entries and extract specified values:
for i = 1:length(key_ind)
keyword_line = file_contents{key_ind(i)};
keyword = strtok( keyword_line(2:end), ', ');
keyword_list{i} = keyword;
if strcmp( keyword, 'UNITS' )
% Three entries expected on one line (length_units, force_units, ws_units), one header line:
units_string = file_contents{key_ind(i)+2};
units_string_spc = strrep( units_string, ',', ' '); % replace commas with spaces
units = strread( strtrim(units_string_spc), '%s', 'delimiter', ' ');
allowed_length_unit = {'ft'};
allowed_force_unit = {'lb'};
allowed_ws_unit = {'ft/s'};
if length(units)~=3
err = errordlg(['The *UNITS section does not contain the expected number (3) of entries. ' ...
'Quoting from DIF file: >> ' units_string ' <<'], err_dlgname);
uiwait(err); DIF_struct.error = 1; return;
elseif ~ismember(units{1}, allowed_length_unit)
err = errordlg(['The first entry in the *UNITS section ("' units{1} ...
'") is not allowed: only "ft" is currently allowed for length units.'], err_dlgname);
uiwait(err); DIF_struct.error = 1; return;
elseif ~ismember(units{2}, allowed_force_unit)
err = errordlg(['The second entry in the *UNITS section ("' units{2} ...
'") is not allowed: only "lb" is currently allowed for force units.'], err_dlgname);
uiwait(err); DIF_struct.error = 1; return;
elseif ~ismember(units{3}, allowed_ws_unit)
err = errordlg(['The third entry in the *UNITS section ("' units{3} ...
'") is not allowed: only "ft/s" is currently allowed for wind speed units.'], err_dlgname);
uiwait(err); DIF_struct.error = 1; return;
else
DIF_struct.length_units = units{1};
DIF_struct.force_units = units{2};
DIF_struct.ws_units = units{3};
end
elseif strcmp( keyword, 'BUILDING_DIMENSIONS' )
% Four entries expected on one line (height, width, ridge_length, slope), one header line:
dimensions_string = file_contents{key_ind(i)+2};
dimensions_string_spc = strrep( dimensions_string, ',', ' '); % replace commas with spaces
dimensions = strread(strtrim(dimensions_string_spc)); % trim trailing spaces, read numerical values
if length(dimensions)~=4
err = errordlg(['The *BUILDING_DIMENSIONS section does not contain the expected number (4) of entries. ' ...
'Quoting from input file: >> ' dimensions_string ' <<'], err_dlgname );
uiwait(err); DIF_struct.error = 1; return;
else
DIF_struct.d0 = dimensions; % (W0, L0, H0, R0)
end
elseif strcmp( keyword, 'WEIGHTING_FACTORS' )
% One header row, one line of numerical data (one entry per model)
wf_string = file_contents{key_ind(i)+2};
wf_string_spc = strrep( wf_string, ',', ' '); % replace commas with spaces
wf = strread(strtrim(wf_string_spc)); % trim trailing spaces, read numerical values
DIF_struct.wf = wf;
elseif strcmp( keyword, 'MODEL_DIMENSIONS' )
% Four entries expected on each line (height, width, ridge_length, slope), one header line
% one line per model in case of interpolated results:
if i == length(key_ind)
d_str = file_contents(key_ind(i)+2:file_lines);
else
d_str = file_contents(key_ind(i)+2:key_ind(i+1)-1);
end
d_str_spc = strrep( d_str, ',', ' ' ); % replace commas with spaces
n_m = size(d_str_spc,1); % number of models
d = zeros(n_m,4); % initialize matrix for storing numerical values
for j = 1:n_m
row_j = strread(strtrim(d_str_spc{j,:}));
if length(row_j)==4
d(j,:) = row_j(:);
else
err = errordlg(['Row ' num2str(j) ' of the *MODEL_DIMENSIONS section contains ' num2str(length(row_j)) ' entries (4 expected). ' ...
'Quoting from input file: >> ' d_str{j} ' <<' ], err_dlgname );
uiwait(err); DIF_struct.error = 1; return;
end
end
DIF_struct.d = d; % (W, L, H, R)
elseif strcmp( keyword, 'MODEL_TERRAIN' )
% One entries expected on one line:
terrain_string = file_contents{key_ind(i)+1};
terrain_string_spc = strrep( terrain_string, ',', ' '); % replace commas with spaces
terrain = strread( strtrim(terrain_string_spc), '%s', 'delimiter', ' ');
if length(terrain)~=1
err = errordlg(['The *TERRAIN section does not contain the expected number (1) of entries. ' ...
'Quoting from input file: >> ' terrain_string ' <<'], err_dlgname);
uiwait(err); DIF_struct.error = 1; return;
elseif ~ismember(terrain,{'Open_Country','Suburban'})
err = errordlg(['The entry in the *TERRAIN section ("' terrain{1} ...
'") is not permitted: only "Open_Country" and "Suburban" are allowed.'], err_dlgname);
uiwait(err); DIF_struct.error = 1; return;
else
DIF_struct.terrain = terrain{1};
end
elseif strcmp( keyword, 'FRAME_LOCATIONS' )
% At least one line expected with two entries per line (frame #, y-coordinate):
if i == length(key_ind)
frame_loc_str = file_contents(key_ind(i)+2:file_lines);
else
frame_loc_str = file_contents(key_ind(i)+2:key_ind(i+1)-1);
end
frame_loc_str_spc = strrep( frame_loc_str, ',', ' ' ); % replace commas with spaces
n_f = size(frame_loc_str,1);
frame_coords = zeros(n_f,3); % initialize matrix for storing numerical values
for j = 1:n_f
% trim trailing spaces, read numerical values, and place in matrix:
row_j = strread(strtrim(frame_loc_str_spc{j,:}));
if length(row_j)==4
if row_j(1)~=j
err = errordlg(['The frame number (' num2str(row_j(1)) ') in row ' num2str(j) ' of the *FRAME_LOCATIONS section ' ...
' is not allowed. Frame numbers must start at 1 and increment by 1.'], err_dlgname );
uiwait(err); DIF_struct.error = 1; return;
else
frame_coords(j,:) = row_j(2:4);
end
else
err = errordlg(['Row ' num2str(j) ' of the *FRAME_LOCATIONS section contains ' num2str(length(row_j)) ' entries (4 expected). ' ...
'Quoting from input file: >> ' frame_loc_str{j} ' <<' ], err_dlgname );
uiwait(err); DIF_struct.error = 1; return;
end
end
DIF_struct.frame_coords = frame_coords;
elseif strcmp( keyword, 'RESPONSE_NAMES' )
% At least one line expected with two entries per line (response #, name):
if i == length(key_ind)
resp_names_str = file_contents(key_ind(i)+2:file_lines);
else
resp_names_str = file_contents(key_ind(i)+2:key_ind(i+1)-1);
end
n_r = length(resp_names_str);
for j = 1:n_r
% trim trailing spaces, read numerical values, and place in matrix:
row_j = resp_names_str{j};
[num_str, rem] = strtok( row_j, ',');
[resp_str, rem] = strtok( rem, ',');
[runit_str, rem] = strtok( rem, ',' );
if isempty(num_str) || str2num(num_str)~=j
err = errordlg(['The response number (' num_str ') in row ' num2str(j) ' of the *RESPONSE_NAMES section ' ...
' is not allowed. Response numbers must start at 1 and increment by 1.'], err_dlgname );
uiwait(err); DIF_struct.error = 1; return;
elseif isempty(resp_str) | isempty(runit_str)
err = errordlg({['Row ' num2str(row_j(1)) ' of the *RESPONSE_NAMES section contains fewer than the expected ' ...
'number of entries (3). Quoting from input file:'],[' ' row_j ]}, err_dlgname );
uiwait(err); DIF_struct.error = 1; return;
elseif ~isempty(setdiff(rem,', '))
err = errordlg({['Row ' num2str(row_j(1)) ' of the *RESPONSE_NAMES section contains more than the expected ' ...
'number of entries (3). Quoting from input file:'],[' ' row_j ]}, err_dlgname );
uiwait(err); DIF_struct.error = 1; return;
else
resp_names{j} = resp_str;
resp_units{j} = runit_str;
end
end
DIF_struct.resp_names = resp_names;
DIF_struct.resp_units = resp_units;
elseif strcmp( keyword, 'ATTACHMENT_LOCATIONS' )
% At least four rows expected, with three entries per row: (index, face #, s-coordinate)
if i == length(key_ind)
attach_str = file_contents(key_ind(i)+2:file_lines);
else
attach_str = file_contents(key_ind(i)+2:key_ind(i+1)-1);
end
attach_str_spc = strrep( attach_str, ',', ' ' ); % replace commas with spaces
n_a1 = size(attach_str_spc,1); % number of attachment points
% check number of entries in first row:
for j = 1:n_a1
row_j = strread(strtrim(attach_str_spc{j,:}));
if row_j(1)~=j
err = errordlg(['The index number (' num2str(row_j(1)) ') in row ' num2str(j) ' of the *ATTACHMENT_LOCATIONS section ' ...
'is not allowed. Index numbers must start at 1 and increment by 1.'], err_dlgname );
uiwait(err); DIF_struct.error = 1; return;
elseif length(row_j)~=3
err = errordlg({['Row ' num2str(j) ' of the *ATTACHMENT_LOCATIONS section does not contain '...
'the expected number of entries (3). Quoting from input file:'],...
[' >> ' inf_coeff_str{j} ' <<' ]}, err_dlgname );
uiwait(err); DIF_struct.error = 1; return;
end
attach_pts(j,:) = row_j(2:3);
end
for j = 1:4
if any(attach_pts(find(attach_pts(:,1)==j),2)~=sort(attach_pts(find(attach_pts(:,1)==j),2)))
err = errordlg(['The s-coordinates for face ' num2str(j) ' in the *ATTACHMENT_LOCATIONS section are not ' ...
'sorted in ascending order, as is required.'], err_dlgname );
uiwait(err); DIF_struct.error = 1; return;
end
end
DIF_struct.attach_pts = attach_pts;
% ================== O B S E R V E D P E A K S ==========================
elseif strcmp( keyword, 'DIF_OBS_MAX' )
if index, continue, end;
if ~exist('n_r','var')
err = errordlg('The *RESPONSE_NAMES section must preceed the *DIF_OBS_MAX section', err_dlgname );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -