annotate toolboxes/MIRtoolbox1.3.2/MIRToolbox/mirstat.m @ 0:cc4b1211e677 tip

initial commit to HG from Changeset: 646 (e263d8a21543) added further path and more save "camirversion.m"
author Daniel Wolff
date Fri, 19 Aug 2016 13:07:06 +0200
parents
children
rev   line source
Daniel@0 1 function varargout = mirstat(f,varargin)
Daniel@0 2 % stat = mirstat(f) returns basic statistics of the feature f as a
Daniel@0 3 % structure array stat such that:
Daniel@0 4 % stat.Mean is the mean of the feature;
Daniel@0 5 % stat.Std is the standard deviation;
Daniel@0 6 % stat.Slope is the linear slope of the curve;
Daniel@0 7 % stat.PeriodFreq is the frequency (in Hz) of the main periodicity;
Daniel@0 8 % stat.PeriodAmp is the normalized amplitude of the main periodicity;
Daniel@0 9 % stat.PeriodEntropy is the entropy of the periodicity curve.
Daniel@0 10 % The main periodicity and periodicity curve are evaluated through the
Daniel@0 11 % computation of the autocorrelation sequence related to f.
Daniel@0 12 %
Daniel@0 13 % f can be itself a structure array composed of features. In this case,
Daniel@0 14 % stat will be structured the same way.
Daniel@0 15 %
Daniel@0 16 % mirstat does not work for multi-channels objects.
Daniel@0 17
Daniel@0 18 if isa(f,'mirstruct')
Daniel@0 19 varargout = {set(f,'Stat',1)};
Daniel@0 20 elseif isstruct(f)
Daniel@0 21 if isdesign(f)
Daniel@0 22 f.Stat = 1;
Daniel@0 23 varargout = {f};
Daniel@0 24 else
Daniel@0 25 fields = fieldnames(f);
Daniel@0 26 for i = 1:length(fields)
Daniel@0 27 field = fields{i};
Daniel@0 28 ff = f.(field);
Daniel@0 29 if iscell(ff) && isa(ff{1},'mirdata')
Daniel@0 30 ff = ff{1};
Daniel@0 31 end
Daniel@0 32 if isa(ff,'mirdata')
Daniel@0 33 if i == 1
Daniel@0 34 la = get(ff,'Label');
Daniel@0 35 if not(isempty(la) || isempty(la{1}))
Daniel@0 36 stat.Class = la;
Daniel@0 37 end
Daniel@0 38 end
Daniel@0 39 ff = set(ff,'Label','');
Daniel@0 40 end
Daniel@0 41 stat.(field) = mirstat(ff,'FileNames',0);
Daniel@0 42 end
Daniel@0 43 if isempty(varargin)
Daniel@0 44 f0 = f;
Daniel@0 45 while isstruct(f0)
Daniel@0 46 fields = fieldnames(f0);
Daniel@0 47 f0 = f0.(fields{1});
Daniel@0 48 end
Daniel@0 49 if iscell(f0)
Daniel@0 50 f0 = f0{1};
Daniel@0 51 end
Daniel@0 52 stat.FileNames = get(f0,'Name');
Daniel@0 53 end
Daniel@0 54 varargout = {stat};
Daniel@0 55 end
Daniel@0 56 elseif iscell(f)
Daniel@0 57 if 0 %ischar(f{1})
Daniel@0 58 varargout = {f};
Daniel@0 59 else
Daniel@0 60 res = zeros(length(f),1);
Daniel@0 61 for i = 1:length(f)
Daniel@0 62 res(i) = mirstat(f{i});
Daniel@0 63 end
Daniel@0 64 varargout = {res};
Daniel@0 65 end
Daniel@0 66 elseif isnumeric(f)
Daniel@0 67 f(isnan(f)) = [];
Daniel@0 68 varargout = {mean(f)};
Daniel@0 69 else
Daniel@0 70 alongfiles.key = 'AlongFiles';
Daniel@0 71 alongfiles.type = 'Boolean';
Daniel@0 72 alongfiles.default = 0;
Daniel@0 73 option.alongfiles = alongfiles;
Daniel@0 74
Daniel@0 75 filenames.key = 'FileNames';
Daniel@0 76 filenames.type = 'Boolean';
Daniel@0 77 filenames.default = 1;
Daniel@0 78 option.filenames = filenames;
Daniel@0 79
Daniel@0 80 specif.option = option;
Daniel@0 81
Daniel@0 82 specif.nochunk = 1;
Daniel@0 83 varargout = mirfunction(@mirstat,f,varargin,nargout,specif,@init,@main);
Daniel@0 84 end
Daniel@0 85
Daniel@0 86
Daniel@0 87 function [x type] = init(x,option)
Daniel@0 88 type = '';
Daniel@0 89
Daniel@0 90
Daniel@0 91 function stat = main(f,option,postoption)
Daniel@0 92 if iscell(f)
Daniel@0 93 f = f{1};
Daniel@0 94 end
Daniel@0 95 if isa(f,'mirhisto')
Daniel@0 96 warning('WARNING IN MIRSTAT: histograms are not taken into consideration yet.')
Daniel@0 97 stat = struct;
Daniel@0 98 return
Daniel@0 99 end
Daniel@0 100 fp = get(f,'FramePos');
Daniel@0 101 if haspeaks(f)
Daniel@0 102 ppp = get(f,'PeakPrecisePos');
Daniel@0 103 if not(isempty(ppp)) && not(isempty(ppp{1}))
Daniel@0 104 stat = addstat(struct,ppp,fp,'PeakPos');
Daniel@0 105 stat = addstat(stat,get(f,'PeakPreciseVal'),fp,'PeakMag');
Daniel@0 106 else
Daniel@0 107 if isa(f,'mirkeystrength') || (isa(f,'mirchromagram') && get(f,'Wrap'))
Daniel@0 108 stat = struct; % This needs to be defined using some kind of circular statistics..
Daniel@0 109 else
Daniel@0 110 stat = addstat(struct,get(f,'PeakPosUnit'),fp,'PeakPos');
Daniel@0 111 end
Daniel@0 112 stat = addstat(stat,get(f,'PeakVal'),fp,'PeakMag');
Daniel@0 113 end
Daniel@0 114 else
Daniel@0 115 stat = addstat(struct,get(f,'Data'),fp,'',option.alongfiles,...
Daniel@0 116 get(f,'Name'),get(f,'Label'));
Daniel@0 117 end
Daniel@0 118 if option.filenames
Daniel@0 119 stat.FileNames = get(f,'Name');
Daniel@0 120 end
Daniel@0 121
Daniel@0 122
Daniel@0 123 function stat = addstat(stat,d,fp,field,alongfiles,filename,labels)
Daniel@0 124 l = length(d);
Daniel@0 125 if nargin<5
Daniel@0 126 alongfiles = 0;
Daniel@0 127 end
Daniel@0 128 if nargin<7
Daniel@0 129 labels = {};
Daniel@0 130 end
Daniel@0 131 if not(alongfiles) || l == 1
Daniel@0 132 anyframe = 0;
Daniel@0 133 for i = 1:l
Daniel@0 134 if not(iscell(d{i}))
Daniel@0 135 d{i} = {d{i}};
Daniel@0 136 end
Daniel@0 137 for k = 1:length(d{i})
Daniel@0 138 dd = d{i}{k};
Daniel@0 139 if iscell(dd)
Daniel@0 140 if length(dd)>1
Daniel@0 141 anyframe = 1;
Daniel@0 142 end
Daniel@0 143 dn = cell2array(dd);
Daniel@0 144 [m{i}{k},s{i}{k},sl{i}{k},pa{i}{k},pf{i}{k},pe{i}{k}] ...
Daniel@0 145 = computestat(dn,fp{i}{k});
Daniel@0 146 elseif size(dd,2) < 2
Daniel@0 147 nonan = find(not(isnan(dd)));
Daniel@0 148 dn = dd(nonan);
Daniel@0 149 if isempty(dn)
Daniel@0 150 m{i}{k} = NaN;
Daniel@0 151 else
Daniel@0 152 m{i}{k} = mean(dn,2);
Daniel@0 153 end
Daniel@0 154 s{i}{k} = NaN;
Daniel@0 155 sl{i}{k} = NaN;
Daniel@0 156 pa{i}{k} = NaN;
Daniel@0 157 pf{i}{k} = NaN;
Daniel@0 158 pe{i}{k} = NaN;
Daniel@0 159 else
Daniel@0 160 anyframe = 1;
Daniel@0 161 s1 = size(dd,1);
Daniel@0 162 s3 = size(dd,3);
Daniel@0 163 dd = mean(dd,4); %mean(dd,3),4);
Daniel@0 164 m{i}{k} = NaN(s1,1,s3);
Daniel@0 165 s{i}{k} = NaN(s1,1,s3);
Daniel@0 166 sl{i}{k} = NaN(s1,1,s3);
Daniel@0 167 pa{i}{k} = NaN(s1,1,s3);
Daniel@0 168 pf{i}{k} = NaN(s1,1,s3);
Daniel@0 169 pe{i}{k} = NaN(s1,1,s3);
Daniel@0 170 for h = 1:s3
Daniel@0 171 for j = 1:s1
Daniel@0 172 [m{i}{k}(j,1,h),s{i}{k}(j,1,h),sl{i}{k}(j,1,h),...
Daniel@0 173 pa{i}{k}(j,1,h),pf{i}{k}(j,1,h),pe{i}{k}(j,1,h)] = ...
Daniel@0 174 computestat(dd(j,:,h),fp{i}{k});
Daniel@0 175 end
Daniel@0 176 end
Daniel@0 177 end
Daniel@0 178 end
Daniel@0 179 end
Daniel@0 180 if anyframe
Daniel@0 181 fields = {'Mean','Std','Slope','PeriodFreq','PeriodAmp','PeriodEntropy'};
Daniel@0 182 stats = {m,s,sl,pf,pa,pe};
Daniel@0 183 else
Daniel@0 184 fields = {'Mean'};
Daniel@0 185 stats = {m};
Daniel@0 186 end
Daniel@0 187 for i = 1:length(stats)
Daniel@0 188 data = stats{i};
Daniel@0 189 data = uncell(data,NaN);
Daniel@0 190 stat.(strcat(field,fields{i})) = data;
Daniel@0 191 end
Daniel@0 192 else
Daniel@0 193 if iscell(d{1}{1})
Daniel@0 194 slash = strfind(filename{1},'/');
Daniel@0 195 nbfolders = 1;
Daniel@0 196 infolder = 0;
Daniel@0 197 foldername{1} = filename{1}(1:slash(end)-1);
Daniel@0 198 for i = 1:length(d)
Daniel@0 199 slash = strfind(filename{i},'/');
Daniel@0 200 if not(strcmpi(filename{i}(1:slash(end)-1),foldername))
Daniel@0 201 nbfolders = nbfolders + 1;
Daniel@0 202 infolder = 0;
Daniel@0 203 foldername{nbfolders} = filename{i}(1:slash(end)-1);
Daniel@0 204 end
Daniel@0 205 infolder = infolder+1;
Daniel@0 206 dd{nbfolders}(infolder,:) = cell2array(d{i}{1});
Daniel@0 207 end
Daniel@0 208 for i = 1:length(dd)
Daniel@0 209 figure
Daniel@0 210 plot(dd{i}')
Daniel@0 211 stat.Mean{i} = mean(dd{i});
Daniel@0 212 stat.Std{i} = std(dd{i});
Daniel@0 213 end
Daniel@0 214 end
Daniel@0 215 end
Daniel@0 216 if not(isempty(labels) || isempty(labels{1}))
Daniel@0 217 stat.Class = labels;
Daniel@0 218 end
Daniel@0 219
Daniel@0 220
Daniel@0 221 function dn = cell2array(dd)
Daniel@0 222 dn = zeros(1,length(dd));
Daniel@0 223 for j = 1:length(dd)
Daniel@0 224 if isempty(dd{j})
Daniel@0 225 dn(j) = NaN;
Daniel@0 226 else
Daniel@0 227 dn(j) = dd{j}(1);
Daniel@0 228 end
Daniel@0 229 end
Daniel@0 230
Daniel@0 231
Daniel@0 232 function [m,s,sl,pa,pf,pe] = computestat(d,fp)
Daniel@0 233 m = NaN;
Daniel@0 234 s = NaN;
Daniel@0 235 sl = NaN;
Daniel@0 236 pa = NaN;
Daniel@0 237 pf = NaN;
Daniel@0 238 pe = NaN;
Daniel@0 239 diffp = fp(1,2:end) - fp(1,1:end-1);
Daniel@0 240 if isempty(diffp) || sum(round((diffp(2:end)-diffp(1:end-1))*1000))
Daniel@0 241 % Not regular sampling (in mirattacktime for instance)
Daniel@0 242 framesampling = NaN;
Daniel@0 243 else
Daniel@0 244 framesampling = fp(1,2)-fp(1,1);
Daniel@0 245 end
Daniel@0 246 nonan = find(not(isnan(d)));
Daniel@0 247 if not(isempty(nonan))
Daniel@0 248 dn = d(nonan);
Daniel@0 249 m = mean(dn,2);
Daniel@0 250 s = std(dn,0,2);
Daniel@0 251 if not(isnan(s))
Daniel@0 252 if s
Daniel@0 253 dk = (dn-m)/s;
Daniel@0 254 tk = linspace(0,1,size(d,2));
Daniel@0 255 sl = dk(:)'/tk(nonan);
Daniel@0 256 elseif size(s,2) == 1
Daniel@0 257 s = NaN;
Daniel@0 258 end
Daniel@0 259 end
Daniel@0 260 if length(dn)>1
Daniel@0 261 cor = xcorr(dn',dn','coeff');
Daniel@0 262 cor = cor(ceil(length(cor)/2):end);
Daniel@0 263 % let's zero the first descending slope of the
Daniel@0 264 % autocorrelation function
Daniel@0 265 firstmin = find(cor(2:end)>cor(1:end-1));
Daniel@0 266 if not(isempty(firstmin) || isnan(framesampling))
Daniel@0 267 cor2 = cor;
Daniel@0 268 cor2(1:firstmin(1)) = 0;
Daniel@0 269 [pa,pfk] = max(cor2);
Daniel@0 270 if pfk > 1
Daniel@0 271 pf = 1/(pfk-1)/framesampling;
Daniel@0 272 end
Daniel@0 273 end
Daniel@0 274 cor = abs(cor);
Daniel@0 275 cor = cor/sum(cor);
Daniel@0 276 pe = -sum(cor.*log(cor+1e-12))./log(length(cor));
Daniel@0 277 end
Daniel@0 278 end
Daniel@0 279
Daniel@0 280
Daniel@0 281 function b = isdesign(f)
Daniel@0 282 if iscell(f)
Daniel@0 283 f = f{1};
Daniel@0 284 end
Daniel@0 285 if isa(f,'mirdesign') || isa(f,'mirstruct')
Daniel@0 286 b = 1;
Daniel@0 287 elseif isa(f,'mirdata') || not(isstruct(f))
Daniel@0 288 b = 0;
Daniel@0 289 else
Daniel@0 290 fields = fieldnames(f);
Daniel@0 291 b = isdesign(f.(fields{1}));
Daniel@0 292 end