Don't you just hate when you have an [cci]MxN[/cci] struct array in Matlab, where each element contains some [cci]PxK[/cci] data field, and you just really want to have all that data in a single [cci]PxKxMxN[/cci] array? OK, maybe this doesn't happen to you very frequently, but it has happened to me. In fact, it has happened so often that I decided to write a (very simple) general solution to this problem.

Let me motivate the problem with an example. I was dealing with Granger causality spectra that are stored in FieldTrip structures as follows:

[cc lang="matlab"]>> allconns(1)

ans =

struct with fields:

label: {7×1 cell}

dimord: 'chan_chan_freq'

grangerspctrm: [7×7×101 double]

freq: [1×101 double]

cfg: [1×1 struct][/cc]

and I had one of these structures per participant, per condition of my experiment, and per time-direction (forward or reverse; details don't really matter here). The structures were all tucked into one structure variable [cci]allconns[/cci] such that

[cc lang="matlab"]>> size(allconns)

ans =

36 7 2

[/cc]

To get out the data into one big 6-dimensional array, I first concatenated along the fourth dimension:

[cc lang="matlab"]catdat = cat(4, allconns.grangerspctrm);[/cc]

which unfortunately flattens all those [cci]36x7x2[/cci] dimensions such that

[cc lang="matlab"]>> size(catdat)

ans =

7 7 101 504

[/cc]

However, it's easy to just get those back by one final [cci]reshape[/cci]:

[cc lang="matlab"]catdat = reshape(catdat, [7 7 101 36 7 2]);[/cc]

The above works because Matlab stores data in column-major order.

It's very straightforward to embed this into a simple function (also available on GitHub):

[cc lang="matlab"]function x = structcat(y, param)

% STRUCTCAT takes a structure y of arbitrary dimensionality Mx...xN, each

% element of which contains a field named of dimensionality

% Px...xK, and returns the data in those fields concatenated into a

% Px...XKxMx...N array.

%

% Author: Eelke Spaak, 2018.

siz1 = size(y);

siz2 = size(y(1).(param));

x = cat(numel(siz2)+1, y.(param));

x = reshape(x, [siz2 siz1]);

end[/cc]

I hope this is useful to someone who's encountered the same!