looping throwing errors, how can I avoid them?

Hi folks,
I have a couple of questions about the following code. I get an error when doing the k-loop which states "Reference to non-existent field 'x'".
I am trying to populate a table for each "testPiece" with all the measurements, and then write them to an excel file. The problem is that some measurements might be missing from the 1290 files this loops through. Is there a way around this?
I essentially want to, for each testpiece, go through all the xml files and populate a table with each measurement. If the measurement is missing in a particular file, I want it to write "NA" or "-" instead. I'm not sure where I'm going wrong, only that I am!
Any help would be greatly appreciated.
startingFolder = pwd;
fprintf('Select the directory containing the Images and Auto analysis \n \n');
RawImages = uigetdir(startingFolder); %Creating the variable from the user selection
addpath(RawImages); %Ensuring matlab will follow the path
files = dir([RawImages '\AutoAnalysis\*.xml']);
numOfFiles = numel(files); %Counting number of files in the folder for looping purposes
Settings = xml_read(fullfile([RawImages '\settings.xml'])); %reading XML file
NumOfSamples = Settings.numberOfTestPieces;
headings = {'Time','Temperature','Height','Area','Circumference', 'Shape Factor', 'Tip Radius', 'Base Width', 'Max Width', 'Height:Base Width Ratio', 'Height:Max Width Ratio', 'Bse Centre X', 'Base Centre Y', 'LHS Difference', 'RHS Difference'};
objectRangeEnd = strcat('O', num2str(numOfFiles));
objectRange = strcat('A2:', objectRangeEnd);
numMaxIndices = 13;
structIndices = {'height', 'area', 'circumference', 'shapeFactor', 'tipRadius', 'baseWidth', 'maxWidth', 'hBwRatio', 'hMwRatio', 'baseCentreX', 'baseCentreY', 'lhsDiff', 'rhsDiff'};
for i = 1:NumOfSamples %Getting the manually named test pieces from the settings
TestPieceName = Settings.testPiece.TestPieceStorage.name; %Creating a name variable to use when making file and folder names
Sample = ['Test Piece ' num2str(i) '-' TestPieceName];
TestPiece = zeros(numOfFiles,3); %Making an array to store the variables
testPieceIdentifier = strcat('testPiece', num2str(i));
for j = 1:numOfFiles %Grabbing the time and file data from the save file name
flds = {'date','bytes','isdir','datenum'}; %Reading time and temp from file
A = rmfield(files,flds); %Remove the file information that is unnecessary
codes = struct2cell(A); %Reduces the structure to only the fields required
codes = codes'; %Converts the labels in A to the format required
new = strsplit(char(codes(j)),'.'); % To remove the file type
new2 = strsplit(char(new(1)),'-'); % Splits the experimental conditions
time = str2double(new2(2));
alpha = new2(3);
alpha = char(alpha);
alpha(1) = [];
temp = str2double(alpha);
TestPiece(j,1) = time;
TestPiece(j,2) = temp;
file = fullfile([ RawImages '\AutoAnalysis\' files(j).name]); % Creating the k-th file name
DataSet = xml_read(file); % read XML files
%Indexing Height, Area, and Circumference etc.
for k = 1 : numMaxIndices
if isfield(DataSet.(testPieceIdentifier).testPieceMeasurements, (structIndices{k})) == 1
initialMeasurement = TestPiece(1, (k+2));
if initialMeasurement > 0
TestPiece(j, (k+2)) = DataSet.(testPieceIdentifier).testPieceMeasurements.(structIndices{k})/initialMeasurement;
else
TestPiece(j, (k+2)) = DataSet.(testPieceIdentifier).testPieceMeasurements.(structIndices{k});
end
else
TestPiece(j, (k+2)) == 'N/A';
end
end
end
sampleDirectory = fullfile(RawImages); %file creation
filename = fullfile(sampleDirectory, ['Results.xls']); %Creating the filename to put the excel file in the appropriate folder
writecell(headings, filename, 'Sheet', Sample, 'Range', 'A1:O1');
writematrix(TestPiece, filename, 'Sheet', Sample, 'Range', objectRange);
end

4 件のコメント

Stephen23
Stephen23 2021 年 1 月 28 日
編集済み: Stephen23 2021 年 1 月 28 日
Start by simplifying your code, it performs a few superfluous operations. For example, you do not need to delete all of the other fields from the structure array returned by DIR, nor do you need to convert it to a cell array, you can replace all of this:
flds = {'date','bytes','isdir','datenum'}; %Reading time and temp from file
A = rmfield(files,flds); %Remove the file information that is unnecessary
codes = struct2cell(A); %Reduces the structure to only the fields required
codes = codes'; %Converts the labels in A to the format required
new = strsplit(char(codes(j)),'.'); % To remove the file type
with this much simpler code:
[~,new] = fileparts(files(j).name);
You call fullfile four times, but only one of those instances makes any sense. In two of the instances fullfile only has one input argument because you mixed it up with string concatention, but these are two separate approaches: you can either concatenate strings (not recommended) or you can use fullfile (recommended), but there is no point in doing both like this:
fullfile([RawImages '\settings.xml']) % only one input to FULLFILE!
should be:
fullfile(RawImages,'settings.xml') % two inputs to FULLFILE.
and the same with the other instance where you do this.
You might find it easier to allocate the sub-tree to a temporary variable:
dat = DataSet.(testPieceIdentifier).testPieceMeasurements;
fnm = structIndices{k};
if isfield(dat,fnm)
.. = dat.(fnm)/initialMeasurement;
end
It is not clear to me how you would get the error message "Reference to non-existent field 'x'", as there is no field referred to by that name, and the dynamic fieldnames all use much longer, distinctive names.
Please shos us the complete error message, which means all of the red text.
Teshan Rezel
Teshan Rezel 2021 年 1 月 28 日
I've made the adjustments you've suggested but get the following error when running this segment of the code:
[~,new] = fileparts(files(j).name);
new2 = strsplit(char(new(1)),'-'); % Splits the experimental conditions
time = str2double(new2(2));
alpha = new2(3);
alpha = char(alpha);
alpha(1) = [];
temp = str2double(alpha);
TestPiece(j,1) = time;
TestPiece(j,2) = temp;
error:
Index exceeds the number of array elements (1).
which seems to be at the "time" variable. Any ideas what causes this please?
Stephen23
Stephen23 2021 年 1 月 28 日
It appears that you were relying on strsplit to return multiple substrings, which implies that the comment "To remove the file type" is not quite the complete description of what that line does. Do the filenames contain period characters in them?
Teshan Rezel
Teshan Rezel 2021 年 1 月 28 日
hi @Stephen Cobeldick, The filenames themselves do not contain periods in them.

サインインしてコメントする。

 採用された回答

Jan
Jan 2021 年 1 月 28 日
編集済み: Jan 2021 年 1 月 28 日

0 投票

[~,new] = fileparts(files(j).name);
% Now "new" is a CHAR vector.
new2 = strsplit(char(new(1)),'-'); % Splits the experimental conditions
% This splits the first character of the CHAR vector new.
% Then "new2" has 1 CHAR only created by splitting a single CHAR
time = str2double(new2(2));
% new2 has 1 element only...
Better:
[~,new] = fileparts(files(j).name);
new2 = strsplit(new, '-'); % Splits the experimental conditions
time = str2double(new{2});

3 件のコメント

Teshan Rezel
Teshan Rezel 2021 年 1 月 28 日
Hi @Jan, I get the following error when doing this: "Brace indexing is not supported for variables of this type." I'm not sure how to proceed as when I try "()", I get the error "Index exceeds the number of array elements (1)."
Jan
Jan 2021 年 6 月 1 日
Which line is failing with which inputs?
Teshan Rezel
Teshan Rezel 2021 年 6 月 2 日
Hi @Jan, I think I solved this issue earlier but can't remember how...apologies!

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

ヘルプ センター および File ExchangeMatrix Indexing についてさらに検索

製品

リリース

R2019b

質問済み:

2021 年 1 月 28 日

コメント済み:

2021 年 6 月 2 日

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by