Verfasst am: 02.03.2012, 09:17
Titel: Problem beim einlesen von Dateien.
Hallo zusammen ich habe von einem Arbeitskollegen zwei Dateien zum einlesen von .pts-Dateien bekommen allerdings funktioniert der Code bei mir nicht richtig es treten immer folgende fehler auf.
??? Undefined function or method 'txt2mat_01' for input arguments of type 'char'.
Error in ==> read_PTS at 18
[EM,ffn,nh,SR,hl,fpos,cell2delete]= txt2mat_01(EingabeDatei, 1, 'RowRange', [1,1e6], 'FilePos', fpos);
Error in ==> plotProfile at 14
ProfilDaten= read_PTS(char(EingabeDatei));
ich verstehe den aufbau allgemein auch noch nicht! Könnte mir vielleicht jemand was dazu erklären.
% Zeilen mit Anzahl Punkten löschen ifisnan(cell2delete(1,1)) == 0 && cell2delete(1,1) ~= 999 [zeilen, spalten]= size(cell2delete);
vektor= (0:1:zeilen)';
for i=1:zeilen
EM(cell2delete(i,1)-vektor(i,1),:)= [];
end end end
Dein Kollege hat also irgendwo diese Funktion definiert. Und da, laut deinem Code, auf diese zugegriffen wird (Matlab diese aber nicht findet) bekommst du eine Fehlermeldung.
% find out matlab version as a decimal, up to the second dot:
v = ver('matlab');
vs= v.Version;
vsDotPos = [strfind(vs,'.'), Inf, Inf];
vn= str2double(vs(1:min(numel(vs),vsDotPos(2)-1)));
% try some automatic data format analysis if needed (by function anatxt) if ~all([is_argin_num_header, is_argin_num_colon]) %, is_argin_conv_str]); % commented out as so far anatxt's conv_str is only '%f' % call subfunction anatxt: [ffn, ana_num_header, ana_num_colon, ana_conv_str, ana_sr_input_ca,...
ana_rm, num_ali, ana_hl, ferrmsg] = anatxt(ffn,filepos,sr_input_ca,replace_expr,replace_regex,kl_input_ca,num_header);
% accept required results from anatxt: if ~is_argin_num_header
num_header = ana_num_header;
end if ~is_argin_num_colon
num_colon = ana_num_colon;
end
%if ~is_argin_conv_str
% conv_str = ana_conv_str;
%end if ~is_argin_readmode
readmode = ana_rm;
end % add new replacement strings from anatxt:
is_new_sr = ~ismember(ana_sr_input_ca, sr_input_ca);
num_sr = num_sr + sum(is_new_sr);
sr_input_ca = [sr_input_ca,ana_sr_input_ca(is_new_sr)];
% display information: if infolvl >= 1 disp(repmat('*',1,length(ffn)+2));
disp(['* ' ffn]);
ifnumel(ferrmsg)==0
sr_display_str = '';
for idx = 1:num_sr;
sr_display_str = [sr_display_str ' »' sr_input_ca{idx} '«']; %#ok<AGROW>
end disp(['* read mode: ' readmode]);
disp(['* ' num2str(num_ali) ' data lines analysed' ]);
disp(['* ' num2str(num_header) ' header line(s)']);
disp(['* ' num2str(num_colon) ' data column(s)']);
disp(['* ' num2str(num_sr) ' string replacement(s)' sr_display_str]);
else disp(['* freaderror: ' ferrmsg]);
end disp(repmat('*',1,length(ffn)+2));
end% if
% return if anatxt did not detect valid data if ana_num_colon==0
A = [];
hl = '';
fpos = filepos;
return end end
%% Detect line termination character
% www.editpadpro.com/tricklinebreak.html : % Line Breaks in Windows, UNIX & Macintosh Text Files % A problem that often bites people working with different platforms, such % as a PC running Windows and a web server running Linux, is the different % character codes used to terminate lines in text files. % % Windows, and DOS before it, uses a pair of CR and LF characters to % terminate lines. UNIX (Including Linux and FreeBSD) uses an LF character % only. The Apple Macintosh, finally, uses a CR character only. In other % words: a complete mess.
if infolvl >= 1
hw = waitbar(0,'detect line termination character ...');
set(hw,'Name',[mfilename ' - ' ffn_short]);
end
lbfull = detect_line_break_characters(ffn);
% DETECT_LINE_BREAK_CHARACTERS find out type of line termination of a file
%
% lb = detect_line_break_characters(ffn)
%
% with % ffn ascii file name % lb line break character(s) as uint8, i.e. % [13 10] (cr+lf) for standard DOS / Windows files % [10] (lf) for Unix files % [13] (cr) for Mac files
%
% The DOS style values are returned as defaults if no such line breaks are % found.
%% Read in ASCII file. Case 1: Portions only, as RowRange is given % RowRange should be given if file is too huge to be read at once by fread. % In this case consecutive freads are used. % A line begins with its first character and ends with its last termination % character.
if infolvl >= 1 waitbar(0.0,hw,'reading file ...');
end
logfid = fopen(ffn);
if is_argin_filepos
fseek(logfid,filepos,'bof');
end
if is_argin_rowrange
do_read = true; % loop condition
num_lb_prev = 0;
read_len = idx_rng;
f8 = [];
fposhdr = 0;
while do_read
[f8p,lenf8p] = fread(logfid,read_len,'*uint8'); % current text section
ldcp_curr = find(f8p==lbuint); % line break positions in current text section
num_lb_curr = numel(ldcp_curr);
% to add all header lines to f8 if num_lb_prev < num_header % not all header lines were read at the end of the prev. loop => add more text to f8 if num_header>num_lb_curr+num_lb_prev % header even ends beyond current section
hdx = lenf8p; % end index is length of section => add the whole section to f8 else% header ends within current section
num_lines_to_add = num_header-num_lb_prev; % how many lines to add
hdx = ldcp_curr(num_lines_to_add); % corresponding end index end
f8 = [f8; f8p(1:hdx)]; %#ok<AGROW>
fpos = ftell(logfid)-lenf8p+hdx; % position of latest used character
fposhdr = fpos-filepos; % index of end of header in f8 end
% to add lines of interest to f8 if(num_lb_prev < num_header+rowrange(2)) && (num_lb_prev+num_lb_curr >= num_header+rowrange(1)-1)
if num_header+rowrange(1)-1<=num_lb_prev % lines of interest started before current section
sdx = 1; % start index is beginning of section => the part of the section to add to f8 includes the start of the section else% lines of interest start within current section
num_lines_to_omit = num_header+rowrange(1)-1-num_lb_prev; % how many lines not to add
sdx = ldcp_curr(num_lines_to_omit)+1; % start right after the omitted lines end
if num_header+rowrange(2)>num_lb_curr+num_lb_prev % lines of interest even end beyond current section
edx = lenf8p; % end index is length of section => the part of the section to add to f8 includes the end of the section else% lines of interest end within current section
num_lines_to_add = num_header+rowrange(2)-num_lb_prev; % how many lines to add
edx = ldcp_curr(num_lines_to_add); % corresponding end index end
f8 = [f8; f8p(sdx:edx)]; %#ok<AGROW>
fpos = ftell(logfid)-lenf8p+edx; % position of latest used character end
% quit loop if all rows of interest are read or if end of file is reached if num_lb_prev >= num_header+rowrange(2) || lenf8p<read_len
do_read = false;
end
num_lb_prev = num_lb_prev + num_lb_curr; % absolute number of dectected line breaks end
hl = char(f8(1:fposhdr)');
end
%% Read in ASCII file. Case 2: Full file
if ~is_argin_rowrange
[f8,fpos] = fread(logfid,Inf,'*uint8'); % das Einlesen
% simply read header with fgetl
hl = '';
if num_header > 0 fseek(logfid, 0, 'bof');
for i = 1:num_header
hl = [hl, fgetl(logfid), char(lbfull)]; %#ok<AGROW>
end end end
%% Clean up trailing whitespaces % replace all trailing whitespaces by spaces and a linebreak % (quick&dirty)
if infolvl >= 1 waitbar(0.0,hw,'cleaning up whitespaces ...');
end
cnt_trail_white = 0;
is_ws_at_end = true;
while is_ws_at_end % step through the endmost characters if f8(end-cnt_trail_white) <= spuint % is it a whitespace?
cnt_trail_white = cnt_trail_white + 1;
else
f8(end-cnt_trail_white+1:end) = spuint; % fill with spaces if cnt_trail_white >= num_lbfull
f8(end-num_lbfull+(1:num_lbfull)) = lbfull; %#ok<AGROW> % replace endmost space(s) by a line break else
f8(end+(1:num_lbfull)) = lbfull; %#ok<AGROW> % append a final line break end
is_ws_at_end = false;
end end% while
%% Find linebreak indices and bad line positions % In what follows the text will repeatedly be processed in consecutive % sections of length <idx_rng> to help avoid memory problems.
lenf8 = numel(f8);
idx_lo = 1; % init., start index of a section processed in a loop
lf_idc = 0; % init., will contain the line break indices
kl_idc = []; % init., will contain the indices of bad line markers strings while idx_lo < lenf8
if infolvl >= 1 waitbar(0.25*(idx_lo/lenf8),hw,'finding line breaks ...');
end
idx_hi = min(idx_lo - 1 + idx_rng,lenf8); % end index of current section
% Check for possible bad line markers and find line breaks if num_kl>0
f8_akt = f8(idx_lo:idx_hi); % current working section for idx = 1:num_kl % find positions of all markers
%kl_idx_akt = findstr(kl_input_ca{idx},char(f8_akt'))';
kl_idx_akt = strfind(char(f8_akt'),kl_input_ca{idx})'; % todo
kl_tdc = [kl_idc; kl_idx_akt + idx_lo-1];
kl_idc = kl_tdc;
end% for
islb = f8_akt==lbuint;
else
islb = f8(idx_lo:idx_hi)==lbuint;
end
% collect line break indices
lf_tdc = [lf_idc; find(islb)+idx_lo-1]; % use lf_tdc temporarily to ...
lf_idc = lf_tdc; % avoid memory fragmentation (?)
idx_lo = idx_hi + 1; % start index for the following loop
end% while
num_lf = numel(lf_idc);
clear lf_tdc islb f8_akt kl_tdc
%% Delete rows marked as bad
% Have we found bad line markers? if ~isempty(kl_idc) if infolvl >= 1 waitbar(0.25,hw,'deleting rows ...');
end
% find indices of line breaks bordering a marker [L,R] = neighbours(kl_idc, lf_idc);
% delete the bad rows
f8 = cutvec(f8,L+1,R,false);
% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ % update line break indices (same as above - are there better ways?)
lenf8 = numel(f8);
idx_lo = 1; % init., start index of a section processed in a loop
lf_idc = 0; % init., will contain the line break indices while idx_lo < lenf8
idx_hi = min(idx_lo - 1 + idx_rng,lenf8); % end index of current section
f8_akt = f8(idx_lo:idx_hi); % current working section
islb = f8_akt==lbuint;
lf_tdc = [lf_idc; find(islb)+idx_lo-1]; % use lf_tdc temporarily to ...
lf_idc = lf_tdc; % avoid memory fragmentation (?)
idx_lo = idx_hi + 1; % start index for the following loop end% while
num_lf = numel(lf_idc);
clear lf_tdc islb f8_akt
% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ end% if clear L R kl_idc
%% Replace (regular) expressions and characters
f8=char(f8); % quicker with strrep, required by sscanf
if num_rr > 0
has_length_changed = true;
else
has_length_changed = false; % flag for changes of length of f8 by replacements end
ldx_lo = num_header+1; % start index while ldx_lo < num_lf
ldx_hi = min(ldx_lo - 1 + ldx_rng,num_lf); % end index
f8_akt = f8( lf_idc(ldx_lo)+1:lf_idc(ldx_hi))'; % current working section
if num_er > 0 || num_rr > 0
len_f8_akt = (lf_idc(ldx_hi))-(lf_idc(ldx_lo)); % length of current section before replacements
% Replacements, e.g. {'odd','one','1'} replaces 'odd' and 'one' by '1'
% Regular Expression Replacements: ============================ for vdx = 1:num_rr % step throug replacements arguments
srarg = replace_regex{vdx}; % pick a single argument...
for sdx = 1:(numel(srarg)-1)
f8_akt = regexprep(f8_akt, srarg{sdx}, srarg{end}); % ... and perform replacements end% for
% Expression Replacements: ==================================== for vdx = 1:num_er % step throug replacements arguments
srarg = replace_expr{vdx}; % pick a single argument...
for sdx = 1:(numel(srarg)-1)
f8_akt = strrep(f8_akt, srarg{sdx}, srarg{end}); % ... and perform replacements if ~has_length_changed && (len_f8_akt~=numel(f8_akt))
has_length_changed = true; % detect a change of length of f8 end end% for
% update f8-sections by f8_akt ================================
exten = numel(f8_akt) - len_f8_akt; % extension by replacements if exten == 0
f8( lf_idc(ldx_lo)+1:lf_idc(ldx_hi)) = f8_akt';
else
f8 = [f8(1:lf_idc(ldx_lo)); f8_akt'; f8(lf_idc(ldx_hi)+1:end)];
% update linebreak indices of the following sections % (but we don't know the lb indices of the current one anymore):
lf_idc(ldx_hi:end) = lf_idc(ldx_hi:end) + exten;
end
% Character Replacements: ========================================= for vdx = 1:num_sr % step through replacement arguments
srarg = sr_input_ca{vdx}; % pick a single argument for sdx = 1:(numel(srarg)-1)
rep_idx = lf_idc(ldx_lo)+strfind(f8_akt,srarg(sdx));
f8(rep_idx) = srarg(end); % perform replacement end% for end
ldx_lo = ldx_hi; % start index for the following loop if infolvl >= 1 waitbar(0.25+0.23*(idx_lo/lenf8),hw) end end% while
if has_length_changed
if infolvl >= 1 waitbar(0.48,hw,'finding new line breaks ...') end
f8=uint8(f8);
lenf8 = numel(f8);
idx_lo = 1;
lf_idc = 0;
while idx_lo < lenf8
idx_hi = min(idx_lo - 1 + idx_rng,lenf8);
f8_akt = f8(idx_lo:idx_hi);
islb = f8_akt==lbuint;
lf_tdc = [lf_idc; find(islb)+idx_lo-1];
lf_idc = lf_tdc;
idx_lo = idx_hi + 1;
end% while
num_lf = numel(lf_idc);
clear lf_tdc islb f8_akt
f8=char(f8);
end
%% Try converting large sections (ReadMode 'Matrix') % sscanf will be applied to consecutive working sections consisting of % <ldx_rng> rows. The number of numeric values must then be a multiple of % the number of columns. Otherwise, or if sscanf produces an error, inform % the user and eventually proceed to the (slower) line-by-line conversion.
errmsg = ''; % Init. error message variable ifstrcmpi(readmode,'auto') || strcmpi(readmode,'matrix') if infolvl >= 1 waitbar(0.5,hw,'converting large bites ...');
end
f8=char(f8);
if vn>=7
lf_idc = uint32(lf_idc); % to save memory... end try % initialize result matrix A depending on matlab version: if vn>=7
A = zeros(num_lf-num_header-1,num_colon,numerictype);
else % create a single row of A to be repeated if numerictype is % other than double:
Ar= zeros(1,num_colon);
switchlower(numerictype) case 'double'
A = zeros(num_lf-num_header-1,num_colon);
case 'single'
A = repmat(single(Ar),num_lf-num_header-1,1);
case 'int8'
A = repmat(int8(Ar),num_lf-num_header-1,1);
case 'int16'
A = repmat(int16(Ar),num_lf-num_header-1,1);
case 'int32'
A = repmat(int32(Ar),num_lf-num_header-1,1);
case 'int64'
A = repmat(int64(Ar),num_lf-num_header-1,1);
case 'uint8'
A = repmat(uint8(Ar),num_lf-num_header-1,1);
case 'uint16'
A = repmat(uint16(Ar),num_lf-num_header-1,1);
case 'uint32'
A = repmat(uint32(Ar),num_lf-num_header-1,1);
case 'uint64'
A = repmat(uint64(Ar),num_lf-num_header-1,1);
end clear Ar
end
ldx_lo = num_header+1; % lower row index
val_cntr = 0; % number of values read
char_cntr = 0; % number of characters read
diag_cntr = 0; % loop counter while ldx_lo < num_lf
ldx_hi = min(ldx_lo - 1 + ldx_rng,num_lf); % lower row index of current working section [Atmp,count,errmsg,nextindex] = sscanf(f8( lf_idc(ldx_lo)+1:lf_idc(ldx_hi)),conv_str); % THE conversion
char_cntr = char_cntr + nextindex - 1;
diag_cntr = diag_cntr + 1;
num_lines_loop = ldx_hi-ldx_lo;
val_cntr = val_cntr + count;
% error 1) current section was not completely read in if ~isempty(errmsg) if nextindex <= lf_idc(ldx_hi)-(lf_idc(ldx_lo)+1)+1 % find line break index of the abortion line
err_line_idx = min(find(lf_idc-(char_cntr+lf_idc(num_header+1))>0)); %#ok<MXFND>
% give user the location of the error cause if infolvl >= 2 disp(['Sscanf error after reading ' num2str(val_cntr) ' numeric values. Critical row (no. ' num2str(err_line_idx-1) '): ']) disp(f8(lf_idc(err_line_idx-1)+1:lf_idc(err_line_idx)-1)') end% if end% if break;
end
% error 2) number of numeric values is not a multiple of the number of columns % try to provide some hints: ifnumel(Atmp) ~= num_colon * num_lines_loop
dlf = diff(lf_idc(ldx_lo:ldx_hi)); % length of each row [dlf_sort,dlf_sort_idc] = sort(dlf);
% We don't know the lines containing the wrong number of % values. As a guess, just show the positions of the % longest and the shortest rows (simply count characters). if infolvl >= 2 disp('Warning: number of values is not a multiple of the number of rows.') disp(['Longest rows: ' num2str( num_header-1+ldx_lo+dlf_sort_idc(end:-1:end-4)', ' %i' ) '(' num2str( dlf_sort(end:-1:end-4)', ' %i' ) ' characters)']) disp(['Shortest rows: ' num2str( num_header-1+ldx_lo+dlf_sort_idc(1:5)' , ' %i' ) '(' num2str( dlf_sort(1:5)' , ' %i' ) ' characters)']) end% if error('Number of values is not a multiple of number of rows.') end% if
% put the values to the right dimensions and add them to A
Atmp = reshape(Atmp,num_colon,num_lines_loop)';
A(ldx_lo-num_header:ldx_hi-num_header-1,:) = Atmp;
ldx_lo = ldx_hi; % start index for the following loop if infolvl >= 1 waitbar(0.5+0.5*(ldx_lo/num_lf),hw) end end% while
catch %#ok<CTCH> % catch further errors (old catch style) if ~exist('errmsg','var') || isempty(errmsg)
errmsg = lasterr; %#ok<LERR> (old catch style) end end% try end
% Quit on error if 'matrix'-mode was enforced: ifstrcmpi(readmode,'matrix') && ~isempty(errmsg) if infolvl >= 1 close(hw) end error(errmsg);
end
% initialize result matrix A depending on matlab version:
width_A = max(abs(num_colon),1);
if vn>=7
A = NaN*zeros(num_lf-num_header-1,width_A,numerictype);
else % create a single row of A to be repeated if numerictype is other % than double:
Ar= NaN*zeros(1,width_A);
switchlower(numerictype) case 'double'
A = NaN*zeros(num_lf-num_header-1,width_A);
case 'single'
A = repmat(single(Ar),num_lf-num_header-1,1);
case 'int8'
A = repmat(int8(Ar),num_lf-num_header-1,1);
case 'int16'
A = repmat(int16(Ar),num_lf-num_header-1,1);
case 'int32'
A = repmat(int32(Ar),num_lf-num_header-1,1);
case 'int64'
A = repmat(int64(Ar),num_lf-num_header-1,1);
case 'uint8'
A = repmat(uint8(Ar),num_lf-num_header-1,1);
case 'uint16'
A = repmat(uint16(Ar),num_lf-num_header-1,1);
case 'uint32'
A = repmat(uint32(Ar),num_lf-num_header-1,1);
case 'uint64'
A = repmat(uint64(Ar),num_lf-num_header-1,1);
end clear Ar
end
A1 = A(1);
if infolvl >= 1 ifstrcmpi(readmode,'line') waitbar(0.5,hw,{'reading line-by-line ...'}) else
poshw = get(hw,'Position');
set(hw,'Position',[poshw(1), poshw(2)-4/7*poshw(4), poshw(3), 11/7*poshw(4)]);
waitbar(0.5,hw,{'reading line-by-line because of error:';['[' errmsg ']']}) end drawnow end
% extract numeric values line-by-line: for ldx = num_header+1:(num_lf-1)
a = sscanf(f8((lf_idc(ldx)+1) : lf_idc(ldx+1)-1),conv_str)';
num_data_per_row(ldx-num_header) = numel(a);
% If necessary, expand A along second dimension (allowed by % num_colon < 0) if(num_data_per_row(ldx-num_header) > width_A) && (num_colon < 0)
A = [A, repmat(A1,size(A,1),...
num_data_per_row(ldx-num_header)-width_A)]; %#ok<AGROW>
width_A = num_data_per_row(ldx-num_header);
end
A(ldx-num_header,1:min(num_data_per_row(ldx-num_header),width_A)) = a(1:min(num_data_per_row(ldx-num_header),width_A));
% display waitbar: if ~mod(ldx,10000) if infolvl >= 1 waitbar(0.5+0.5*(ldx./(num_lf-1)),hw) end end% if end% for
% display info about number of numeric values per line if infolvl >= 2 if num_colon>=0
reference = num_colon;
elseif num_colon == -1;
reference = width_A;
else
reference = -num_colon;
end
disp('Row length info:')
idc_less_data = find(num_data_per_row<reference)+num_header;
idc_more_data = find(num_data_per_row>reference)+num_header;
num_less_data = numel(idc_less_data);
num_more_data = numel(idc_more_data);
num_equal_data = num_lf-num_header-1 - num_less_data - num_more_data;
info_ca(1:3,1) = {['' num2str(num_equal_data)];['' num2str(num_less_data)];['' num2str(num_more_data)]};
info_ca(1:3,2) = {[' row(s) found with ' num2str(reference) ' values'],...
' row(s) found with less values',...
' row(s) found with more values'};
info_ca(1:3,3) = {' ';' ';' '};
if num_less_data>0
info_ca{2,3} = ['(row no. ', num2str(idc_less_data(1:min(10,num_less_data))'), repmat(' ...',1,num_less_data>10), ')'];
end if num_more_data>0
info_ca{3,3} = ['(row no. ', num2str(idc_more_data(1:min(10,num_more_data))'), repmat(' ...',1,num_more_data>10), ')'];
end disp(strcatcell(info_ca));
% ANATXT analyse data layout in a text file for txt2mat % % Usage: % [ffn, nh, nc, cstr, SR, RM, llta, hl, ferrmsg] = ... % anatxt(fn,fpos,sr_input_ca,replace_expr,replace_regex,nh);
%
% ffn full file name of analysed file % nh number of header lines % nc number of columns % cstr conversion string (curr. always '%f') % SR character replacement string % RM recommended read mode % llta lines analysed after header % hl header line characters % ferrmsg file operation error message
%
% fn file name % fpos file position to start reading at % sr_input character replacement argument as for txt2mat % replace_expr expression replacement argument as for txt2mat % replace_regex regular expression replacement argument as for txt2mat % kl_input cell array of strings to skip lines % nh number of header lines; NaN if not provided
% Copyright 2006 A.Tönnesmann, The PierWorks, Inc. % $Revision: 2.80 $ $Date: 2008/04/05 13:05:08 $
% definitions
num_chars_read = 65536; % number of characters to read
has_nuff_n_ratio = 0.1; % this ratio will tell if a row has enough values
cstr = '%f'; % assume floats only (so far)
logfid = fopen(ffn);
if fpos > 0
status = fseek(logfid,fpos,'bof');
if status ~= 0
has_ferror = true;
ferrmsg = ferror(logfid,'clear');
end end
if ~has_ferror
[f8,f8cnt] = fread(logfid,num_chars_read,'*uint8'); % THE read if f8cnt < num_chars_read
did_read_to_end = true;
else
did_read_to_end = false;
end
f8 = f8';
end fclose(logfid);
if has_ferror || isempty(f8) [nh, nc, cstr, llta] = deal(0);
[cstr, SR, RM, hl] = deal('');
return end
%% Replace regular expressions, expressions and characters, if needed
if num_rr>0 for vdx = 1:num_rr % step through replacement arguments
srarg = replace_regex{vdx}; % pick a single argument for sdx = 1:(numel(srarg)-1)
f8 = regexprep(f8, srarg{sdx}, srarg{end});
end end end
if num_er>0 for vdx = 1:num_er % step through replacement arguments
srarg = replace_expr{vdx}; % pick a single argument for sdx = 1:(numel(srarg)-1)
f8 = strrep(f8, srarg{sdx}, srarg{end});
end end end
if num_sr>0 for vdx = 1:num_sr % step through replacement arguments
srarg = sr_input_ca{vdx}; % pick a single argument for sdx = 1:(numel(srarg)-1)
rep_idx = strfind(f8,srarg(sdx));
f8(rep_idx) = srarg(end); % perform replacement end end end
% position of the endmost printable ASCII character in f8 % (switch to uint8 and use V6.X find arguments for compatibility)
printasc = uint8([32:127, 128+32:255]); % printable ASCIIs
idx_last_pa = max(find(ismembc(double(f8),double(printasc)))); %#ok<MXFND> % new syntax: find(ismembc(f8,dec_nr), 1, 'last' )
% trim f8 after the first linebreak after this character, or, if none % present, after the first linebreak before it: ifany(idc_lb>idx_last_pa)
f8 = f8(1:min(idc_lb(idc_lb>idx_last_pa)));
else
f8 = f8(1:max(idc_lb));
end
%% Find bad line positions
num_kl = numel(kl_input);
% Check for possible bad line markers
kl_idc = [];
if num_kl>0
for idx = 1:num_kl % find positions of all markers
kl_idx_akt = strfind(char(f8),kl_input{idx})';
kl_idc = [kl_idc; kl_idx_akt]; %#ok<AGROW>
end% for end
%% Delete rows marked as bad if we found bad line markers if ~isempty(kl_idc)
% find indices of line breaks bordering a marker [L,R] = neighbours(kl_idc, idc_lb);
% care for multiple markers within a single row ifany(diff(L) <= 0) && any(diff(R) <= 0)
L = unique(L);
R = unique(R);
end % delete the bad rows
f8 = cutvec(f8,L+1,R,false);
% update line break indices
is_lb = f8==lbuint;
idc_lb = find(is_lb);
end
% types of characters:
dec_nr_p = sort(uint8('+-1234567890eE.NanIiFf')); % decimals with NaN, Inf, signs and .
sep_wo_k = uint8([932475859]); % separators excluding comma
sep_wi_k = uint8([93244475859]); % separators including comma (Tab Space ,/:
komma = uint8(','); % ,
other = setdiff(printasc, [sep_wi_k, dec_nr_p]); % printables without separators and decimals
% characters not expected to appear in the data lines:
is_othr = ismembc(f8d,double(other)); % switch to double for compatibility
is_beg_othr = diff([false, is_othr]); % true where groups of such characters begin
idc_beg_othr = find(is_beg_othr==1); % start indices of these groups [S, sidx] = sort([idc_lb,idc_beg_othr]); % in sidx, the numbers (1:num_lb) representing the linebreaks are placed between the indices of the start indices from above
num_beg_othr_per_line = diff([0,find(sidx<=num_lb)]) - 1; % number of character groups per line
ifisnan(nh) % Determine number of header lines:
nh = max([0, find(num_beg_othr_per_line>0)]); %#ok<MXFND> % for now, take the last line containing an 'other'-character
num_beg_numbers_ph = num_beg_numbers_per_line(nh+1:end)+num_beg_nan_per_line(nh+1:end); % number of lines following % by definition, a line is a valid data line if it contains enough numbers % compared to the average:
has_enough_numbers = num_beg_numbers_ph>has_nuff_n_ratio.*mean(num_beg_numbers_ph);
nh = nh + min(find(has_enough_numbers)) - 1; %#ok<MXFND>
end
if nh>0
f8v_idx1 = idc_lb(nh)+1;
hl = char(f8(1:idc_lb(nh)));
else
f8v_idx1 = 1;
hl = [];
end
f8v = f8(f8v_idx1:end); % valid data section of f8
llta = num_lb - nh; % number of non-header lines to analyse % todo: handle llta==0
% find out decimal character (. or ,)
SR = {}; % Init. replacement character string
SR_idx = 0; % Init. counter of the above
sepchar = ''; % Init. separator (delimiter) character
decchar = '.'; % Init. decimal character (default)
% Are there commas? If yes, are they decimal commas or delimiters? ifany( num_kom_per_line(nh+1:end) > 0)
sepchar = ','; % preliminary take comma for delimiter % Decimal commas are neighboured by two numeric digits ... % and between two commas there has to be another separator ifall(num_kom_per_line(nh+1:end) == num_beg_kombd_per_line(nh+1:end))...% Are all commas enclosed by numeric digits?
&& ~any(num_beg_digdotdig_per_line(nh+1:end) > 0)...% There are no numbers with dots?
&& ~any(idc_2kom(nh+1:end) > 0)% There is no pair of commas with no other separator inbetween?
decchar = ',';
sepchar = '';
num_values_per_line = -num_beg_digkomdig_per_line + num_beg_numbers_per_line; % number of values per line end end
% replacement string for replacements by spaces % other separators
is_wo_k_found = ismember(sep_wo_k, f8v); % Tab Space : ;
is_other_found= ismember(other,f8v); % other printable ASCIIs
% possible replacement string to replace : and ;
sr1 = [sepchar, char(sep_wo_k([00111]&is_wo_k_found))];
% possible replacement string to replace other characters
sr2 = char(other(is_other_found)); % still obsolete as such lines are treated as header lines
nc = max(num_items_per_line(nh+1:end)); % proposed number of columns
% suggest a proper read mode depending on uniformity of the number of values per % line ifnumel(unique(num_items_per_line(nh+1:end))) > 1
RM = 'line';
else
RM = 'auto';
end
% STRCATCELL Concatenate strings of a 1D/2D cell array of strings
%
% C = {'a ','123';'b','12'} % C = % 'a ' '123' % 'b' '12' % s = strcatcell(C) % s = % a 123 % b 12
num_col = size(C,2);
D = cell(1,num_col);
for idx = 1:num_col
D{idx} = char(C{:,idx});
end
s = [D{:}];
% NEIGHBOURS find nearest neighbours in a given set of values % % [L,R] = neighbours(a,b)
%
% find neighbours of elements of a in b: % L(i): b(i) with a(i)-b minimal, a(i)-b >0 (left neighbour) % R(i): b(i) with b-a(i) minimal, b-a(i)>=0 (right neighbour) % % If no left or right neighbour matching the above criteria can be found % in b, -Inf or Inf (respectively) will be returned.
%
%
% EXAMPLE: % [L,R] = neighbours([-5, pi, 101],[-5:2:101]) % % L = % -Inf % 3 % 99 % R = % -5 % 5 % 101
% compare the possible property strings to all arguments and save what % can be found at which argument number to <proppos> and <valpos> for adx = 2:length(allargin) %nargin% look at all args but the first ifischar(allargin{adx})% if it is a string... for pdx = 1:len_pn
ifisequal(lower(propnames{pdx}),lower(allargin{adx})) if proppos(pdx) ~= 0 error(['Multiple occurence of ' propnames{pdx} ' argument.']) end
proppos(pdx) = adx;
valpos(pdx) = adx+1;
end end end end
% add argument numbers that have no property string, i.e. that occur % before the first property string
firstproppos = min(proppos(proppos>0));
ifisempty(firstproppos) for pdx = 2:length(allargin)
valpos(pdx-1) = pdx;
end% for else for pdx = 2:firstproppos-1 if proppos(pdx-1) ~= 0 error(['Multiple occurence of ' propnames{pdx-1} ' argument.']) end
valpos(pdx-1) = pdx;
end end
% Check input argument contents % todo: complete type checking % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
is_argin_num_header= false; % Init., is an argument for the number of header lines given? if valpos(1) ~= 0
num_header = allargin{valpos(1)};
if ~isempty(num_header)
is_argin_num_header = true;
end else
num_header = NaN;
end % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
is_argin_num_colon = false; % Init., is an argument for the number of data columns lines given? if valpos(2) ~= 0
num_colon = allargin{valpos(2)};
if ~isempty(num_colon)
is_argin_num_colon = true;
end else
num_colon = [];
end % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
%is_argin_conv_str = false; % Init., conversion string argument given? if valpos(3) ~= 0
conv_str = allargin{valpos(3)};
ifisempty(conv_str)
conv_str = '%f';
%else % is_argin_conv_str = true; end else
%conv_str = {};
conv_str = '%f'; % standard, as always returned by anatxt end % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ % Check for character replacement argument. For compatibility reasons, % multiple strings as separate arguments are still supported.
has_sr_input_only = false;
sr_input_ca = {};
if valpos(4) ~= 0 if iscellstr(allargin{valpos(4)})
sr_input_ca = allargin{valpos(4)};
elseifischar(allargin{valpos(4)});
sr_input_ca = {allargin{valpos(4):end}};
disp([mfilename ': for future versions, please use a singlecell array of strings as an input argument for multiple replacement strings.'])
has_sr_input_only = true;
else error('replacement string argument must be of type string or cell array of strings') end
num_sr = length(sr_input_ca);
else
num_sr = 0;
end % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if valpos(5) ~= 0 && ~has_sr_input_only % bad line strings if iscellstr(allargin{valpos(5)})
kl_input_ca = allargin{valpos(5)};
elseifischar(allargin{valpos(5)});
kl_input_ca = {allargin{valpos(5)}};
disp([mfilename ': for future versions, please use a singlecell array of strings as an input argument for bad line marker strings.']) else error('bad line marker argument must be of type string or cell array of strings') end
num_kl = length(kl_input_ca);
else
num_kl = 0;
kl_input_ca = {};
end % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if valpos(6) ~= 0% 'ReplaceExpression'
replace_expr = allargin{valpos(6)};
num_er = length(replace_expr);
else
replace_expr = {};
num_er = 0;
end % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if valpos(7) ~= 0% 'DialogString'
dialog_string = allargin{valpos(7)};
else
dialog_string = 'Choose a data file';
end % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if valpos(8) ~= 0% 'MemPar'
mem_par = allargin{valpos(8)};
idx_rng = mem_par(1);
ldx_rng = mem_par(2);
else
idx_rng = 2E7; % idx_rng = 2E7; % number of characters to be processed simultaneously (memory-dependent!)
ldx_rng = 2E5; % ldx_rng = 2E5; % number of rows to be processed simultaneously (memory-dependent!) end % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if valpos(9) ~= 0% 'InfoLevel'
infolvl = allargin{valpos(9)};
else
infolvl = 2;
end % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if valpos(10) ~= 0% 'ReadMode'
readmode = allargin{valpos(10)};
is_argin_readmode = true;
%% force readmode to 'line' if num_colon < 0 if is_argin_num_colon && num_colon < 0 && ~strcmpi(readmode,'line');
readmode = 'line';
warning('txt2mat:ineptReadmode', ...
'ReadMode isset to ''line'' as NumColumns was given as negative.') end else
is_argin_readmode = false;
if is_argin_num_colon && num_colon < 0;
readmode = 'line';
else
readmode = 'auto';
end end % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if valpos(11) ~= 0% 'NumericType'
numerictype = allargin{valpos(11)};
else
numerictype = 'double';
end % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if valpos(12) ~= 0% 'RowRange'
rowrange = allargin{valpos(12)};
if ~(numel(rowrange)==2) || ~issorted(rowrange) || rowrange(1)<1 || ... (rem(rowrange(1),1)~=0) || ((rem(rowrange(2),1)~=0) && (rowrange(2)~=Inf)) error('RowRange argument must be a sorted positive integer 2x1 vector.') end
is_argin_rowrange = true;
else
is_argin_rowrange = false;
rowrange = [1,Inf];
end % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if valpos(13) ~= 0% 'FilePos'
filepos = allargin{valpos(13)};
if filepos<0 || (rem(filepos,1)~=0) error('FilePos argument must be a nonnegative integer.') end
is_argin_filepos = true;
else
is_argin_filepos = false;
filepos = 0;
end % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if valpos(14) ~= 0% 'ReplaceRegExpr'
replace_regex= allargin{valpos(14)};
num_rr = length(replace_regex);
else
replace_regex= {};
num_rr = 0;
end % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ % handle file name argument ifnargin == 0 || isempty(allargin{1})% no file or path name given? [filn,pn] = uigetfile('*.*', dialog_string); % open file dialogue
ffn = fullfile(pn,filn);
elseifexist(allargin{1},'dir') == 7% only path name given
curcd = cd;
cd(allargin{1}); % temporarily change directory [filn,pn] = uigetfile('*.*', dialog_string); % open file dialogue
ffn = fullfile(pn,filn);
cd(curcd);
elseifexist(allargin{1},'file')% file name given
ffn = allargin{1};
[dum_pathstr,name,ext] = fileparts(ffn);
filn = [name,ext];
else% wrong name error([mfilename ': no such file or directory.']) end ifexist(ffn,'file')~=2% check again (e.g. afger ESC in open file dialogue) error('No existing file given.') end
% generate a shortened form of the file name: iflength(filn) < 28
ffn_short = filn;
else
ffn_short = ['...' filn(end-17:end)];
end
% DETECT_LINE_BREAK_CHARACTERS find out type of line termination of a file
%
% lb = detect_line_break_characters(ffn)
%
% with % ffn ascii file name % lb line break character(s) as uint8, i.e. % [13 10] (cr+lf) for standard DOS / Windows files % [10] (lf) for Unix files % [13] (cr) for Mac files
%
% The DOS style values are returned as defaults if no such line breaks are % found.
% Cycle through file and read until we find line termination characters or % we reach the end of file. % Possible line breaks are: cr+lf (default), lf, cr
logfid = fopen(ffn);
has_found_lbs = false;
while ~has_found_lbs
pos_crlf = strfind(f8',crlfchar);
pos_lf = strfind(f8',lfchar);
pos_cr = strfind(f8(1:end-1)',crchar);
% here we ignored a cr at the end as it might belong to a cr+lf % combination (later we'll step back one byte in the file position to % avoid overlooking such a single cr)
ifall(num_lbs==0) fseek(logfid, -1, 0); % step back one byte
% if we reached the end of file without finding any special % character, set the endmost line break character and the complete % line break character to DOS values as defaults if cntr < readlen
has_found_lbs = true; % just to exit the while loop
lb = crlfuint; % complete line break character set end elseif num_lbs(1)>0
has_found_lbs = true;
lb = crlfuint;
elseif num_lbs(2)>0
has_found_lbs = true;
lb = lfuint;
elseif num_lbs(3)>0
has_found_lbs = true;
lb = cruint;
end end fclose(logfid);
geh ich von aus sonst hätte er es mir ja nicht gegeben
wenn ich eine datei lade und diese dann mit txt2mat auswerte klappt das auch. Nur wenn ich das üer die plotprofil mache funzt es nicht
Einstellungen und Berechtigungen
Du kannst Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen. Du kannst Dateien in diesem Forum posten Du kannst Dateien in diesem Forum herunterladen
MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.