Effacer les filtres
Effacer les filtres

Undefined command/function 'reshape'.

94 vues (au cours des 30 derniers jours)
Jensen Lam
Jensen Lam le 10 Avr 2024 à 11:58
Modifié(e) : DGM le 11 Avr 2024 à 9:33
I have a script I am trying to write to call a function (Not written by me) to extract files from a folder. The function basically takes data from a folder and then places them into a struct and reformats it. I am not able to really visualize what the finished result would look like since it is getting stuck on an error.
clc
clear all
close all
files = dir('/Users/admin/Documents/MATLAB/pivdat/*.v3d');
for k = 1:length(files)
[h,d] = svecread(files(k).name ,1,8)
end
Then I have parts of the actual function here:
function [varargout] = svecread(varargin)
% Inputs:
msg = nargchk(1,3,nargin); if ~isempty(msg), error(msg), end;
% Defaults:
if nargin < 3
varargin{3} = 8; % default columns value (13/08/01)
if nargin < 2
varargin{2} = 1; % default number of header lins
end
end
% Assign variables
name = varargin{1};
comments = varargin{2};
columns = varargin{3};
disp(name);
% Extension issue
if isempty(findstr(lower(name),'.v3d')), name = strcat(name,'.v3D'); end;
% Read the file
fid=fopen(name,'r');
if fid<0
error('File not found');
end
[dch,count]=fread(fid,inf,'uchar');
fclose(fid);
% Reformat the data
chdat=[dch(:)',setstr(13)];
ind10=find(chdat==setstr(10));
comp=computer;
if strcmp(comp(1:3),'PCW')|strcmp(comp(1:3),'VAX')|strcmp(comp(1:3),'ALP'),
% replace cr-lf with cr only for PC's, VAXen and Alphas
chdat(ind10)=setstr(' '*ones(1,length(ind10)));
else
%replace line-feeds with carriage-returns for Unix boxes
chdat(ind10)=setstr(13*ones(length(ind10),1));
end
% Now replace commas with spaces
indcom=find(chdat==',');
chdat(indcom)=setstr(' '*ones(1,length(indcom)));
%find carriage-returns
ind13=find(chdat==setstr(13));
% Truncate array to just have data
if comments==0,
char1=1;
else
char1=ind13(comments)+1;
end
hdr = lower(chdat(1:char1-1));
chdata=chdat(char1:count);
% Convert it
data=sscanf(chdata,'%g',[columns inf])';
% Find and remove bad points > 9.99e9
badind = find(data>9e9);
if ~isempty(badind), data(badind) = 0; warning(sprintf('Bad %d points',length(badind))); end;
% Parse the header
i = findstr(hdr,'i=');
j = findstr(hdr,'j=');
k = findstr(hdr,'k='); % 3rd dimension index, 19/08, Alex.
[i,junk] = strtok(hdr(i+2:end));
[j,junk] = strtok(hdr(j+2:end));
[k,junk] = strtok(hdr(k+2:end)); % 19/08/01
i = eval(i); j = eval(j); k= eval(k); % 19/08/01
disp(i);
disp(j);
disp(k);
disp(columns);
data = reshape(data,[i,j,columns]);
data = permute(data,[2 1 3]);
When I run this I receive the result:
Undefined command/function 'reshape'.
Error in svecread (line 126)
data = reshape(data,[i,j,columns]);
Error in pivdatareadertest (line 7)
[h,d] = svecread(files(k).name ,1,8)
I did not alter the file except for making it display i, j, and columns, to ensure they are actually outputting values. Having read some other forum questions and also checking the reshape function page for matlab, I tried removing the brackets all together, keeping the brackets and removing the commas, also tried only putting brackets around i,j. I am quite stuck on what might be causing this. I assume Reshape is a built in function and so I am not missing any additional libraries? I know the data was loaded properly as I made it display that too and it did just fine prior to reshape.
Any help would be very much appreciated.
  15 commentaires
DGM
DGM le 11 Avr 2024 à 5:48
At this point, I'm not yet worried about updating the string extraction part. I'm just trying to figure out how numel(data) is supposed to be factored. We have ostensible sizes given by 73, 54, 1, and 8, but only 1 and 8 are factors of numel(data). Might want to make sure that data is the correct length. I'm also curious as to why j = 54 and there are 53 named variables. Maybe there's a column for a timestamp or something?
DGM
DGM le 11 Avr 2024 à 6:22
Modifié(e) : DGM le 11 Avr 2024 à 6:40
Obviously, I'm not familiar with this file format or what to expect of variations in header formatting, but I note that the header is on one line (the decoder expects this), and this particular file has 3943 non-header lines (one of which is empty), each of which appears to contain 57 fields. How that relates to the numbers in the header, I have no idea.
EDIT: Oh. 73x54 = 3942, and there are only 8 of the 57 fields which appear to be used. Not sure what information should be used to find the number of fields.

Connectez-vous pour commenter.

Réponse acceptée

DGM
DGM le 11 Avr 2024 à 7:20
Modifié(e) : DGM le 11 Avr 2024 à 7:26
Again, I have no idea what variations might exist between files. I also don't really know how far you want to go with changing things. This seems to work, but relies on a lot of things which are relatively new (compared to 2001-2008)
name = 'FSTwentyHz000001.T000.D000.P000.H000.PIV.v3d';
headerlines = 1;
columns = 8;
% this is only needed for the forum
unzip([name '.zip']);
% append an extension if the user neglected to include it
% this seems like it would cause as many problems as it might fix.
if isempty(findstr(lower(name),'.v3d'))
name = strcat(name,'.v3D');
end
% Read the header
fid = fopen(name,'r');
if fid<0
error('File not found');
end
hdr = fgetl(fid);
fclose(fid);
% Parse the header
% i'm terrible at using regex safely,
% so take this with a grain of salt
hdr = lower(hdr);
i = regexp(hdr,'i=(\d+)','tokens');
i = str2double(i{1}{1});
j = regexp(hdr,'j=(\d+)','tokens');
j = str2double(j{1}{1});
k = regexp(hdr,'k=(\d+)','tokens');
k = str2double(k{1}{1});
% read everything using a convenience tool
data = readmatrix(name,'filetype','text', ...
'expectednumvariables',columns, ...
'numheaderlines',headerlines);
% then reshape
% i don't know which way this is supposed to be oriented
data = reshape(data,i,j,[]);
data = permute(data,[2 1 3]);
% it appears to be sensible
imagesc(data(:,:,4))
In this case, I'm just being lazy and using readmatrix() to avoid all the reformatting and ambiguity regarding the number of fields per line. It can still be done, but you'll have to come up with a way to discern how many fields/columns are actually in the file (57) so that sscanf() reads everything right. After that, you can just truncate to 8 if desired.
Note also that we read k. I don't know when it would be used.
  2 commentaires
Jensen Lam
Jensen Lam le 11 Avr 2024 à 8:06
Hey, I really appreciate you helping me with this.
To give a bit of background the data is regarding the velocity of particles in an image taken during flow analysis for aerodynamics. Considering this is freestream data, aka all the particles should just be moving in one direction without much change in axis, your plot makes sense.
As for the "discern how many fields/columsn there are in the file", do you mean that there are currently 57 stated columns, but it is possible that MATLAB mistakenly recognized some as columns whereas they actually aren't/ failed to recognize some columns whereas there should be? And that by actually individually distinguishing each of the headers I will be able to go forth and just truncate to 8 and try it with the old code again?
To be quite honest with you my matlab experience has been mostly computational and not really on the file handling and manipulation of data and structs so I am not exactly sure what the difference between your method and their's would be.
DGM
DGM le 11 Avr 2024 à 9:30
Modifié(e) : DGM le 11 Avr 2024 à 9:33
In the original code, you have a variable called columns, which ends up becoming the number of pages in the output. In the call to sscanf(), this is also used to scan the data as if it had 8 columns.
The problem is that each line in the example file actually has 57 columns (or fields or whatever you want to call em (pun unintended)).
-71.031464, 77.468857, 0.000000, 0.000000, 0.000000, 0.000000, -3, 0.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, 0.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000, -9999999.000000
As a consequence, sscanf() will end up truncating its output to a multiple of 8, when it shouldn't be. The original code doesn't seem to have a way to detect the actual number of columns in the file. You'd need to manually set columns=57, or you'd have to programmatically determine it (e.g. based on the number of delimiters per line).
It appeared to me that there were really only 8 of these columns which have plausible data, so that's what I assumed was intended by the variable called "columns". I assumed we should just read that many columns, and the rest should be ignored. I don't know if that's appropriate. Scrolling deeper into the file, it does look like some of the other columns do contain valid data. Some of them just have some strange extreme values at their border. You might want to look at those and see what you think. It might make more sense to just ignore the presumption of 8 columns, and just change it to
% read everything using a convenience tool
data = readmatrix(name,'filetype','text', ...
'numheaderlines',headerlines);
As far as why the old code was written so very differently, I really am not familiar with revision history older than 2006, since that's when most of the available information stops, but I imagine a big part of the reason why they did it that way was because the available tools were different 20 years ago. I don't even know if regexp() was available in 2001.
Readmatrix() wasn't introduced until R2019a. It can take care of splitting data into lines and fields based on characters which are either determined by the user or automatically.
FWIW, I'm not really great at handling files, but sometimes one strikes me as a puzzle.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Matrix Indexing dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by