Home > database > ensemble_print_datast.m

ensemble_print_datast

PURPOSE ^

prints the contents of a data struct to screen and/or to file

SYNOPSIS ^

function outdata = ensemble_print_datast(indata,defs)

DESCRIPTION ^

 prints the contents of a data struct to screen and/or to file
 
   outdata = ensemble_print_datast(indata,defs)
 
 This simple script prints the contents of a given ensemble data structure
 to screen and/or to file. Given a single ensemble data structure, it will
 use "indata.vars" as the column names, and "indata.data" as the rows, and
 will print first the column names, then the rows, delimited by commas
 (default), or some other character (as defined by "defs").
 
 Given nested ensemble data structures, or a cell array of data
 structures, it will iterate through each data structure and print the
 contents of each data structure. In this case, the function will recurse
 upon itself.
 
 NOTE: if there are semi-nested data structures, such that in a given data
 structure there are some columns that are not nested data structures, and
 some that are, this funciton will not output the data in that particular
 structure.
 
 NOTE: this function doesn't know how to deal with nested cells within
 indata.data columns. Currently, these are output as "MxN cell"
 
 REQUIRES
   indata.vars
   indata.data
   indata.name - if present, this will be used to identify data structure
       output, especially in the case of nested data structures. if no
       .name is found, but .type is found, .type will be used.
   indata.parent_name - if the function is given nested data structures,
       upon recursion, it will add this name to the resulting indata
       structure, and the contents of this name will be used to identify
       output at the given sub-struct level. indata.parent_name will be
       defined thus:
 
       sprintf('%s.%s',parent_indata_name,child_indata_name)
 
   defs.delim (default: comma) - the character or set of characters that
       will be used to delimit the output values
   defs.fid - if nested data structures are provided as input, the file id
       from the first iteration will be saved, passed on to recursive
       calls to this function, and used for output over defs.export.
   defs.export - parameters for ensemble_init_fid. if present, they will
       be used to try to print data to file.
       .print, .write2file, .fname, .filemode
   defs.print2screen (default: 1) - print data to the screen (stdout)?
 
 RETURNS
   indata - in the form it was provided

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function outdata = ensemble_print_datast(indata,defs)
0002 
0003 % prints the contents of a data struct to screen and/or to file
0004 %
0005 %   outdata = ensemble_print_datast(indata,defs)
0006 %
0007 % This simple script prints the contents of a given ensemble data structure
0008 % to screen and/or to file. Given a single ensemble data structure, it will
0009 % use "indata.vars" as the column names, and "indata.data" as the rows, and
0010 % will print first the column names, then the rows, delimited by commas
0011 % (default), or some other character (as defined by "defs").
0012 %
0013 % Given nested ensemble data structures, or a cell array of data
0014 % structures, it will iterate through each data structure and print the
0015 % contents of each data structure. In this case, the function will recurse
0016 % upon itself.
0017 %
0018 % NOTE: if there are semi-nested data structures, such that in a given data
0019 % structure there are some columns that are not nested data structures, and
0020 % some that are, this funciton will not output the data in that particular
0021 % structure.
0022 %
0023 % NOTE: this function doesn't know how to deal with nested cells within
0024 % indata.data columns. Currently, these are output as "MxN cell"
0025 %
0026 % REQUIRES
0027 %   indata.vars
0028 %   indata.data
0029 %   indata.name - if present, this will be used to identify data structure
0030 %       output, especially in the case of nested data structures. if no
0031 %       .name is found, but .type is found, .type will be used.
0032 %   indata.parent_name - if the function is given nested data structures,
0033 %       upon recursion, it will add this name to the resulting indata
0034 %       structure, and the contents of this name will be used to identify
0035 %       output at the given sub-struct level. indata.parent_name will be
0036 %       defined thus:
0037 %
0038 %       sprintf('%s.%s',parent_indata_name,child_indata_name)
0039 %
0040 %   defs.delim (default: comma) - the character or set of characters that
0041 %       will be used to delimit the output values
0042 %   defs.fid - if nested data structures are provided as input, the file id
0043 %       from the first iteration will be saved, passed on to recursive
0044 %       calls to this function, and used for output over defs.export.
0045 %   defs.export - parameters for ensemble_init_fid. if present, they will
0046 %       be used to try to print data to file.
0047 %       .print, .write2file, .fname, .filemode
0048 %   defs.print2screen (default: 1) - print data to the screen (stdout)?
0049 %
0050 % RETURNS
0051 %   indata - in the form it was provided
0052 
0053 % FB <fbarrett@ucdavis.edu> 2010.10.18
0054 % 24Jul2013 - Petr Janata - added handling of logicals as well as standar
0055 %             filtering
0056 % 25Jan2015 - added option of enclosing strings containing commas in
0057 %             quotes. This is now the default behavior when comma-delimited
0058 % 29Aug2016 - PJ added optional output of datatype row and handling for R
0059 
0060 %% set variables
0061 outdata = indata;
0062 ic = set_var_col_const(indata.vars);
0063 nc = length(indata.vars);
0064 
0065 if nargin < 2
0066   defs = struct;
0067 end
0068 
0069 try delim = defs.delim; catch delim = ','; end
0070 try print2screen = defs.print2screen; catch print2screen = 1; end
0071 
0072 name = '';
0073 if isfield(indata,'name')
0074   name = indata.name;
0075 elseif isfield(indata,'type')
0076   name = indata.type;
0077 elseif isfield(defs,'name')
0078   name = defs.name;
0079 end
0080 if ~isempty(name) && isfield(indata,'parent_name')
0081   name = sprintf('%s.%s',indata.parent_name,name);
0082 end
0083 
0084 parent = 0;
0085 fid = 0;
0086 if isfield(defs,'fid')
0087   fid = defs.fid;
0088 elseif isfield(defs,'export')
0089   fid = ensemble_init_fid(defs.export);
0090   defs.fid = fid;
0091   parent = 1;
0092 end
0093 
0094 if isfield(defs,'print2screen')
0095   print2screen = defs.print2screen;
0096 else
0097   print2screen = 1;
0098 end
0099 
0100 if isfield(defs, 'outputType')
0101   outputType = defs.outputType;
0102 else
0103   outputType = 'SAS';
0104 end
0105 
0106 
0107 % Add quotes around field contents if they contain a comma?
0108 if isfield(defs,'enclose_commas')
0109   encloseCommas = defs.enclose_commas;
0110 else
0111   if strcmp(delim,',')
0112     encloseCommas = 1;
0113   else
0114     encloseCommas = 0;
0115   end
0116 end
0117 
0118 if ~fid && ~print2screen, error('no output specified'); end
0119 
0120 %% check to see if there are nested data structures
0121 nested = zeros(1,nc);
0122 for k=1:nc
0123   if isstruct(indata.data{k})
0124     if isfield(indata.data{k},'data') && isfield(indata.data{k},'vars')
0125       % nested data structure is found
0126       nested(k) = 1;
0127       
0128       % recurse
0129       recdata = indata.data{k};
0130       if ~isempty(name), recdata.parent_name = name; end
0131       ensemble_print_datast(recdata,defs);
0132     else
0133       nested(k) = -1;
0134       msg = 'bad input structure found';
0135       if ~isempty(name), msg = sprintf('%s in %s',msg,name); end
0136       msg = sprintf('%s, SKIPPING',msg);
0137       warning(msg);
0138     end
0139   end % end if isstruct(indata.data{k
0140 end % for k=1:nc
0141 
0142 if any(nested) && ~all(nested)
0143   msg = 'some, but not all, nested data structures found';
0144   if ~isempty(name), msg = sprintf('%s in %s',msg,name); end
0145   msg = sprintf('%s, SKIPPING non-nested structures',msg);
0146   warning(msg);
0147   return
0148 elseif all(nested)
0149   return
0150 end
0151 
0152 %% Perform filtering
0153 if isfield(defs, 'filt') && ~isempty(defs.filt)
0154   indata = ensemble_filter(indata, defs.filt);
0155 end
0156 
0157 %% Check to see if there are multiple columns within any given variable
0158 for ivar = 1:nc
0159   dims = size(indata.data{ivar});
0160   if dims(2) > 1
0161     warning('Variable <%s> contains %d columns. Only using values in first column', indata.vars{ivar}, dims(2));
0162   end
0163 end
0164 
0165 %% non-nested data structure, so print it out
0166 % print header lines
0167 if ~isempty(name) && isfield(defs, 'print_header') && defs.print_header
0168   if print2screen, fprintf(1,'----------\nSource: %s\n----------\n\n',name); end
0169   if fid, fprintf(fid,'----------\nSource: %s\n----------\n\n',name); end
0170 end
0171 
0172 % print variable names
0173 varstr = cell2str(indata.vars,delim);
0174 if print2screen, fprintf(1,'%s\n',varstr); end
0175 if fid, fprintf(fid,'%s\n',varstr); end
0176 
0177 % Check whether we are also writing a line of datatypes
0178 haveDatatypeInfo = 0;
0179 if isfield(defs, 'write_datatype') && defs.write_datatype
0180   % Make sure we have a datatype field in the input data and that it
0181   % matches vars in length
0182   if isfield(indata, 'datatype') && (length(indata.datatype) == length(indata.vars))
0183     haveDatatypeInfo = 1;
0184     
0185     if strcmp(outputType,'R')
0186       datatype = strrep(indata.datatype,'n','numeric');
0187       datatype = strrep(datatype,'l','logical');
0188       datatype = strrep(datatype,'s','character');
0189     end
0190     datatypestr = cell2str(datatype,',');
0191     
0192     if print2screen, fprintf(1,'%s\n', dataypestr); end
0193     if fid, fprintf(fid,'%s\n', datatypestr); end
0194   end
0195 end % if isfield(params, 'write_datatype')
0196 
0197 % iterate over rows, print data
0198 for k=1:size(indata.data{1},1)
0199   % generate data string for the given row
0200   inputstr = '';
0201   for l=1:nc
0202     data = indata.data{l}(k);
0203     if iscell(data)
0204       if iscell(data{1})
0205         data = sprintf('%dx%d cell',size(data,1),size(data,2));
0206       else
0207         data = data{1};
0208       end
0209     end
0210     
0211     if isnan(data)
0212       if strcmp(outputType,'R')
0213         data = 'NA';
0214       end
0215       
0216     elseif isnumeric(data)
0217       % Check whether we have datatype info and this is actually a logical
0218       if haveDatatypeInfo && strcmp(outputType,'R') && strcmp(datatype{l},'logical')
0219         if data
0220           data = 'TRUE';
0221         else
0222           data = 'FALSE';
0223         end
0224       else
0225         data = num2str(data);
0226       end
0227       
0228     elseif islogical(data)
0229       if strcmp(outputType,'R')
0230         if ~data
0231           data = 'FALSE';
0232         else
0233           data = 'TRUE';
0234         end
0235       else
0236         data = num2str(data);
0237       end
0238     end
0239     
0240     if l > 1, inputstr = [inputstr delim]; end
0241     
0242     if encloseCommas && any(data == ',')
0243       data = sprintf('"%s"',data);
0244     end
0245     
0246     inputstr = [inputstr data];
0247   end
0248 
0249   % print to screen and/or file
0250   if print2screen, fprintf(1,'%s\n',inputstr); end
0251   if fid, fprintf(fid,'%s\n',inputstr); end
0252 end % for k=1:length(indata.data{1
0253 
0254 %% clean up?
0255 % print a few extra line endings
0256 if print2screen, fprintf(1,'\n\n'); end
0257 if fid, fprintf(1,'\n\n'); end
0258 
0259 % if this call opened a file id, we should close it
0260 if parent, fclose(fid); end

Generated on Wed 20-Sep-2023 04:00:50 by m2html © 2003