MATLAB Answers

0

Can I create a code to avoid updating the struct every time I use a different struct?

Asked by Matthew Wilson on 9 Nov 2018 at 6:46
Latest activity Edited by Stephen Cobeldick about 15 hours ago
Hi all, and thanks in advance. I have 1x1 struct files which have 65 fields, some fields contain a single number, and others can be opened up and has about 80 cells worth of data. These are files produced by a piece of research equipment, and the name relates to the time the readings were taken, and are unable to be changed.
Is there a way I can easily extract data from specific fields? In every copy of the file the field names remain the same (i,e, Pressure, Compliance etc). Some of these will be single figures, others will be the ones with cells worth of data.
I have hobbled together something which works, but trust me...its bad, I have no idea what I am doing.
While it kind of works, I have to change the struct name in the code every time I open a new file. Is there a way I can avoid having to update the struct code every time? (180+ times a day).
Thanks in advance.
Matt

  22 Comments

Oh OK, not sure why the first was different, it had been opened in Matlab previously but this one has not, so this one here is probably the right type then. Apologies for any confusion and trouble. Are these similar to .mat files to work with, just need to modify some of the code? Or quite different.
Would it be best to start a new question now that I have more of an idea of what I need/what I have and what to ask? This has all become quite messy and confusing for me :(
"Are these similar to .mat files to work with, just need to modify some of the code? Or quite different."
The .m file you posted earlier is totally unrelated to everything that you have uploaded previously on this thread. Answering a question is very difficult when the information keeps changing.
"Would it be best to start a new question now that I have more of an idea "
You could, but based on your most recent .m file the solution will not be particularly simple or neat. Basically the tool that you are using is very badly written because its author has forced meta-data (the date) into the structure's name. Forcing meta-data into a variable name makes accessing that variable slow, complex, and buggy. Read this to know why:
The best solution would be to fix the tool that you are using. Otherwise you will have to run that file, then magically try to access the variable that it creates:
save('temp.mat','-regexp','File_.*_\d{4}_.*')
T = load('temp.mat');
C = struct2cell(T);
A = C{1};
A.PRESSURE
A.FREQ
A.ABSORBANCE
... etc
I recommend getting the tool fixed. If you upload it here or give us a link we might be able to help with that.

Sign in to comment.

3 Answers

Answer by Walter Roberson
on 9 Nov 2018 at 7:20

datastruct = load(filename) ;
FN = fieldnames(datastruct) ;
selected_data = SelectData(datastruct.(FN{1});
function selected = SelectData(S)
fns = {'Pressure', 'Compliance', 'etc'} ;
for K = 1 :length(fns)
fn = fns{K};
selected.(fn) = S.(fn);
end

  0 Comments

Sign in to comment.


Answer by Stephen Cobeldick on 10 Nov 2018 at 7:40
Edited by Stephen Cobeldick about 16 hours ago

If each mat file contains only one variable (but its name changes and you don't know the name in advance) then you could just use struct2cell to get the data of that variable. If there are multiple variables in the .mat file then this method can be modified, but what modifications are most suitable depends on how the variables are named, which you have told us nothing about.
Here is a simple method that will load your .mat file/s (which is actually how your data is saved), without knowing the name of the structure inside the .mat file/s.
One Single File
T = load('WB3DT_2018_10_12__16_10_31.mat');
C = struct2cell(T);
A = C{1};
A.PRESSURE
A.FREQ
A.ABSORBANCE
... etc.
Multiple Files
S = dir('*.mat');
for k = 1:numel(S)
T = load(S(k).name);
C = struct2cell(T);
S(k).data = C{1};
end
And then you can access the imported structure simply like this, e.g. here is the data for the first file:
S(1).data.PRESSURE
S(1).data.FREQ
S(1).data.ABSORBANCE
... etc.

  1 Comment

@ Matthew Wilson: now that you have actually uploaded a sample data file, it was easy to test my code. Here are some of the values that it imported:
>> S(1).data.RESONANCE_FREQUENCY
ans = 483
>> S(1).data.PEAK_PRESSURE
ans = -5
>> S(1).data.PRESSURE(:)
ans =
178
178
157
148
136
123
106
90
74
59
45
31
18
5
-5
-16
-27
... lots of rows here
-330
-333
-335
-338
-340
-344
-349
-355
-361
-367
-372
-375
-379
-384
-389
-395
Note how the code in my answer does not use the structure name anywhere (which is exactly what your question said that you wanted to acheive).

Sign in to comment.


Answer by Matthew Wilson on 10 Nov 2018 at 9:02

It seems this is all unfortunately beyond my skill. I'll just continue to do extract the data manually. Thank you all for your help.
Matt

  9 Comments

"Hoping this is what you mean :)"
Yes, that is the data file.
Note that my answer shows you how to import and access the data in your .mat files without using the structure name, which is exactly what you asked for in your question: "I have to change the struct name in the code every time I open a new file. Is there a way I can avoid having to update the struct code every time?"
Try the code in my answer. When I tested it, it does what you requested. If you have any questions, please make a comment to my answer.
Thank you so much, all of you! I feel like I'm so close to something which will be great! Is it possible to call on multiple fields, say for instance:
ABS_PEAK, ABS_AMBIENT, EQUIVALENT_EAR_VOLUME, RESONANCE_FREQUENCY
and have these come up in one spreadsheet page (like when you double click on one of the box things in the work space) so that way I can copy rows or columns into their respective fields in a spreadsheet?
Again can't thank you guys enough, this will help us with our research more than I can even imagine.
Matt
If you use the code I posted, adjusting for the fields you want, then afterwards you can use struct2table and then writetable

Sign in to comment.