Mercurial > hg > ltpda
diff m-toolbox/classes/@ao/fromComplexDatafile.m @ 0:f0afece42f48
Import.
author | Daniele Nicolodi <nicolodi@science.unitn.it> |
---|---|
date | Wed, 23 Nov 2011 19:22:13 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/m-toolbox/classes/@ao/fromComplexDatafile.m Wed Nov 23 19:22:13 2011 +0100 @@ -0,0 +1,303 @@ +% FROMCOMPLEXDATAFILE Construct an AO from filename AND parameter list +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% FUNCTION: fromDatafile +% +% DESCRIPTION: Construct an AO from filename AND parameter list +% +% CALL: a = fromComplexDatafile(a, pli) +% +% PARAMETER: a: empty ao-object +% pli: plist-object (must contain the filename) +% +% VERSION: $Id: fromComplexDatafile.m,v 1.12 2011/08/12 09:55:39 hewitson Exp $ +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +function objs = fromComplexDatafile(ain, pli) + + utils.helper.msg(utils.const.msg.PROC1, 'loading complex data from filename and/or plist'); + + VERSION = '$Id: fromComplexDatafile.m,v 1.12 2011/08/12 09:55:39 hewitson Exp $'; + + % get AO info + mi = ao.getInfo('ao', 'From Complex ASCII File'); + + % Set the method version string in the minfo object + mi.setMversion([VERSION '-->' mi.mversion]); + + % Get filename + file_name = find(pli, 'filename'); + file_path = find(pli, 'filepath'); + + [filePath, fileName, ext] = fileparts(file_name); + + % Add the file extenstion to the fileName + fileName = strcat(fileName, ext); + + % Define the path of the + if ~isempty(file_path) && ~isempty(filePath) + % Do nothing because we will use filePath + elseif ~isempty(file_path) + filePath = file_path; + elseif ~isempty(filePath) + % Do nothing because we will use filePath + else + filePath = pwd(); + end + + absolutePathname = fullfile(filePath, fileName); + + % Check if the abolute Pathname exist + if ~exist(absolutePathname, 'file') + absolutePathname = fileName; + end + + %%%%%%%%%% Get default parameter list %%%%%%%%%% + pl = applyDefaults(mi.plists, pli); + + pl = pset(pl, 'filename', fileName); + pl = pset(pl, 'filepath', filePath); + + data_type = find (pl, 'type'); + columns = find (pl, 'columns'); + comment_char = find (pl, 'comment_char'); + orig_col = columns; % necessary for the histroy + objs = []; + + %%%%%%%%%% read file %%%%%%%%%% + [fid,msg] = fopen (absolutePathname, 'r'); + if (fid < 0) + error ('### can not open file: %s \n### error msg: %s', fileName, msg); + end + + %%%%%%%%%% create scan format: '%f %f %f %f %f %*[^\n]' %%%%%%%%%% + scan_format = ''; + read_col = 0; + sort_col = sort(columns); + + %%%%%%%%%% Get/Count max number of lines %%%%%%%%%% + maxLines = numlines(fid); + utils.helper.msg(utils.const.msg.PROC2, 'Counting lines: %d', maxLines); + fseek(fid, 0, 'bof'); + + %%%%%%%%%% Read data %%%%%%%%%% + readlines = min(50000, maxLines); + nlines = 0; + + %%% Based on skipping the not used columns we have to transform the columns. + %%% We must transform the columns [ 2 5 2 6 5 7] to [ 1 2 1 3 2 4] + %%% In each loop we have to replace the corresponding value. In the first loop + %%% the first minimum, in the second loop the second minimum, ... with the + %%% current loop number. + for j=1:max(columns) + if ismember(j, columns) + scan_format = [scan_format '%n ']; + read_col = read_col + 1; + replace = min(sort_col); + + columns (columns==replace) = read_col; + sort_col(sort_col==replace) = []; + else + scan_format = [scan_format '%*n ']; + end + end + scan_format = [deblank(scan_format) '%*[^\n]']; + + %%% preallocate data array + f_data = zeros(maxLines, read_col); + + %%% check if using robust read: 'yes'/'no' or true/false or 'true'/'false' + robust = find(pl, 'Robust'); + if isempty(robust) + robust = false; + elseif ischar(robust) + if strcmpi(robust, 'yes') || strcmpi(robust, 'true') + robust = true; + else + robust = false; + end + end + + if robust + + f_data = robustRead(fid, f_data, columns, orig_col); + + else + + %%% Look for the first line of data + if ~isempty(comment_char) + while ~feof(fid) + f = deblank(fgetl(fid)); + if ~isempty(f) + if f(1) ~= comment_char + break; + end + end + end + else + f = deblank(fgetl(fid)); + end + + %%% Scan it to find how many columns we have in the file + C = textscan(f, scan_format, 1, 'CollectOutput', 1); + if any(isnan(C{:})) + error('### Error in file format. Perhaps you specified more columns than the file contains?'); + end + + fseek(fid, 0, 'bof'); + %%% read file to end + while ~feof(fid) && nlines < maxLines + + if isempty(comment_char) + C = textscan(fid, scan_format, readlines, ... + 'CollectOutput', 1); + else + C = textscan(fid, scan_format, readlines, ... + 'CommentStyle', comment_char, ... + 'CollectOutput', 1); + end + f_data(nlines+1:nlines+size(C{1},1),:) = C{1}; + nlines = nlines + length(C{1}); + + if isempty(C{1}) + error('\n### There are no data.\n### Did you use the right comment character?\n### The current comment character is: [%s]\n### Use a parameter list with the parameter:\n### plist(''comment_char'', ''%%'')', comment_char); + end + utils.helper.msg(utils.const.msg.PROC2, 'read %09d lines of %09d', nlines, maxLines); + + end + fclose(fid); + + %%% get only the data we want + if size(f_data,1) > nlines + f_data = f_data(1:nlines, :); + end + end + + + %%%%%%%%%% Create for each three columns the data object %%%%%%%%%% + + %%%%%%%%%% The numbers in columns must be straight %%%%%%%%%% + if mod(length(columns),3) ~= 0 + error('### The numbers in columns must be multiple of three.'); + end + + complex_type = pl.find('complex_type'); + + for lauf = 1:length(columns)/3 + + data_x = f_data(:, columns(lauf*3-2)); + data_y_1 = f_data(:, columns(lauf*3-1)); + data_y_2 = f_data(:, columns(lauf*3)); + + if strcmpi(complex_type, 'abs/deg') + data_y = data_y_1 .* exp(1i*data_y_2*pi/180); + + elseif strcmpi(complex_type, 'dB/deg') + data_y = 10.^(data_y_1./20) .* exp(1i*data_y_2*pi/180); + + elseif strcmpi(complex_type, 'abs/rad') + data_y = data_y_1 .* exp(1i*data_y_2); + + elseif strcmpi(complex_type, 'dB/rad') + data_y = 10.^(data_y_1./20) .* exp(1i*data_y_2); + + elseif strcmpi(complex_type, 'real/imag') + data_y = complex(data_y_1, data_y_2); + + else + error('### I can not handle real [%s] and imaginary [%s].', real_type, imag_type); + end + + % create data object corresponding to the parameter list + ao_data = []; + switch lower(data_type) + case 'tsdata' + ao_data = tsdata(data_x, data_y); + case 'fsdata' + ao_data = fsdata(data_x, data_y); + case 'cdata' + error('### Please code me up'); + case 'xydata' + ao_data = xydata(data_x, data_y); + otherwise + error('### unknown data type ''%s''', data_type); + end + aa = ao(ao_data); + % overide the default name + if isempty(pl.find('name')) + pl.pset('name', sprintf('%s_%02d_%02d_%02d', fileName, orig_col(lauf*3-2), orig_col(lauf*3-1), orig_col(lauf*3))); + end + + % set units + aa.setXunits(pl.find('xunits')); + aa.setYunits(pl.find('yunits')); + + % Add history + pl = pl.pset('columns', [orig_col(lauf*3-2) orig_col(lauf*3-1) orig_col(lauf*3)]); + aa.addHistory(mi, pl, [], []); + + objs = [objs aa]; + + end + + % set any object properties now + objs.setObjectProperties(pl); + +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Local Functions % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% FUNCTION: numlines +% +% SYNTAX: count = numlines(fid); +% +% DESCRIPTION: Number of lines in an ASCII file +% +% HISTORY: 02-08-2002 Peter Acklam, CSSM post +% Creation. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +function lines = numlines(fid) + + lines = 0; % number of lines in file + nlchr = uint8(sprintf('\n')); % newline chr as uint8 + bsize = 4 * 256 * 8192; % block size to read + + while ~feof(fid) + block = fread(fid, bsize, '*uint8'); + lines = lines + sum(block == nlchr); + end + if ~isempty(block) % in case file is empty + lines = lines + double(block(end) ~= nlchr); + end +end + +% A robust and slow data reader +function f_data = robustRead(fid, f_data, columns, orig_cols) + + cols = unique(columns); + ocols = unique(orig_cols); + Nline = 1; + while ~feof(fid) + % read and parse line + tokens = sscanf(fgets(fid), '%f'); + % parse tokens + if ~isempty(tokens) + f_data(Nline, cols) = tokens(ocols); + if mod(Nline, 1000) == 0 + utils.helper.msg(utils.const.msg.PROC2, 'lines read: %d', Nline); + end + Nline = Nline + 1; + end + end + + % drop empty lines + f_data = f_data(1:Nline-1, :); + +end