MATLAB: How to read the data from a header file into single variables

text file

I would appreciate some help at reading the data contained in the attached header file into single variables that then I will use to access a file containing the true numbers. Thank you in advace. Best regards, Maura

Best Answer

Should get ya' started...
>> c=textread('ma.txt','%s','delimiter','\n','whitespace','');
>> ix=~cellfun(@isempty,(strfind(c,'Number'))) | ~cellfun(@isempty,(strfind(c,'Energy of')));
>> c=c(ix)
c =
'Number of Original Histories: 100'
'Number of Original Histories that Reached Phase Space: 100'
'Number of Scored Particles: 107'
'Number of e-: 4'
'Number of gamma: 1'
'Number of neutron: 2'
'Number of proton: 100'
'Minimum Kinetic Energy of e-: 0.0454162 MeV'
'Minimum Kinetic Energy of gamma: 0.0175963 MeV'
'Minimum Kinetic Energy of neutron: 5.64233 MeV'
'Minimum Kinetic Energy of proton: 73.3641 MeV'
'Maximum Kinetic Energy of e-: 0.223425 MeV'
'Maximum Kinetic Energy of gamma: 0.0175963 MeV'
'Maximum Kinetic Energy of neutron: 49.4473 MeV'
'Maximum Kinetic Energy of proton: 159.678 MeV'
[Elided previous partial solution and background discussion for brevity. dpb]
OK, here's a working script in its entirety. While I don't normally recommend it, I used the assignin option here...if run from the command window, the variables will show up in that workspace; if called from a function in that function's workspace of course.
c=c(~cellfun(@isempty,(strfind(c,'Number'))) | ...
~cellfun(@isempty,(strfind(c,'Energy of')))); % save only wanted rows
ic=cell2mat(strfind(c,':'))+1; % find the colons plus one char past
particles={'hist';'e-';'gamma';'neutron';'proton'}; % keyword for particles to process
vnames={'histories';'electron';'gamma';'neutron';'proton'}; % output variables for data
cellfun(@(x) str2num(char(x{:})),regexp(c(idx),'(?:(:\s{0,}))(\S)*','tokens'))
Test run...
>> maura % I named the script maura.m, rename as see fit
>> [histories electron gamma neutron proton] % the variables in vnames
ans =
100.0000 4.0000 1.0000 2.0000 100.0000
100.0000 0.0454 0.0176 5.6423 73.3641
107.0000 0.2234 0.0176 49.4473 159.6780
OK, with Bruno's help with the regexp pattern, the above internal loop can be eliminated. It's still a little convoluted owing to regexp return a cell of cells instead of simply a cell array of strings so the dereferencing is more complex than would like, but with it the final loop becomes --
for i=1:length(vnames) % get each of the variables values
if i==1
idx=[1:3].'; % histories are first three records
assignin('caller', ...
char(vnames(i)), ...
cellfun(@(x) str2num(char(x{:})),regexp(c(idx),'(?:(:\s{0,}))(\S)*','tokens')))
PS: With respect to John's criticsm on not completing the solution in its entirety on first go but providing the bread crumbs of the technique with an example of converting one line to numeric value thereby hoping to inspire completion on own, I'd not have expected you to come up with this enhancement initially. :)
As an aside, this particular parsing intrigued me as it is a fairly common type of problem -- my goal was to figure out how to write an anonymous function that would eliminate the remaining loop by judicious cellfun and/or arrayfun and friends, but I've so far not succeeded.