[4] | 1 | function [header_mat, data_mat] = mhdrload_bis(file)
|
---|
| 2 | %MHDRLOAD Load data from an ASCII file containing multiple text
|
---|
| 3 | % headers throughout the file.
|
---|
| 4 | % [header, data] = MHDRLOAD('filename.ext') reads a data file
|
---|
| 5 | % called 'filename.ext', which contains a text header. There
|
---|
| 6 | % is no default extension; any extensions must be explicitly
|
---|
| 7 | % supplied.
|
---|
| 8 | %
|
---|
| 9 | % The first output, HEADER, is the header information, returned
|
---|
| 10 | % as a text array.
|
---|
| 11 | % The second output, DATA, is the data matrix. This data matrix
|
---|
| 12 | % has the same dimensions as the data in the file, one row per
|
---|
| 13 | % line of ASCII data in the file. If the data is not regularly
|
---|
| 14 | % spaced (i.e., each line of ASCII data does not contain the
|
---|
| 15 | % same number of points), the data is returned as a column
|
---|
| 16 | % vector.
|
---|
| 17 | %
|
---|
| 18 | % Limitations: No lines of the text header can begin with
|
---|
| 19 | % a number. The header must come before the data.
|
---|
| 20 | %
|
---|
| 21 | % MODIFIED from hdrload.m: Dec 20, 2002 Jeff Daniels, NSWCCD - ARD
|
---|
| 22 | %
|
---|
| 23 | % See also LOAD, SAVE, SPCONVERT, FSCANF, FPRINTF, STR2MAT, HDRLOAD.
|
---|
| 24 | % See also the IOFUN directory.
|
---|
| 25 | %
|
---|
| 26 | % EXAMPLE:
|
---|
| 27 | % If example_data.txt is:
|
---|
| 28 | % Recorded Data: 12/15/2001
|
---|
| 29 | % header 1
|
---|
| 30 | % rows = 2 cols = 2
|
---|
| 31 | % 12 23
|
---|
| 32 | % 34 21
|
---|
| 33 | % header 2
|
---|
| 34 | % rows = 3 cols = 3
|
---|
| 35 | % 19 73 13
|
---|
| 36 | % 33 32 47
|
---|
| 37 | % 34 12 68
|
---|
| 38 | %
|
---|
| 39 | % MHDRLOAD returns:
|
---|
| 40 | % header(:,:,1) =
|
---|
| 41 | %
|
---|
| 42 | % Recorded Data: 12/15/2001
|
---|
| 43 | % header 1
|
---|
| 44 | % rows = 2 cols = 2
|
---|
| 45 | %
|
---|
| 46 | % header(:,:,2) =
|
---|
| 47 | %
|
---|
| 48 | % header 2
|
---|
| 49 | % rows = 3 cols = 3
|
---|
| 50 | %
|
---|
| 51 | % data(:,:,1) =
|
---|
| 52 | %
|
---|
| 53 | % 12 23 0
|
---|
| 54 | % 34 21 0
|
---|
| 55 | % 0 0 0
|
---|
| 56 | %
|
---|
| 57 | % data(:,:,2) =
|
---|
| 58 | %
|
---|
| 59 | % 19 73 13
|
---|
| 60 | % 33 32 47
|
---|
| 61 | % 34 12 68
|
---|
| 62 |
|
---|
| 63 | % check number and type of arguments
|
---|
| 64 | if nargin < 1
|
---|
| 65 | error('Function requires one input argument');
|
---|
| 66 | elseif ~ischar(file)
|
---|
| 67 | error('Input argument must be a string representing a filename');
|
---|
| 68 | end
|
---|
| 69 |
|
---|
| 70 | % Open the file. If this returns a -1, we did not open the file
|
---|
| 71 | % successfully.
|
---|
| 72 | fid = fopen(file);
|
---|
| 73 | if fid==-1
|
---|
| 74 | error('File not found or permission denied.');
|
---|
| 75 | end
|
---|
| 76 |
|
---|
| 77 | % Initialize loop variables
|
---|
| 78 | % We store the number of lines in the header, and the maximum length
|
---|
| 79 | % of any one line in the header. These are used later in assigning
|
---|
| 80 | % the 'header' output variable.
|
---|
| 81 | no_lines = 0;
|
---|
| 82 | max_line = 0;
|
---|
| 83 |
|
---|
| 84 | % We also store the number of columns in the data we read. This way
|
---|
| 85 | % we can compute the size of the output based on the number of
|
---|
| 86 | % columns and the total number of data points.
|
---|
| 87 | ncols = 0;
|
---|
| 88 |
|
---|
| 89 | % Finally, we initialize the data to [].
|
---|
| 90 | data = [];
|
---|
| 91 | j=1;
|
---|
| 92 |
|
---|
| 93 | % Start processing.
|
---|
| 94 | line = fgetl(fid);
|
---|
| 95 | if ~ischar(line)
|
---|
| 96 | disp('Warning: file contains no header and no data')
|
---|
| 97 | end;
|
---|
| 98 |
|
---|
| 99 | while line~=-1,
|
---|
| 100 | [data, ncols, errmsg, nxtindex] = sscanf(line, '%f');
|
---|
| 101 | % One slight problem, pointed out by Peter VanderWal: If the first
|
---|
| 102 | % character of the line is 'e', then this will scan as 0.00e+00.
|
---|
| 103 | % We can trap this case specifically by using the 'next index'
|
---|
| 104 | % output: in the case of a stripped 'e' the next index is one,
|
---|
| 105 | % indicating zero characters read. See the help entry for 'sscanf'
|
---|
| 106 | % for more information on this output parameter.
|
---|
| 107 | % We loop through the file one line at a time until we find some
|
---|
| 108 | % data. After that point we stop checking for header information.
|
---|
| 109 | % This part of the program takes most of the processing time, because
|
---|
| 110 | % fgetl is relatively slow (compared to fscanf, which we will use
|
---|
| 111 | % later).
|
---|
| 112 | while isempty(data)|(nxtindex==1)
|
---|
| 113 | no_lines = no_lines+1;
|
---|
| 114 | max_line = max([max_line, length(line)]);
|
---|
| 115 | % Create unique variable to hold this line of text information.
|
---|
| 116 | % Store the last-read line in this variable.
|
---|
| 117 | eval(['line', num2str(no_lines), '=line;'])
|
---|
| 118 | line = fgetl(fid);
|
---|
| 119 | if ~ischar(line)
|
---|
| 120 | disp('Warning: file contains no data')
|
---|
| 121 | break
|
---|
| 122 | end;
|
---|
| 123 | [data, ncols, errmsg, nxtindex] = sscanf(line, '%f');
|
---|
| 124 | end % while
|
---|
| 125 |
|
---|
| 126 | % Create header output from line information. The number of lines and
|
---|
| 127 | % the maximum line length are stored explicitly, and each line is
|
---|
| 128 | % stored in a unique variable using the 'eval' statement within the
|
---|
| 129 | % loop. Note that, if we knew a priori that the headers were 10 lines
|
---|
| 130 | % or less, we could use the STR2MAT function and save some work.
|
---|
| 131 | % First, initialize the header to an array of spaces.
|
---|
| 132 | header_mat(1:no_lines,1:max_line,j) = setstr(' '*ones(no_lines,max_line));
|
---|
| 133 | for i = 1:no_lines,
|
---|
| 134 | if length(eval(['line' num2str(i)])),
|
---|
| 135 | varname = eval(['line' num2str(i)]);
|
---|
| 136 | else
|
---|
| 137 | varname = ['line',num2str(i)];
|
---|
| 138 | end
|
---|
| 139 | % Note that we only assign this line variable to a subset of this
|
---|
| 140 | % row of the header array. We thus ensure that the matrix sizes in
|
---|
| 141 | % the assignment are equal.
|
---|
| 142 | %eval(['header(i, 1:length(' varname ')) = ' varname ';']);
|
---|
| 143 | header_mat(i,1:length(varname),j)=varname;
|
---|
| 144 | end
|
---|
| 145 |
|
---|
| 146 | % Now that we have read in the first line of data, we can skip the
|
---|
| 147 | % processing that stores header information, and just read in the
|
---|
| 148 | % rest of the data.
|
---|
| 149 | data = [data; fscanf(fid, '%f')];
|
---|
| 150 | % Resize output data, based on the number of columns (as returned
|
---|
| 151 | % from the sscanf of the first line of data) and the total number of
|
---|
| 152 | % data elements. Since the data was read in row-wise, and MATLAB
|
---|
| 153 | % stores data in columnwise format, we have to reverse the size
|
---|
| 154 | % arguments and then transpose the data. If we read in irregularly
|
---|
| 155 | % spaced data, then the division we are about to do will not work.
|
---|
| 156 | % Therefore, we will trap the error with an EVAL call; if the reshape
|
---|
| 157 | % fails, we will just return the data as is.
|
---|
| 158 | eval('data_mat(1:length(data)/ncols,1:ncols,j) = reshape(data,ncols, length(data)/ncols)'';', '')
|
---|
| 159 | line = fgetl(fid);
|
---|
| 160 | j=j+1;
|
---|
| 161 | no_lines = 0;
|
---|
| 162 | end
|
---|
| 163 |
|
---|
| 164 | fclose(fid);
|
---|
| 165 | % And we're done!
|
---|
| 166 |
|
---|
| 167 | end |
---|