X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?p=CreaPhase.git;a=blobdiff_plain;f=octave_packages%2Fio-1.0.19%2Fparsecell.m;fp=octave_packages%2Fio-1.0.19%2Fparsecell.m;h=770242ae34e42ad9a8afb92b809020f27c95f001;hp=0000000000000000000000000000000000000000;hb=f5f7a74bd8a4900f0b797da6783be80e11a68d86;hpb=1705066eceaaea976f010f669ce8e972f3734b05 diff --git a/octave_packages/io-1.0.19/parsecell.m b/octave_packages/io-1.0.19/parsecell.m new file mode 100644 index 0000000..770242a --- /dev/null +++ b/octave_packages/io-1.0.19/parsecell.m @@ -0,0 +1,171 @@ +## Copyright (C) 2009,2010,2011,2012 Philip Nienhuis +## +## This program is free software; you can redistribute it and/or modify it under +## the terms of the GNU General Public License as published by the Free Software +## Foundation; either version 3 of the License, or (at your option) any later +## version. +## +## This program is distributed in the hope that it will be useful, but WITHOUT +## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +## details. +## +## You should have received a copy of the GNU General Public License along with +## this program; if not, see . + +## -*- texinfo -*- +## @deftypefn {Function File} [ @var{numarr}, @var{txtarr}, @var{lim} ] = parsecell (@var{rawarr}) +## @deftypefnx {Function File} [ @var{numarr}, @var{txtarr}, @var{lim} ] = parsecell (@var{rawarr}, @var{limits}) +## +## Divide a heterogeneous 2D cell array into a 2D numeric array and a +## 2D cell array containing only strings. Both returned arrays are +## trimmed from empty outer rows and columns. +## This function is particularly useful for parsing cell arrays returned +## by functions reading spreadsheets (e.g., xlsread, odsread). +## +## Optional return argument @var{lim} contains two field with the outer +## column and row numbers of @var{numarr} and @var{txtarr} in the +## original array @var{rawarr}. +## Optional input argument @var{limits} can either be the spreadsheet +## data limits returned in the spreadsheet file pointer struct +## (field xls.limits or ods.limits), or the file ptr struct itself. +## If one of these is specified, optional return argument @var{lim} +## will contain the real spreadsheet row & column numbers enclosing +## the origins of the numerical and text data returned in @var{numarr} +## and @var{txtarr}. +## +## Examples: +## +## @example +## [An, Tn] = parsecell (Rn); +## (which returns the numeric contents of Rn into array An and the +## text data into array Tn) +## @end example +## +## @example +## [An, Tn, lims] = parsecell (Rn, xls.limits); +## (which returns the numeric contents of Rn into array An and the +## text data into array Tn.) +## @end example +## +## @seealso {xlsread, odsread, xls2oct, ods2oct} +## +## @end deftypefn + +## Author: Philip Nienhuis +## Created: 2009-12-13 +## Updates: +## 2009-12-29 +## 2010-08-25 Added option for second argument to be a file ptr +## 2010-10-15 Simplified code for numerical array +## 2011-05-17 Fixed subscript indexing bug in cropping section when rawarr is +## " numeric scalar +## 2011-09-08 Copyright string updated +## 2012-01-26 Fixed "seealso" help string + +function [ numarr, txtarr, lim ] = parsecell (rawarr, arg2=[]) + + if (isstruct (arg2)) + # Assume a file ptr has been supplied + if (isfield (arg2, 'limits')) + rawlimits = arg2.limits; + else + warning ("Invalid file ptr supplied to parsecell() - limits ignored."); + endif + else + rawlimits = arg2; + endif + + lim = struct ( "numlimits", [], "txtlimits", []); + + numarr = []; + txtarr = {}; + + if (~isempty (rawarr)) + # Valid data returned. Divide into numeric & text arrays + no_txt = 0; no_num = 0; + if (isnumeric ([rawarr{:}])) + numarr = num2cell (rawarr); + no_txt = 1; + elseif (iscellstr (rawarr)) + txtarr = cellstr (rawarr); + no_num = 1; + endif + # Prepare parsing + [nrows, ncols] = size (rawarr); + + # Find text entries in raw data cell array + txtptr = cellfun ('isclass', rawarr, 'char'); + if (~no_txt) + # Prepare text array. Create placeholder for text cells + txtarr = cell (size (rawarr)); + txtarr(:) = {''}; + if (any (any (txtptr))) + # Copy any text cells found into place holder + txtarr(txtptr) = rawarr(txtptr); + # Clean up text array (find leading / trailing empty + # rows & columns) + irowt = 1; + while (~any (txtptr(irowt, :))) irowt++; endwhile + irowb = nrows; + while (~any (txtptr(irowb, :))) irowb--; endwhile + icoll = 1; + while (~any (txtptr(:, icoll))) icoll++; endwhile + icolr = ncols; + while (~any (txtptr(:, icolr))) icolr--; endwhile + # Crop textarray + txtarr = txtarr(irowt:irowb, icoll:icolr); + lim.txtlimits = [icoll, icolr; irowt, irowb]; + if (~isempty (rawlimits)) + correction = [1; 1]; + lim.txtlimits (:,1) = lim.txtlimits(:,1) + rawlimits(:,1) - correction; + lim.txtlimits (:,2) = lim.txtlimits(:,2) + rawlimits(:,1) - correction; + endif + else + # If no text cells found return empty text array + txtarr = {}; + endif + endif + + if (~no_num) + # Prepare numeric array. Set all text & empty cells to + # NaN. First get their locations + emptr = cellfun ('isempty', rawarr); + emptr(find (txtptr)) = 1; + if (all (all (emptr))) + numarr= []; + else + # Find leading & trailing empty rows + irowt = 1; + while (all(emptr(irowt, :))) irowt++; endwhile + irowb = nrows; + while (all(emptr(irowb, :))) irowb--; endwhile + icoll = 1; + while (all(emptr(:, icoll))) icoll++; endwhile + icolr = ncols; + while (all(emptr(:, icolr))) icolr--; endwhile + + # Pre-crop rawarr + rawarr = rawarr (irowt:irowb, icoll:icolr); + # Build numerical array + numarr = zeros (irowb-irowt+1, icolr-icoll+1); + # Watch out for scalar (non-empty) numarr where emptr = 0 + if (sum (emptr(:)) > 0) + numarr (emptr(irowt:irowb, icoll:icolr)) = NaN; + endif + numarr(~emptr(irowt:irowb, icoll:icolr)) = cell2mat (rawarr(~emptr(irowt:irowb, icoll:icolr))); + # Save limits + lim.numlimits = [icoll, icolr; irowt, irowb]; + if (~isempty (rawlimits)) + correction = [1; 1]; + lim.numlimits(:,1) = lim.numlimits(:,1) + rawlimits(:,1) - correction(:); + lim.numlimits(:,2) = lim.numlimits(:,2) + rawlimits(:,1) - correction(:); + endif + endif + endif + + lim.rawlimits = rawlimits; + + endif + +endfunction