MATLAB: Subscripted assignment between dissimilar structures and Error: The variable info in a parfor cannot be classified. I need educating!

copying structuresdicomparfor

I am having difficulty trying to speed up code by using parfor and pre-defining variable dimensions. The original code looks something like this(abbreviated):
for i = 1 : num_files_in_folder
Flag = true;
foldername = files_in_folder(i).name;
try
info = dicominfo(foldername);
catch ME
Flag = false;
warning("Problem: dicominfo error.");
DB2(i,1) = "Bad DICOM File";
DB2(i,2) = foldername;
% rethrow(ME);
end %%try
...
When trying to speed it up with parfor I get the "cannot be classified" and other similar error messages.
Then I tried moving some of these temporary variables outside and making them an structured array. Note: I have ram to spare, even with a 8G ram disk. So big variable are not an issue yet.

Best Answer

Here is a marginally cleaned up version that does not have the parfor errors, and which manages directories a little better. Untested.
You should double-check the line
ExamsInfo(i,:) = [{infx(i)},{thisfile}];
I do not understand why you would not use
ExamsInfo(i,:) = {infx(i), thisfile};
%clear
% Script to extract a specified Dicom series from the PET/CT data set
WarmFuzzy = 0;
data_folder = uigetdir;
files_in_folder = dir( fullfile(data_folder, '*.dcm'));
% Discard the current and root file descriptors
files_in_folder = files_in_folder( [files_in_folder.bytes] > 0);
filenames_in_folder = fullfile(data_folder, {files_in_folder.name});
num_files_in_folder = numel(filenamess_in_folder);
DB2 = strings([num_files_in_folder,2]);
dlu = dicomlookup('0008', '103E');
% I searched for a series descriptor called �docs�; You can change it to what you need.
% desired_series_descriptor = 'docs';
ExamsInfo = cell(num_files_in_folder,2);
Flag(1:num_files_in_folder) = true;
Flag1(1:num_files_in_folder) = true;
n = num_files_in_folder;
infx(1:10) = dicominfo(filenames_in_folder{1});
for i = 1:num_files_in_folder
infx(i) = dicominfo(filenames_in_folder{i});
str1(i) = infx(i).(dlu);
end
% foldername(1:num_files_in_folder) = ' ';
parfor i = 1 : num_files_in_folder
newDB2 = strings(1,2);
thisfile = filenames_in_folder{i};
try
infx(i) = dicominfo(thisfile);
catch ME
Flag(i) = false;
warning("Problem: dicominfo error.");
newDB2(1) = "Bad DICOM File";
newDB2(2) = thisfile;
% rethrow(ME);
end %%try

if (Flag(i))
Flag1(i) = true;
try
str1(i) = infx(i).(dlu);
catch ME
warning("No Series Discription");
newDB2(1) = "Nyet";
newDB2(2) = thisfile;
Flag1(i) = false;
end %%try
if(Flag1(i))
newDB2(1) = str1(i);
newDB2(2) = thisfile;
end %% if(Flag1)
% You can convert this section to a series of if statements to match multiple descriptors
% and get the file names for the specific files that you are interested in, and then read the data in
% using DICOM read
ExamsInfo(i,:) = [{infx(i)},{thisfile}];
end % if Flag
DB2(i,:) = newDB2;
% WarmFuzzy = WarmFuzzy +1;
% xt = sprintf('%d Interation\n', WarmFuzzy);
% disp(xt);
end %%parfor i = 1 : num_files_in_folder
disp("Done reading in the directory information");
% parsing the information - creating the database
Dicom_type = {'[GA-N_CTAC_60s] Rest Rb' '[NG_NAC_60s] Stress Rb' 'Cardiac-ldCT' '[NG_NAC_60s] Rest Rb' '[NG_CTAC_60s] Rest Rb' '[NG_CTAC_60s] Stress Rb' '[GA-N_CTAC_60s] Stress Rb'};
% N = size(DB2);
prime = 1033; % 61;
LTA = strings(prime,361);
ptr_lga(prime,361) = int16(0);
% test debug number double due to second run?
for i = 1:prime
ptr_lga(1,1) = 0;
end
nitem(1:prime) = int16(1);
hflag = true;
for i= 1:num_files_in_folder
Logical_Flag = (DB2(i,1) ~= "Bad DICOM File") && (DB2(i,1) ~= "Nyet") ...
&& convertCharsToStrings((ExamsInfo{i, 1}.AccessionNumber) ...
== convertCharsToStrings(ExamsInfo{1, 1}.AccessionNumber));
if (Logical_Flag)
if (hflag)
arr = convertStringsToChars(DB2(i,1));
hash = mod(string2hash(arr), prime)+1;
end %%if (hflag)
hflag = true;
switch LTA(hash,1)
case ""
LTA(hash,1)= DB2(i,1);
nitem(hash) = nitem(hash) + 1;
LTA(hash,nitem(hash)) = DB2(i,2);
% test if this is an image we need

lg2 = false;
lg = ( DB2(i,1) == Dicom_type);
for j = 1:7
lg2 = lg2 | lg(j);
end
if lg2
ptr_lga(hash,nitem(hash)) = int16(ExamsInfo{i,1}.InstanceNumber);
ptr_lga(hash,1) = ptr_lga(hash,1) +1;
end
case DB2(i,1)
nitem(hash) = nitem(hash) + 1;
LTA(hash,nitem(hash)) = DB2(i,2);
% test if this is an image we need
lg2 = false;
lg = ( DB2(i,1) == Dicom_type);
for j = 1:7
lg2 = lg2 | lg(j);
end
if lg2
ptr_lga(hash,nitem(hash)) = int16(ExamsInfo{i,1}.InstanceNumber);
ptr_lga(hash,1) = ptr_lga(hash,1) +1;
end
otherwise
if ~(LTA(hash,1) == DB2(i,1))
hflag = false;
i = i-1;
hash = mod((hash+7),prime);
else
error('Unexpected event - Halting execution');
end % if ~(LTA(hash,1) == DB2(i,1))
end % switch LTA
end % if num_files_in_folder
end
Dicom_name = {"Rest_gated_AC" "StressNG_NAC" "Cardiac_CT" "Rest_NG_NAC" "Rest_NG_AC" "Stress_NG_AC" "Stress_gated_AC"};
exit;
hashtag(1:7) = int16(0);
Rand_Num_Name = string( int16(rand(1,1) * 50000));
for i=1:7
hashtag(i) = mod(string2hash(char(Dicom_type(i))), prime)+1;
while (Dicom_type(i) ~= LTA(hashtag(i)))
hashtag(i) = mod((hashtag(i)+7),prime);
end % while
slicex = dicomread(LTA(hashtag(i),2));
num_slices = ptr_lga(hashtag(i),1);
[x,y] = size(slicex);
Dimage = int16(zeros(num_slices,x,y));
for k = 1:num_slices
indx = ptr_lga(hashtag(i),(k+1));
Dimage(indx, 1:x,1:y) = dicomread(LTA(hashtag(i),(k+1)));
end
% Now write the file out
save(strcat(string(Dicom_name(i)),"_", Rand_Num_Name, ".mat"), 'Dimage')
end
IDt.PatientName = ExamsInfo{1, 1}.PatientName;
IDt.AccessionNumber = ExamsInfo{1, 1}.AccessionNumber;
IDt.StudyDate = ExamsInfo{1, 1}.StudyDate;
save(char(strcat("IDt", Rand_Num_Name, ".mat")), 'IDt')