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 );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if ~exist('n_f','var')
            err = errordlg('The *FRAME_LOCATIONS section must preceed the *DIF_OBS_MAX section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if i == length(key_ind)
            dif_str = file_contents(key_ind(i)+1:file_lines);
        else
            dif_str = file_contents(key_ind(i)+1:key_ind(i+1)-1);
        end
        % Eliminate header rows:
        num_ind = intersect(find(~strncmp('Frame',dif_str,5)),find(~strncmp('Wind',dif_str,4)));
        dif_str = dif_str(num_ind);
        dif_str_spc = strrep( dif_str, ',', ' ' ); % replace commas with spaces
        n_q = size(dif_str,1)/n_f;
        if round(n_q)~=n_q
            err = errordlg(['The number of rows (' num2str(size(dif_str,1)) ') in the *DIF_OBS_MAX section ' ...
                ' indicates that the number of wind directions per frame is inconsistent.'], err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        X_max_obs = zeros(n_r,n_q,n_f);
        for j = 1:n_f
            for k = 1:n_q
                ind = n_q*(j-1)+k; % number of the current row (skip two headers for each frame)
                row_k = strread(strtrim(dif_str_spc{ind,:}));
                if length(row_k)~=n_r+1
                    err = errordlg(['Row ' num2str(ind) ' of the *DIF_OBS_MAX section (excluding headers) contains ' ...
                        num2str(length(row_k)) ' entries (' num2str(n_r+1) ' expected).'], err_dlgname );
                    uiwait(err); DIF_struct.error = 1; return;
                end
                theta(k,1) = row_k(1);
                X_max_obs(:,k,j) = row_k(2:end);
            end
            if ~exist('theta_save','var')
                DIF_struct.theta = theta;
                theta_save = theta;
            else
                if any(size(theta_save)~=size(theta)) || any( theta_save~=theta)
                    err = errordlg('Inconsistent wind direction list found in *DIF_OBS_MAX section.', err_dlgname );
                    uiwait(err); DIF_struct.error = 1; return;
                end
            end
        end
        DIF_struct.X_max_obs = X_max_obs;
    elseif strcmp( keyword, 'DIF_OBS_MIN' )
        if index, continue, end;

        if ~exist('n_r','var')
            err = errordlg('The *RESPONSE_NAMES section must preceed the *DIF_OBS_MIN section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if ~exist('n_f','var')
            err = errordlg('The *FRAME_LOCATIONS section must preceed the *DIF_OBS_MIN section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if i == length(key_ind)
            dif_str = file_contents(key_ind(i)+1:file_lines);
        else
            dif_str = file_contents(key_ind(i)+1:key_ind(i+1)-1);
        end
        % Eliminate header rows:
        num_ind = intersect(find(~strncmp('Frame',dif_str,5)),find(~strncmp('Wind',dif_str,4)));
        dif_str = dif_str(num_ind);
        dif_str_spc = strrep( dif_str, ',', ' ' ); % replace commas with spaces
        n_q = size(dif_str,1)/n_f;
        if round(n_q)~=n_q
            err = errordlg(['The number of rows (' num2str(size(dif_str,1)) ') in the *DIF_OBS_MIN section ' ...
                ' indicates that the number of wind directions per frame is inconsistent.'], err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        X_min_obs = zeros(n_r,n_q,n_f);
        for j = 1:n_f
            for k = 1:n_q
                ind = n_q*(j-1)+k; % number of the current row (skip two headers for each frame)
                row_k = strread(strtrim(dif_str_spc{ind,:}));
                if length(row_k)~=n_r+1
                    err = errordlg(['Row ' num2str(ind) ' of the *DIF_OBS_MIN section (excluding header rows) contains ' ...
                        num2str(length(row_k)) ' entries (' num2str(n_r+1) ' expected).'], err_dlgname );
                    uiwait(err); DIF_struct.error = 1; return;
                end
                theta(k,1) = row_k(1);
                X_min_obs(:,k,j) = row_k(2:end);
            end
            if ~exist('theta_save','var')
                DIF_struct.theta = theta(:);
                theta_save = theta;
            else
                if any(size(theta_save)~=size(theta)) || any( theta_save~=theta)
                    err = errordlg('Inconsistent wind direction lists found in *DIF_OBS_MIN section.', err_dlgname );
                    uiwait(err); DIF_struct.error = 1; return;
                end
            end
        end
        DIF_struct.X_min_obs = X_min_obs;
    elseif strcmp( keyword, 'DIF_OBS_MAX_ALL' )
        if index, continue, end;

        if ~exist('n_r','var')
            err = errordlg('The *RESPONSE_NAMES section must preceed the *DIF_OBS_MAX_ALL section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if ~exist('n_f','var')
            err = errordlg('The *FRAME_LOCATIONS section must preceed the *DIF_OBS_MAX_ALL section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if i == length(key_ind)
            dif_str = file_contents(key_ind(i)+1:file_lines);
        else
            dif_str = file_contents(key_ind(i)+1:key_ind(i+1)-1);
        end
        % Eliminate header rows:
        num_ind = intersect(find(~strncmp('Frame',dif_str,5)),find(~strncmp('Wind',dif_str,4)));
        dif_str = dif_str(num_ind);
        dif_str_spc = strrep( dif_str, ',', ' ' ); % replace commas with spaces
        n_qa = size(dif_str,1)/n_f; % total number of wind directions
        if round(n_qa)~=n_qa
            err = errordlg(['The number of rows (' num2str(size(dif_str,1)) ') in the *DIF_OBS_MAX_ALL section ' ...
                ' indicates that the number of wind directions per frame is inconsistent.'], err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        X_max_obs_all = zeros(n_r,n_qa,n_f);
        for j = 1:n_f
            for k = 1:n_qa
                ind = n_qa*(j-1)+k; % number of the current row
                row_k = strread(strtrim(dif_str_spc{ind,:}));
                if length(row_k)~=n_r+1
                    err = errordlg(['Row ' num2str(ind) ' of the *DIF_OBS_MAX_ALL section (excluding header rows) contains '...
                        num2str(length(row_k)) ' entries (' num2str(n_r+1) ' expected).'], err_dlgname );
                    uiwait(err); DIF_struct.error = 1; return;
                end
                theta_all(k,1) = row_k(1);
                X_max_obs_all(:,k,j) = row_k(2:end);
            end
            if ~exist('theta_all_save','var')
                DIF_struct.theta_all= theta_all;
                theta_all_save = theta_all;
            else
                if any(size(theta_all_save)~=size(theta_all)) || any( theta_all_save~=theta_all)
                    err = errordlg('Inconsistent wind direction list found in *DIF_OBS_MAX_ALL section.', err_dlgname );
                    uiwait(err); DIF_struct.error = 1; return;
                end
            end
        end
        DIF_struct.X_max_obs_all = X_max_obs_all;
    elseif strcmp( keyword, 'DIF_OBS_MIN_ALL' )
        if index, continue, end;

        if ~exist('n_r','var')
            err = errordlg('The *RESPONSE_NAMES section must preceed the *DIF_OBS_MIN_ALL section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if ~exist('n_f','var')
            err = errordlg('The *FRAME_LOCATIONS section must preceed the *DIF_OBS_MIN_ALL section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if i == length(key_ind)
            dif_str = file_contents(key_ind(i)+1:file_lines);
        else
            dif_str = file_contents(key_ind(i)+1:key_ind(i+1)-1);
        end
        % Eliminate header rows:
        num_ind = intersect(find(~strncmp('Frame',dif_str,5)),find(~strncmp('Wind',dif_str,4)));
        dif_str = dif_str(num_ind);
        dif_str_spc = strrep( dif_str, ',', ' ' ); % replace commas with spaces
        n_qa = size(dif_str,1)/n_f; % total number of wind directions
        if round(n_qa)~=n_qa
            err = errordlg(['The number of rows (' num2str(size(dif_str,1)) ') in the *DIF_OBS_MIN_ALL section ' ...
                ' indicates that the number of wind directions per frame is inconsistent.'], err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        X_min_obs_all = zeros(n_r,n_qa,n_f);
        for j = 1:n_f
            for k = 1:n_qa
                ind = n_qa*(j-1)+k; % number of the current row
                row_k = strread(strtrim(dif_str_spc{ind,:}));
                if length(row_k)~=n_r+1
                    err = errordlg(['Row ' num2str(ind) ' of the *DIF_OBS_MIN_ALL section (excluding header rows) contains ' ...
                        num2str(length(row_k)) ' entries (' num2str(n_r+1) ' expected).'], err_dlgname );
                    uiwait(err); DIF_struct.error = 1; return;
                end
                theta_all(k,1) = row_k(1);
                X_min_obs_all(:,k,j) = row_k(2:end);
            end
            if ~exist('theta_all_save','var')
                DIF_struct.theta_all= theta_all;
                theta_all_save = theta_all;
            else
                if any(size(theta_all_save)~=size(theta_all)) || any( theta_all_save~=theta_all)
                    err = errordlg('Inconsistent wind direction list found in *DIF_OBS_MIN_ALL section.', err_dlgname );
                    uiwait(err); DIF_struct.error = 1; return;
                end
            end
        end
        DIF_struct.X_min_obs_all = X_min_obs_all;

    elseif strcmp( keyword, 'DIF_OBS_MAX_BND' )
        if index, continue, end;

        if ~exist('n_m','var')
            err = errordlg('The *MODEL_DIMENSIONS section must preceed the *DIF_OBS_MAX_BND section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if ~exist('n_r','var')
            err = errordlg('The *RESPONSE_NAMES section must preceed the *DIF_OBS_MAX_BND section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if ~exist('n_f','var')
            err = errordlg('The *FRAME_LOCATIONS section must preceed the *DIF_OBS_MAX_BND section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if i == length(key_ind)
            dif_str = file_contents(key_ind(i)+1:file_lines);
        else
            dif_str = file_contents(key_ind(i)+1:key_ind(i+1)-1);
        end
        % Eliminate header rows:
        num_ind = intersect(find(~strncmp('Frame',dif_str,5)),intersect(find(~strncmp('Model',dif_str,5)),find(~strncmp('Wind',dif_str,4))));
        dif_str = dif_str(num_ind);
        dif_str_spc = strrep( dif_str, ',', ' ' ); % replace commas with spaces
        n_q = size(dif_str,1)/(n_m*n_f); % total number of wind directions
        if round(n_q)~=n_q
            err = errordlg(['The number of rows (' num2str(size(dif_str,1)) ') in the *DIF_OBS_MAX_BND section ' ...
                ' indicates that the number of wind directions per frame is inconsistent.'], err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        X_max_obs_bnd = zeros(n_r,n_q*n_m,n_f);
        for j = 1:n_f
            for k = 1:n_m
                for ii = 1:n_q
                    ind = n_q*n_m*(j-1)+n_q*(k-1)+ii; % number of the current row
                    row_ii = strread(strtrim(dif_str_spc{ind,:}));
                    if length(row_k)~=n_r+1
                        err = errordlg(['Row ' num2str(ind) ' of the *DIF_OBS_MAX_BND section (excluding header rows) contains '...
                            num2str(length(row_k)) ' entries (' num2str(n_r+1) ' expected).'], err_dlgname );
                        uiwait(err); DIF_struct.error = 1; return;
                    end
                    theta(ii,1) = row_ii(1);
                    X_max_obs_bnd(:,n_q*(k-1)+ii,j) = row_ii(2:end);
                end
                if ~exist('theta_save','var')
                    DIF_struct.theta = theta;
                    theta_save = theta;
                elseif any(size(theta_save)~=size(theta)) || any( theta_save~=theta)
                    err = errordlg('Inconsistent wind direction list found in *DIF_OBS_MAX_BND section.', err_dlgname );
                    uiwait(err); DIF_struct.error = 1; return;
                end
            end
        end
        DIF_struct.X_max_obs_bnd = X_max_obs_bnd;
        
    elseif strcmp( keyword, 'DIF_OBS_MIN_BND' )
        if index, continue, end;

        if ~exist('n_m','var')
            err = errordlg('The *MODEL_DIMENSIONS section must preceed the *DIF_OBS_MIN_BND section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if ~exist('n_r','var')
            err = errordlg('The *RESPONSE_NAMES section must preceed the *DIF_OBS_MIN_BND section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if ~exist('n_f','var')
            err = errordlg('The *FRAME_LOCATIONS section must preceed the *DIF_OBS_MIN_BND section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if i == length(key_ind)
            dif_str = file_contents(key_ind(i)+1:file_lines);
        else
            dif_str = file_contents(key_ind(i)+1:key_ind(i+1)-1);
        end
        % Eliminate header rows:
        num_ind = intersect(find(~strncmp('Frame',dif_str,5)),intersect(find(~strncmp('Model',dif_str,5)),find(~strncmp('Wind',dif_str,4))));
        dif_str = dif_str(num_ind);
        dif_str_spc = strrep( dif_str, ',', ' ' ); % replace commas with spaces
        n_q = size(dif_str,1)/(n_m*n_f); % total number of wind directions
        if round(n_q)~=n_q
            err = errordlg(['The number of rows (' num2str(size(dif_str,1)) ') in the *DIF_OBS_MIN_BND section ' ...
                ' indicates that the number of wind directions per frame is inconsistent.'], err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        X_min_obs_bnd = zeros(n_r,n_q*n_m,n_f);
        for j = 1:n_f
            for k = 1:n_m
                for ii = 1:n_q
                    ind = n_q*n_m*(j-1)+n_q*(k-1)+ii; % number of the current row
                    row_ii = strread(strtrim(dif_str_spc{ind,:}));
                    if length(row_k)~=n_r+1
                        err = errordlg(['Row ' num2str(ind) ' of the *DIF_OBS_MIN_BND section (excluding header rows) contains '...
                            num2str(length(row_k)) ' entries (' num2str(n_r+1) ' expected).'], err_dlgname );
                        uiwait(err); DIF_struct.error = 1; return;
                    end
                    theta(ii,1) = row_ii(1);
                    X_min_obs_bnd(:,n_q*(k-1)+ii,j) = row_ii(2:end);                    
                end
                if ~exist('theta_save','var')
                    DIF_struct.theta = theta;
                    theta_save = theta;
                elseif any(size(theta_save)~=size(theta)) || any( theta_save~=theta)
                    err = errordlg('Inconsistent wind direction list found in *DIF_OBS_MIN_BND section.', err_dlgname );
                    uiwait(err); DIF_struct.error = 1; return;
                end
            end
        end
        DIF_struct.X_min_obs_bnd = X_min_obs_bnd;
        

% ================== E S T I M A T E D   P E A K S ========================

    elseif strcmp( keyword, 'DIF_EST_MAX' )
        if index, continue, end;

        if ~exist('n_r','var')
            err = errordlg('The *RESPONSE_NAMES section must preceed the *DIF_EST_MAX section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if ~exist('n_f','var')
            err = errordlg('The *FRAME_LOCATIONS section must preceed the *DIF_EST_MAX section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if i == length(key_ind)
            dif_str = file_contents(key_ind(i)+1:file_lines);
        else
            dif_str = file_contents(key_ind(i)+1:key_ind(i+1)-1);
        end
        % Eliminate header rows:
        num_ind = intersect(find(~strncmp('Frame',dif_str,5)),find(~strncmp('Wind',dif_str,4)));
        dif_str = dif_str(num_ind);
        dif_str_spc = strrep( dif_str, ',', ' ' ); % replace commas with spaces
        n_q = size(dif_str,1)/n_f;
        if round(n_q)~=n_q
            err = errordlg(['The number of rows (' num2str(size(dif_str,1)) ') in the *DIF_EST_MAX section ' ...
                ' indicates that the number of wind directions per response quantity is inconsistent.'], err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        X_max_est = zeros(n_r,n_q,n_f);
        for j = 1:n_f
            for k = 1:n_q
                ind = n_q*(j-1)+k; % number of the current row (skip two headers for each frame)
                row_k = strread(strtrim(dif_str_spc{ind,:}));
                if length(row_k)~=n_r+1
                    err = errordlg(['Row ' num2str(ind) ' of the *DIF_EST_MAX section (excluding headers) contains ' ...
                        num2str(length(row_k)) ' entries (' num2str(n_r+1) ' expected).'], err_dlgname );
                    uiwait(err); DIF_struct.error = 1; return;
                end
                theta(k,1) = row_k(1);
                X_max_est(:,k,j) = row_k(2:end);
            end
            if ~exist('theta_save','var')
                DIF_struct.theta = theta;
                theta_save = theta;
            elseif any(size(theta_save)~=size(theta)) || any( theta_save~=theta)
                err = errordlg('Inconsistent wind direction list found in *DIF_EST_MAX section.', err_dlgname );
                uiwait(err); DIF_struct.error = 1; return;
            end
        end
        DIF_struct.X_max_est = X_max_est;
    elseif strcmp( keyword, 'DIF_EST_MIN' )
        if index, continue, end;

        if ~exist('n_r','var')
            err = errordlg('The *RESPONSE_NAMES section must preceed the *DIF_EST_MIN section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if ~exist('n_f','var')
            err = errordlg('The *FRAME_LOCATIONS section must preceed the *DIF_EST_MIN section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if i == length(key_ind)
            dif_str = file_contents(key_ind(i)+1:file_lines);
        else
            dif_str = file_contents(key_ind(i)+1:key_ind(i+1)-1);
        end
        % Eliminate header rows:
        num_ind = intersect(find(~strncmp('Frame',dif_str,5)),find(~strncmp('Wind',dif_str,4)));
        dif_str = dif_str(num_ind);
        dif_str_spc = strrep( dif_str, ',', ' ' ); % replace commas with spaces
        n_q = size(dif_str,1)/n_f;
        if round(n_q)~=n_q
            err = errordlg(['The number of rows (' num2str(size(dif_str,1)) ') in the *DIF_EST_MIN section ' ...
                ' indicates that the number of wind directions per response quantity is inconsistent.'], err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        X_min_est = zeros(n_r,n_q,n_f);
        for j = 1:n_f
            for k = 1:n_q
                ind = n_q*(j-1)+k; % number of the current row (skip two headers for each frame)
                row_k = strread(strtrim(dif_str_spc{ind,:}));
                if length(row_k)~=n_r+1
                    err = errordlg(['Row ' num2str(ind) ' of the *DIF_EST_MIN section (excluding header rows) contains ' ...
                        num2str(length(row_k)) ' entries (' num2str(n_r+1) ' expected).'], err_dlgname );
                    uiwait(err); DIF_struct.error = 1; return;
                end
                theta(k,1) = row_k(1);
                X_min_est(:,k,j) = row_k(2:end);
            end
            if ~exist('theta_save','var')
                DIF_struct.theta = theta(:);
                theta_save = theta;
            elseif any(size(theta_save)~=size(theta)) || any( theta_save~=theta)
                err = errordlg('Inconsistent wind direction lists found in *DIF_EST_MIN section.', err_dlgname );
                uiwait(err); DIF_struct.error = 1; return;
            end
        end
        DIF_struct.X_min_est = X_min_est;
    elseif strcmp( keyword, 'DIF_EST_MAX_ALL' )
        if index, continue, end;

        if ~exist('n_r','var')
            err = errordlg('The *RESPONSE_NAMES section must preceed the *DIF_EST_MAX section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if ~exist('n_f','var')
            err = errordlg('The *FRAME_LOCATIONS section must preceed the *DIF_EST_MAX section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if i == length(key_ind)
            dif_str = file_contents(key_ind(i)+1:file_lines);
        else
            dif_str = file_contents(key_ind(i)+1:key_ind(i+1)-1);
        end
        % Eliminate header rows:
        num_ind = intersect(find(~strncmp('Frame',dif_str,5)),find(~strncmp('Wind',dif_str,4)));
        dif_str = dif_str(num_ind);
        dif_str_spc = strrep( dif_str, ',', ' ' ); % replace commas with spaces
        n_qa = size(dif_str,1)/n_f; % total number of wind directions
        if round(n_qa)~=n_qa
            err = errordlg(['The number of rows (' num2str(size(dif_str,1)) ') in the *DIF_EST_MAX_ALL section ' ...
                ' indicates that the number of wind directions per response quantity is inconsistent.'], err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        X_max_est_all = zeros(n_r,n_qa,n_f);
        for j = 1:n_f
            for k = 1:n_qa
                ind = n_qa*(j-1)+k; % number of the current row
                row_k = strread(strtrim(dif_str_spc{ind,:}));
                if length(row_k)~=n_r+1
                    err = errordlg(['Row ' num2str(ind) ' of the *DIF_EST_MAX_ALL section (excluding header rows) contains '...
                        num2str(length(row_k)) ' entries (' num2str(n_r+1) ' expected).'], err_dlgname );
                    uiwait(err); DIF_struct.error = 1; return;
                end
                theta_all(k,1) = row_k(1);
                X_max_est_all(:,k,j) = row_k(2:end);
            end
            if ~exist('theta_all_save','var')
                DIF_struct.theta_all= theta_all;
                theta_all_save = theta_all;
            elseif any(size(theta_all_save)~=size(theta_all)) || any( theta_all_save~=theta_all)
                err = errordlg('Inconsistent wind direction list found in *DIF_EST_MAX_ALL section.', err_dlgname );
                uiwait(err); DIF_struct.error = 1; return;
            end
        end
        DIF_struct.X_max_est_all = X_max_est_all;
    elseif strcmp( keyword, 'DIF_EST_MIN_ALL' )
        if index, continue, end;

        if ~exist('n_r','var')
            err = errordlg('The *RESPONSE_NAMES section must preceed the *DIF_EST_MIN section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if ~exist('n_f','var')
            err = errordlg('The *FRAME_LOCATIONS section must preceed the *DIF_EST_MIN section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if i == length(key_ind)
            dif_str = file_contents(key_ind(i)+1:file_lines);
        else
            dif_str = file_contents(key_ind(i)+1:key_ind(i+1)-1);
        end
        % Eliminate header rows:
        num_ind = intersect(find(~strncmp('Frame',dif_str,5)),find(~strncmp('Wind',dif_str,4)));
        dif_str = dif_str(num_ind);
        dif_str_spc = strrep( dif_str, ',', ' ' ); % replace commas with spaces
        n_qa = size(dif_str,1)/n_f; % total number of wind directions
        if round(n_qa)~=n_qa
            err = errordlg(['The number of rows (' num2str(size(dif_str,1)) ') in the *DIF_EST_MIN_ALL section ' ...
                ' indicates that the number of wind directions per response quantity is inconsistent.'], err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        X_min_est_all = zeros(n_r,n_qa,n_f);
        for j = 1:n_f
            for k = 1:n_qa
                ind = n_qa*(j-1)+k; % number of the current row
                row_k = strread(strtrim(dif_str_spc{ind,:}));
                if length(row_k)~=n_r+1
                    err = errordlg(['Row ' num2str(ind) ' of the *DIF_EST_MIN_ALL section (excluding header rows) contains ' ...
                        num2str(length(row_k)) ' entries (' num2str(n_r+1) ' expected).'], err_dlgname );
                    uiwait(err); DIF_struct.error = 1; return;
                end
                theta_all(k,1) = row_k(1);
                X_min_est_all(:,k,j) = row_k(2:end);
            end
            if ~exist('theta_all_save','var')
                DIF_struct.theta_all= theta_all;
                theta_all_save = theta_all;
            elseif any(size(theta_all_save)~=size(theta_all)) || any( theta_all_save~=theta_all)
                err = errordlg('Inconsistent wind direction list found in *DIF_EST_MIN_ALL section.', err_dlgname );
                uiwait(err); DIF_struct.error = 1; return;
            end
        end
        DIF_struct.X_min_est_all = X_min_est_all;

    elseif strcmp( keyword, 'DIF_EST_MAX_BND' )
        if index, continue, end;

        if ~exist('n_m','var')
            err = errordlg('The *MODEL_DIMENSIONS section must preceed the *DIF_EST_MAX_BND section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if ~exist('n_r','var')
            err = errordlg('The *RESPONSE_NAMES section must preceed the *DIF_EST_MAX_BND section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if ~exist('n_f','var')
            err = errordlg('The *FRAME_LOCATIONS section must preceed the *DIF_EST_MAX_BND section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if i == length(key_ind)
            dif_str = file_contents(key_ind(i)+1:file_lines);
        else
            dif_str = file_contents(key_ind(i)+1:key_ind(i+1)-1);
        end
        % Eliminate header rows:
        num_ind = intersect(find(~strncmp('Frame',dif_str,5)),intersect(find(~strncmp('Model',dif_str,5)),find(~strncmp('Wind',dif_str,4))));
        dif_str = dif_str(num_ind);
        dif_str_spc = strrep( dif_str, ',', ' ' ); % replace commas with spaces
        n_q = size(dif_str,1)/(n_m*n_f); % total number of wind directions
        if round(n_q)~=n_q
            err = errordlg(['The number of rows (' num2str(size(dif_str,1)) ') in the *DIF_EST_MAX_BND section ' ...
                ' indicates that the number of wind directions per frame is inconsistent.'], err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        X_max_est_bnd = zeros(n_r,n_q*n_m,n_f);
        for j = 1:n_f
            for k = 1:n_m
                for ii = 1:n_q
                    ind = n_q*n_m*(j-1)+n_q*(k-1)+ii; % number of the current row
                    row_ii = strread(strtrim(dif_str_spc{ind,:}));
                    if length(row_k)~=n_r+1
                        err = errordlg(['Row ' num2str(ind) ' of the *DIF_EST_MAX_BND section (excluding header rows) contains '...
                            num2str(length(row_k)) ' entries (' num2str(n_r+1) ' expected).'], err_dlgname );
                        uiwait(err); DIF_struct.error = 1; return;
                    end
                    theta(ii,1) = row_ii(1);
                    X_max_est_bnd(:,n_q*(k-1)+ii,j) = row_ii(2:end);
                end
                if ~exist('theta_save','var')
                    DIF_struct.theta = theta;
                    theta_save = theta;
                elseif any(size(theta_save)~=size(theta)) || any( theta_save~=theta)
                    err = errordlg('Inconsistent wind direction list found in *DIF_EST_MAX_BND section.', err_dlgname );
                    uiwait(err); DIF_struct.error = 1; return;
                end
            end
        end
        DIF_struct.X_max_est_bnd = X_max_est_bnd;
        
    elseif strcmp( keyword, 'DIF_EST_MIN_BND' )
        if index, continue, end;

        if ~exist('n_m','var')
            err = errordlg('The *MODEL_DIMENSIONS section must preceed the *DIF_EST_MIN_BND section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if ~exist('n_r','var')
            err = errordlg('The *RESPONSE_NAMES section must preceed the *DIF_EST_MIN_BND section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if ~exist('n_f','var')
            err = errordlg('The *FRAME_LOCATIONS section must preceed the *DIF_EST_MIN_BND section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if i == length(key_ind)
            dif_str = file_contents(key_ind(i)+1:file_lines);
        else
            dif_str = file_contents(key_ind(i)+1:key_ind(i+1)-1);
        end
        % Eliminate header rows:
        num_ind = intersect(find(~strncmp('Frame',dif_str,5)),intersect(find(~strncmp('Model',dif_str,5)),find(~strncmp('Wind',dif_str,4))));
        dif_str = dif_str(num_ind);
        dif_str_spc = strrep( dif_str, ',', ' ' ); % replace commas with spaces
        n_q = size(dif_str,1)/(n_m*n_f); % total number of wind directions
        if round(n_q)~=n_q
            err = errordlg(['The number of rows (' num2str(size(dif_str,1)) ') in the *DIF_EST_MIN_BND section ' ...
                ' indicates that the number of wind directions per frame is inconsistent.'], err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        X_min_est_bnd = zeros(n_r,n_q*n_m,n_f);
        for j = 1:n_f
            for k = 1:n_m
                for ii = 1:n_q
                    ind = n_q*n_m*(j-1)+n_q*(k-1)+ii; % number of the current row
                    row_ii = strread(strtrim(dif_str_spc{ind,:}));
                    if length(row_k)~=n_r+1
                        err = errordlg(['Row ' num2str(ind) ' of the *DIF_EST_MIN_BND section (excluding header rows) contains '...
                            num2str(length(row_k)) ' entries (' num2str(n_r+1) ' expected).'], err_dlgname );
                        uiwait(err); DIF_struct.error = 1; return;
                    end
                    theta(ii,1) = row_ii(1);
                    X_min_est_bnd(:,n_q*(k-1)+ii,j) = row_ii(2:end);                    
                end
                if ~exist('theta_save','var')
                    DIF_struct.theta = theta;
                    theta_save = theta;
                elseif any(size(theta_save)~=size(theta)) || any( theta_save~=theta)
                    err = errordlg('Inconsistent wind direction list found in *DIF_EST_MIN_BND section.', err_dlgname );
                    uiwait(err); DIF_struct.error = 1; return;
                end
            end
        end
        DIF_struct.X_min_est_bnd = X_min_est_bnd;
        

% ================== L O A D   D I S T R I B U T I O N S ==================
    
    elseif strcmp( keyword, 'LOAD_DISTRIBUTION_MAX' )
        if index, continue, end;

        if ~exist('n_r','var')
            err = errordlg('The *RESPONSE_NAMES section must preceed the *LOAD_DISTRIBUTION_MAX section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if ~exist('n_f','var')
            err = errordlg('The *FRAME_LOCATIONS section must preceed the *LOAD_DISTRIBUTION_MAX section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if i == length(key_ind)
            dif_str = file_contents(key_ind(i)+1:file_lines);
        else
            dif_str = file_contents(key_ind(i)+1:key_ind(i+1)-1);
        end
        % Eliminate header rows:
        num_ind = intersect(find(~strncmp('Frame',dif_str,5)),find(~strncmp('Wind',dif_str,4)));
        dif_str = dif_str(num_ind);
        dif_str_spc = strrep( dif_str, ',', ' ' ); % replace commas with spaces
        n_q = size(dif_str,1)/(n_r*n_f); % total number of wind directions
        if round(n_q)~=n_q
            err = errordlg(['The number of rows (' num2str(size(dif_str,1)) ') in the *LOAD_DISTRIBUTION_MAX section ' ...
                ' indicates that the number of wind directions per frame is inconsistent.'], err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        % find number of attachment points from first row:
        row_1 = strread(strtrim(dif_str_spc{1,:}));
        n_a = length(row_1)-2; % number of attachment points
        load_max = zeros(n_a,n_r,n_q,n_f);
        for j = 1:n_f
            for k = 1:n_r
                for ii = 1:n_q
                    ind = n_q*n_r*(j-1)+n_q*(k-1)+ii; % number of the current row
                    row_ii = strread(strtrim(dif_str_spc{ind,:}));
                    if length(row_ii)~=n_a+2
                        err = errordlg(['The number of entries (' num2str(length(row_ii)) ') in row ' num2str(ind) ...
                            ' of the *LOAD_DISTRIBUTION_MAX section (excluding header rows) does not match the number '...
                            ' in the first row (' num2str(n_a+2) ').'], err_dlgname );
                        uiwait(err); DIF_struct.error = 1; return;
                    end
                    theta(ii,1) = row_ii(1);
                    load_max(:,k,ii,j) = row_ii(3:end);
                end
                if ~exist('theta_save','var')
                    DIF_struct.theta= theta;
                    theta_save = theta;
                elseif any(size(theta_save)~=size(theta)) || any( theta_save~=theta)
                    err = errordlg('Inconsistent wind direction list found in *LOAD_DISTRIBUTION_MAX section.', err_dlgname );
                    uiwait(err); DIF_struct.error = 1; return;
                end
            end
        end
        DIF_struct.load_max = load_max;
        
    elseif strcmp( keyword, 'LOAD_DISTRIBUTION_MIN' )
        if index, continue, end;

        if ~exist('n_r','var')
            err = errordlg('The *RESPONSE_NAMES section must preceed the *LOAD_DISTRIBUTION_MIN section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if ~exist('n_f','var')
            err = errordlg('The *FRAME_LOCATIONS section must preceed the *LOAD_DISTRIBUTION_MIN section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if i == length(key_ind)
            dif_str = file_contents(key_ind(i)+1:file_lines);
        else
            dif_str = file_contents(key_ind(i)+1:key_ind(i+1)-1);
        end
        % Eliminate header rows:
        num_ind = intersect(find(~strncmp('Frame',dif_str,5)),find(~strncmp('Wind',dif_str,4)));
        dif_str = dif_str(num_ind);
        dif_str_spc = strrep( dif_str, ',', ' ' ); % replace commas with spaces
        n_q = size(dif_str,1)/(n_r*n_f); % total number of wind directions
        if round(n_q)~=n_q
            err = errordlg(['The number of rows (' num2str(size(dif_str,1)) ') in the *LOAD_DISTRIBUTION_MIN section ' ...
                ' indicates that the number of wind directions per frame is inconsistent.'], err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        % find number of attachment points from first row:
        row_1 = strread(strtrim(dif_str_spc{1,:}));
        n_a = length(row_1)-2; % number of attachment points
        load_min = zeros(n_a,n_r,n_q,n_f);
        for j = 1:n_f
            for k = 1:n_r
                for ii = 1:n_q
                    ind = n_q*n_r*(j-1)+n_q*(k-1)+ii; % number of the current row
                    row_ii = strread(strtrim(dif_str_spc{ind,:}));
                    if length(row_ii)~=n_a+2
                        err = errordlg(['The number of entries (' num2str(length(row_ii)) ') in row ' num2str(ind) ...
                            ' of the *LOAD_DISTRIBUTION_MIN section (excluding header rows) does not match the number '...
                            ' in the first row (' num2str(n_a+2) ').'], err_dlgname );
                        uiwait(err); DIF_struct.error = 1; return;
                    end
                    theta(ii,1) = row_ii(1);
                    load_min(:,k,ii,j) = row_ii(3:end);
                end
                if ~exist('theta_save','var')
                    DIF_struct.theta= theta;
                    theta_save = theta;
                elseif any(size(theta_save)~=size(theta)) || any( theta_save~=theta)
                    err = errordlg('Inconsistent wind direction list found in *LOAD_DISTRIBUTION_MIN section.', err_dlgname );
                    uiwait(err); DIF_struct.error = 1; return;
                end
            end
        end
        DIF_struct.load_min = load_min;
        
    elseif strcmp( keyword, 'LOAD_DISTRIBUTION_MAX_ALL' )
        if index, continue, end;

        if ~exist('n_r','var')
            err = errordlg('The *RESPONSE_NAMES section must preceed the *LOAD_DISTRIBUTION_MAX_ALL section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if ~exist('n_f','var')
            err = errordlg('The *FRAME_LOCATIONS section must preceed the *LOAD_DISTRIBUTION_MAX_ALL section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if i == length(key_ind)
            dif_str = file_contents(key_ind(i)+1:file_lines);
        else
            dif_str = file_contents(key_ind(i)+1:key_ind(i+1)-1);
        end
        % Eliminate header rows:
        num_ind = intersect(find(~strncmp('Frame',dif_str,5)),find(~strncmp('Wind',dif_str,4)));
        dif_str = dif_str(num_ind);
        dif_str_spc = strrep( dif_str, ',', ' ' ); % replace commas with spaces
        n_qa = size(dif_str,1)/(n_r*n_f); % total number of wind directions
        if round(n_qa)~=n_qa
            err = errordlg(['The number of rows (' num2str(size(dif_str,1)) ') in the *LOAD_DISTRIBUTION_MAX_ALL section ' ...
                ' indicates that the number of wind directions per frame is inconsistent.'], err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        % find number of attachment points from first row:
        row_1 = strread(strtrim(dif_str_spc{1,:}));
        n_a = length(row_1)-2; % number of attachment points
        load_max_all = zeros(n_a,n_r,n_qa,n_f);
        for j = 1:n_f
            for k = 1:n_r
                for ii = 1:n_qa
                    ind = n_qa*n_r*(j-1)+n_qa*(k-1)+ii; % number of the current row
                    row_ii = strread(strtrim(dif_str_spc{ind,:}));
                    if length(row_ii)~=n_a+2
                        err = errordlg(['The number of entries (' num2str(length(row_ii)) ') in row ' num2str(ind) ...
                            ' of the *LOAD_DISTRIBUTION_MAX_ALL section (excluding header rows) does not match the number '...
                            ' in the first row (' num2str(n_a+2) ').'], err_dlgname );
                        uiwait(err); DIF_struct.error = 1; return;
                    end
                    theta_all(ii,1) = row_ii(1);
                    load_max_all(:,k,ii,j) = row_ii(3:end);
                end
                if ~exist('theta_all_save','var')
                    DIF_struct.theta_all= theta_all;
                    theta_all_save = theta_all;
                elseif any(size(theta_all_save)~=size(theta_all)) || any( theta_all_save~=theta_all)
                    err = errordlg('Inconsistent wind direction list found in *LOAD_DISTRIBUTION_MAX_ALL section.', err_dlgname );
                    uiwait(err); DIF_struct.error = 1; return;
                end
            end
        end
        DIF_struct.load_max_all = load_max_all;
        
    elseif strcmp( keyword, 'LOAD_DISTRIBUTION_MIN_ALL' )
        if index, continue, end;

        if ~exist('n_r','var')
            err = errordlg('The *RESPONSE_NAMES section must preceed the *LOAD_DISTRIBUTION_MIN_ALL section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if ~exist('n_f','var')
            err = errordlg('The *FRAME_LOCATIONS section must preceed the *LOAD_DISTRIBUTION_MIN_ALL section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if i == length(key_ind)
            dif_str = file_contents(key_ind(i)+1:file_lines);
        else
            dif_str = file_contents(key_ind(i)+1:key_ind(i+1)-1);
        end
        % Eliminate header rows:
        num_ind = intersect(find(~strncmp('Frame',dif_str,5)),find(~strncmp('Wind',dif_str,4)));
        dif_str = dif_str(num_ind);
        dif_str_spc = strrep( dif_str, ',', ' ' ); % replace commas with spaces
        n_qa = size(dif_str,1)/(n_r*n_f); % total number of wind directions
        if round(n_qa)~=n_qa
            err = errordlg(['The number of rows (' num2str(size(dif_str,1)) ') in the *LOAD_DISTRIBUTION_MIN_ALL section ' ...
                ' indicates that the number of wind directions per response quantity is inconsistent.'], err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        % find number of attachment points from first row:
        row_1 = strread(strtrim(dif_str_spc{1,:}));
        n_a = length(row_1)-2; % number of attachment points
        load_min_all = zeros(n_a,n_r,n_qa,n_f);
        for j = 1:n_f
            for k = 1:n_r
                for ii = 1:n_qa
                    ind = n_qa*n_r*(j-1)+n_qa*(k-1)+ii; % number of the current row
                    row_ii = strread(strtrim(dif_str_spc{ind,:}));
                    if length(row_ii)~=n_a+2
                        err = errordlg(['The number of entries (' num2str(length(row_ii)) ') in row ' num2str(ind) ...
                            ' of the *LOAD_DISTRIBUTION_MIN_ALL section (excluding header rows) does not match the number '...
                            ' in the first row (' num2str(n_a+2) ').'], err_dlgname );
                        uiwait(err); DIF_struct.error = 1; return;
                    end
                    theta_all(ii,1) = row_ii(1);
                    load_min_all(:,k,ii,j) = row_ii(3:end);
                end
                if ~exist('theta_all_save','var')
                    DIF_struct.theta_all= theta_all;
                    theta_all_save = theta_all;
                elseif any(size(theta_all_save)~=size(theta_all)) || any( theta_all_save~=theta_all)
                    err = errordlg('Inconsistent wind direction list found in *LOAD_DISTRIBUTION_MIN_ALL section.', err_dlgname );
                    uiwait(err); DIF_struct.error = 1; return;
                end
            end
        end
        DIF_struct.load_min_all = load_min_all;

    elseif strcmp( keyword, 'LOAD_DISTRIBUTION_MAX_BND' )
        if index, continue, end;

        if ~exist('n_m','var')
            err = errordlg('The *MODEL_DIMENSIONS section must preceed the *LOAD_DISTRIBUTION_MAX_BND section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if ~exist('n_r','var')
            err = errordlg('The *RESPONSE_NAMES section must preceed the *LOAD_DISTRIBUTION_MAX_BND section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if ~exist('n_f','var')
            err = errordlg('The *FRAME_LOCATIONS section must preceed the *LOAD_DISTRIBUTION_MAX_BND section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if i == length(key_ind)
            dif_str = file_contents(key_ind(i)+1:file_lines);
        else
            dif_str = file_contents(key_ind(i)+1:key_ind(i+1)-1);
        end
        % Eliminate header rows:
        num_ind = intersect(find(~strncmp('Frame',dif_str,5)),intersect(find(~strncmp('Model',dif_str,5)),find(~strncmp('Wind',dif_str,4))));
        dif_str = dif_str(num_ind);
        dif_str_spc = strrep( dif_str, ',', ' ' ); % replace commas with spaces
        n_q = size(dif_str,1)/(n_m*n_r*n_f); % total number of wind directions
        if round(n_q)~=n_q
            err = errordlg(['The number of rows (' num2str(size(dif_str,1)) ') in the *LOAD_DISTRIBUTION_MAX_BND section ' ...
                ' indicates that the number of wind directions per frame is inconsistent.'], err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        % find number of attachment points from first row:
        row_1 = strread(strtrim(dif_str_spc{1,:}));
        n_a = length(row_1)-2; % number of attachment points
        load_max_bnd = zeros(n_a,n_r,n_m*n_q,n_f);
        for j = 1:n_f
            for k = 1:n_r
                for ii = 1:n_m
                    for jj = 1:n_q
                        ind = n_q*n_m*n_r*(j-1)+n_q*n_m*(k-1)+n_q*(ii-1)+jj; % number of the current row
                        row_jj = strread(strtrim(dif_str_spc{ind,:}));
                        if length(row_jj)~=n_a+2
                            err = errordlg(['The number of entries (' num2str(length(row_jj)) ') in row ' num2str(ind) ...
                                ' of the *LOAD_DISTRIBUTION_MAX_BND section (excluding header rows) does not match the number '...
                                ' in the first row (' num2str(n_a+2) ').'], err_dlgname );
                            uiwait(err); DIF_struct.error = 1; return;
                        end
                        theta(jj,1) = row_jj(1);
                        load_max_bnd(:,k,n_q*(ii-1)+jj,j) = row_jj(3:end);
                        if ~exist('theta_save','var')
                            DIF_struct.theta= theta;
                            theta_save = theta;
                        elseif any(size(theta_save)~=size(theta)) || any( theta_save~=theta)
                            err = errordlg('Inconsistent wind direction list found in *LOAD_DISTRIBUTION_MAX_BND section.', err_dlgname );
                            uiwait(err); DIF_struct.error = 1; return;
                        end
                    end
                end
            end
        end
        DIF_struct.load_max_bnd = load_max_bnd;

    elseif strcmp( keyword, 'LOAD_DISTRIBUTION_MIN_BND' )
        if index, continue, end;

        if ~exist('n_m','var')
            err = errordlg('The *MODEL_DIMENSIONS section must preceed the *LOAD_DISTRIBUTION_MIN_BND section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if ~exist('n_r','var')
            err = errordlg('The *RESPONSE_NAMES section must preceed the *LOAD_DISTRIBUTION_MIN_BND section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if ~exist('n_f','var')
            err = errordlg('The *FRAME_LOCATIONS section must preceed the *LOAD_DISTRIBUTION_MIN_BND section', err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        if i == length(key_ind)
            dif_str = file_contents(key_ind(i)+1:file_lines);
        else
            dif_str = file_contents(key_ind(i)+1:key_ind(i+1)-1);
        end
        % Eliminate header rows:
        num_ind = intersect(find(~strncmp('Frame',dif_str,5)),intersect(find(~strncmp('Model',dif_str,5)),find(~strncmp('Wind',dif_str,4))));
        dif_str = dif_str(num_ind);
        dif_str_spc = strrep( dif_str, ',', ' ' ); % replace commas with spaces
        n_q = size(dif_str,1)/(n_m*n_r*n_f); % total number of wind directions
        if round(n_q)~=n_q
            err = errordlg(['The number of rows (' num2str(size(dif_str,1)) ') in the *LOAD_DISTRIBUTION_MIN_BND section ' ...
                ' indicates that the number of wind directions per frame is inconsistent.'], err_dlgname );
            uiwait(err); DIF_struct.error = 1; return;
        end
        % find number of attachment points from first row:
        row_1 = strread(strtrim(dif_str_spc{1,:}));
        n_a = length(row_1)-2; % number of attachment points
        load_min_bnd = zeros(n_a,n_r,n_m*n_q,n_f);
        for j = 1:n_f
            for k = 1:n_r
                for ii = 1:n_m
                    for jj = 1:n_q
                        ind = n_q*n_m*n_r*(j-1)+n_q*n_m*(k-1)+n_q*(ii-1)+jj; % number of the current row
                        row_jj = strread(strtrim(dif_str_spc{ind,:}));
                        if length(row_jj)~=n_a+2
                            err = errordlg(['The number of entries (' num2str(length(row_jj)) ') in row ' num2str(ind) ...
                                ' of the *LOAD_DISTRIBUTION_MIN_BND section (excluding header rows) does not match the number '...
                                ' in the first row (' num2str(n_a+2) ').'], err_dlgname );
                            uiwait(err); DIF_struct.error = 1; return;
                        end
                        theta(jj,1) = row_jj(1);
                        load_min_bnd(:,k,n_q*(ii-1)+jj,j) = row_jj(3:end);
                        if ~exist('theta_save','var')
                            DIF_struct.theta= theta;
                            theta_save = theta;
                        elseif any(size(theta_save)~=size(theta)) || any( theta_save~=theta)
                            err = errordlg('Inconsistent wind direction list found in *LOAD_DISTRIBUTION_MIN_BND section.', err_dlgname );
                            uiwait(err); DIF_struct.error = 1; return;
                        end
                    end
                end
            end
        end
        DIF_struct.load_min_bnd = load_min_bnd;
        
    else
        err = errordlg(['The keyword ' keyword ' is unrecognized.'], err_dlgname);
        uiwait(err); DIF_struct.error = 1; return;
    end
    
end

% required keyword entries:
required_keywords = {'UNITS','MODEL_TERRAIN','FRAME_LOCATIONS','RESPONSE_NAMES','ATTACHMENT_LOCATIONS','BUILDING_DIMENSIONS','MODEL_DIMENSIONS'};

% check that all required keywords are included:
missing_keywords = setdiff( required_keywords, keyword_list );
missing_key_char = [];
if ~isempty(missing_keywords)
    for i = 1:length(missing_keywords)
        missing_key_char = [missing_key_char missing_keywords{i}];
        if i ~= length(missing_keywords)
            missing_key_char = [missing_key_char ', '];
        end
    end
    err = errordlg({'The following required keywords are missing from the input file:',['     ' missing_key_char ]}, err_dlgname);
    uiwait(err); DIF_struct.error = 1; return;
end

status = fclose(fid);
if status==-1
    err = errordlg(['Unable to close file: '  DIF_full_filename ], err_dlgname );
    uiwait(err); DIF_struct.error = 1; return;
end 