Extracting multiple sets of scientific notation data

Hello all,
I am trying to extract some data for plotting and I've been struggling to get the data structered how I want it. I have a results file attached which is where I'm getting my data. I want to pull out the first section of data which represents node numbers and xyz coordinates and store this data as a Nx4 array (N happens to be 12881 for this file). I also want to pull out the very last temperature data set (at the very end, the NDTEMP block just above the RFL block) and store that as a 61x2 array.
The main problem I've been having so far is that the coordinates and temperature data is in exponential/scientific notation, and sscanf() doesn't seem to want to read them. I've tried formating sscanf() with %11.5E, %11.5e with no luck. The dimensions of the arrays come out correct if I format sscanf() with %d and %f but I want to keep the scientific notation if I can.
Any tips or advice would be greatly appreciated!
Thank you for your time,
Best,
John

 Réponse acceptée

Stephen23
Stephen23 le 2 Juil 2019
Modifié(e) : Stephen23 le 3 Juil 2019
Try this sscanf format string:
'%d%f'
However your file-importing code is rather complex. Here is a simpler method using textscan, which reads the two sections that you are apparently interested in:
myp = '.'; % path to where the file is saved.
fnm = fullfile(myp,'Quarter_Cone_10deg_CASE_No_FR.txt');
[fid,msg] = fopen(fnm,'rt');
assert(fid>=3,msg)
% 1. Read first matrix:
C = textscan(fid,'-1%f%f%f%f','HeaderLines',12,'CollectOutput',true);
% 2. Locate last NDTEMP line:
idx = NaN;
while ~feof(fid) % read every remaining line in the file...
str = strtrim(fgets(fid));
if strncmp(str,'-4 NDTEMP',10)
idx = ftell(fid); % location of this line within the file.
end
end
fseek(fid,idx,'bof'); % go back to the last NDTEMP line.
% 3. Read second matrix:
D = textscan(fid,'-1%f%f','HeaderLines',1,'CollectOutput',true);
fclose(fid);
And checking:
>> size(C{1})
ans =
12881 4
>> C{1}
ans =
1 0 0 0
2 0.026303 0 0.062219
3 0.039788 0.051913 0.051913
4 0.026303 0.062219 0
5 0.0127 2.2789e-15 0
6 0.03574 0 0.055006
7 0.047963 0.045664 0.045664
.... lots of lines here
12883 1.4438 0.24538 0.20958
12884 1.4438 0.24442 0.20875
12885 1.4438 0.24345 0.20793
12886 1.4438 0.24248 0.2071
12887 1.4438 0.24152 0.20628
>> size(D{1})
ans =
61 2
>> D{1}
ans =
1 2116.5
2 1975.5
10 1702.6
16 1445.4
22 1288.9
... lots of lines here
634 1162.1
635 1156.7
636 1151.8
637 1147.5
638 1144.4

7 commentaires

John Moran IV
John Moran IV le 3 Juil 2019
Modifié(e) : John Moran IV le 3 Juil 2019
Thank you for the input and providing a simple way to solve my problem!
That's a much cleaner way to do what I was aiming to do! I thought about using textscan but I wasn't sure how to grab the temperature section at the end, and honestly I'm not sure how you did it either, although it certainly looks like you grabbed the correct temp values! Could you please elaborate on how you're telling textscan to only pull the temperature data you asked for?
Stephen23
Stephen23 le 3 Juil 2019
Modifié(e) : Stephen23 le 3 Juil 2019
"Could you please elaborate on how you're telling textscan to only pull the temperature data you asked for?"
There are basically three parts to the code (which are also marked in the code):
  1. Read the first matrix.
  2. Locate the last NDTEMP line.
  3. Read the second matrix.
In more detail:
  1. The function textscan keeps parsing the file until it can no longer match the format string, at which point it returns the data (i.e. the first matrix).
  2. Then the next part of the code reads every remaining line from the file, and checks if the line starts with '-4 NDTEMP'. If the start of the line matches, then the file location is stored in variable idx. Thus when the while loop has finished, idx contains the file location of the last NDTEMP line, and fseek takes us back to that point in the file.
  3. Then textscan imports the second matrix, starting from that point in the file.
Ah that makes a lot of sense. Thank you so much for the clarification and speedy responses!
Why does the textscan result in a 1x1 cell? The size command results in the correct dimensions but when I try to extract the vectors of the matrix, MATLAB says I've exceeded my size if I ask for x=C{2}, y=C{3}, z={4}, etc. In the past when I've used textscan the cell dimensions are the dimensions of the arrays, such as 7 column vectors showing up as "cell 1x7". Any ideas?
Nevermind, I got it. x=C{1}(:,2), y=C{1}(:,3), z={1}(:,4) does work.
Stephen23
Stephen23 le 3 Juil 2019
Modifié(e) : Stephen23 le 3 Juil 2019
"Why does the textscan result in a 1x1 cell?"
That is because I set 'CollectOutput' to true. This option concatenates compatible arrays of the same class together. Because the format string contains only numeric format specifiers, the output of textscan will be a scalar cell array containing one numeric matrix with all of the data in it. You can access the data using indexing into that numeric matrix, just like you would any other numeric matrix:
M = C{1}; % this is the advantage: all of the data in one numeric matrix!
M(:,1)
M(:,2)
M(:,3)
M(:,4)
or directly from the cell array:
C{1}(:,1)
C{1}(:,2)
C{1}(:,3)
C{1}(:,4)
If you prefer to get a 1x4 cell array, then simply set the 'CollectOutput' option to false, or remove the option entirely (the default is false), then you will be able to use
C{1}
C{2}
C{3}
C{4}
You can pick whichever is more convenient for your data processing, it makes no difference to how my answer works.
Awesome, thank you!

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Large Files and Big Data dans Centre d'aide et File Exchange

Produits

Version

R2019a

Community Treasure Hunt

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

Start Hunting!

Translated by