How to concatenate a set of rows created in a for loop?

I'm trying to create a 2D array by concatenating a set of 1D column arrays created in a for loop. The code I have so far.
fileList = {};
warning('off', 'all');
% Ask user for directory input and gather subfolders
[filePath] = uigetdir('','Select Directory of Folders to be Loaded');
fileList = dir(filePath);
fileList = fileList(arrayfun(@(x) x.name(1), fileList) ~= '.');
% Create array of files
dat = cell(size(fileList, 1), 6);
for j = 1:size(fileList, 1)
% Open array of file and gather info
fID = fileList(j).name;
fID = strcat(filePath, '\',fID);
info = dicominfo(fID);
pID = info.PatientID;
serNo = info.SeriesNumber;
sliceLoc = info.SliceLocation;
repet = info.RepetitionTime;
echo = info.EchoTime;
% Construct array of files with info
dat(j,:) = {fID, pID, serNo, sliceLoc, repet, echo};
end
% Sort array by echo time
dat = sortrows(dat, 6);
% Read files according to echo time
for j = 1:length(dat)
[img] = dicomread(char(dat(j,1)));
images(:,:,j) = img;
end
% plot T2 by matching each pixel, use T(1, 1, :) and iterate for all
% pixels.
vals = cell(size(images, 3), 2);
T2ind = cell(size(images, 1), 1);
T2 = cell(size(images, 1), size(images, 2));
% Loop through all rows
for y = 1:size(images,1)
% Loop through all colunms
for x = 1:size(images,2)
% If the average value is greater than 100 for the given row and colunm number then loop through all 'pages'
if ((sum(images(y,x,:))/size(images, 3)) > 100)
for z = 1:size(images, 3)
% Read echo time and pixel values and constuct array
echo = dat(z, 6);
imgVal = images(y,x,z);
vals(z,:) = {echo, imgVal};
end
% Fit an exponential curve to pixel values and calculate T2
f = fit(cellfun(@cell2mat, vals(:,1)), cell2mat(vals(:,2)), 'exp1');
coeff = coeffvalues(f);
a= coeff(1);
b = coeff(2);
S1 = f(10);
S2 = S1/exp(1);
T2ind{x} = ((log(S2/a))/b);
end
end
T2(:,y) = (T2ind(:));
end
% T2(T2 < 0) = 0;
% T2(isnan(T2)) = 0;
The error I get is...
Subscripted assignment dimension mismatch.
Error in T2_mapping (line 61)
T2(:,y) = cat(2, T2ind{:});
Any help? Thanks!

6 Comments

You may need to be explicit in the use of either vertcat or horzcat. It is hard to see at a glance though from your code and I can't run it to check as it isn't self-contained.
Also the result of cat will not be a cell array yet you are trying to assign it to a cell array as far as I can see. Don't use cell arrays for regular numeric data unless you really have to (e.g. if you will have empty [] values included).
I assume you want the
T2(:,y) = cat(2, T2ind{:});
line inside the outer loop though rather than outside, otherwise using y seems slightly odd even though it will still be defined at that point as being size(images,1).
You're right about T2 line, it should be in the outer loop!
I've added my full code, still struggling to get it to work. I will have empty cells but I plan to set any empty cells to 0 so could do that before the loop if it would make the coding easier....
Just reading through your code, spotted a few things:
fileList = fileList(arrayfun(@(x) x.name(1), fileList) ~= '.');
this would probably more efficient:
fileList = fileList(strncmp({fileList.name}, '.', 1));
More importantly:
for j = 1:length(dat)
This is not going to work the way you expect when you have less than 6 files in your file list because then length is 6 (the number of columns). As a rule never use length. Use size with an explicit dimension for matrices, and numel for vectors.
Finally,
[img, map] = dicomread(...)
If you don't use the map, don't ask for it. You'll save on memory and time.
Thanks for your hints! I'll take them on board!
Any more help anyone?
So I now have a 256 by 256 array of cells! When I try to convert the cells I get a concatenation error....
cell2mat(T2)
Error using cat
Dimensions of matrices being concatenated are not consistent.
Error in cell2mat (line 86)
m = cat(2,m{:});
Any ideas on that?

Sign in to comment.

Answers (1)

If I read your code right (comments needed!) T2Ind is a cell array of scalar or empties. Therefore horzcat(T2Ind{:}) is a vector of numbers. You're trying to assign that to a m*1 cell array (with m = size(images, 2)), so of course it's not going to work. I'm not sure what you're trying to do, so can't really suggest how to correct it.
Further to my comment above, it's possible you don't need all your loops. Again, I've not wrapped my head around the whole of your code, but
sum(images(y,x,:))/size(images, 3)
could be just calculated outside the loop as:
imagesmean = mean(images, 3);
Furthermore, what the heck is that supposed to do:
cell2mat(cellfun(@cell2mat, vals(:,1), 'UniformOutput', false))

5 Comments

Hi,
Sorry for confusion, I've added some comments to the question. Hopefully they will clear a few things up. I'm a beginner at Matlab and so my code is messy...
To clarify, I am comparing pixel values across images. So I want to create a 256 by 256 array of numbers. The innermost loop compares the pixel values across the images for a given row and column. The outer two loops are to move along the rows and columns so that all pixels have been compared.
So the innermost loop gives me a single scalar, the second loop gives me a set of scalars (256 by 1) and I then want to outermost loop to give me an array of scalars (256 by 256)... I think....
Regarding the imagesmean comment, I want to assess whether the loop should be run on a pixel set by pixel set basis. Pixel set referring to a set of pixels with the same row and column throughout the images.
As far as I am aware....
cell2mat(cellfun(@cell2mat, vals(:,1), 'UniformOutput', false))
prepares the values for the fitting function to convert from cells..... I was given that code by someone and it seemed to work so I stuck with it. Very amateur, I know!!
I still don't see why you are using a cell array if it is just full of numbers. Cell arrays are very inefficient and should only be used when you have to - i.e. you have different size elements in each cell or different data types or strings, etc.
"I'm a beginner at Matlab and so my code is messy": actually you are making it more complicated than it needs to be. Forget about cell arrays for now and learn about vectorization and how you can use this on your numeric data array.
@Shaun,
Yes, I understood the purpose of your loop and I'm fairly certain they're not necessary or can be reduced to just one loop. The obscure bit is all this weird cell manipulation with echo and as mentioned what you're trying to do with your cell array assignment on the line with the error.
Thanks for your comments everyone, I think I have it working now. I re-wrote the code after actually reading up on the vectorization Stephen mentioned.... I can see why cell arrays aren't what I should have been using now! My code is much neater and nicer now and is giving me what I wanted. Thanks!

Sign in to comment.

Asked:

on 20 Feb 2015

Commented:

on 25 Feb 2015

Community Treasure Hunt

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

Start Hunting!