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!