diff toolboxes/MIRtoolbox1.3.2/MIRToolbox/mirstat.m @ 0:e9a9cd732c1e tip

first hg version after svn
author wolffd
date Tue, 10 Feb 2015 15:05:51 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/toolboxes/MIRtoolbox1.3.2/MIRToolbox/mirstat.m	Tue Feb 10 15:05:51 2015 +0000
@@ -0,0 +1,292 @@
+function varargout = mirstat(f,varargin)
+% stat = mirstat(f) returns basic statistics of the feature f as a
+%   structure array stat such that:
+%       stat.Mean is the mean of the feature;
+%       stat.Std is the standard deviation;
+%       stat.Slope is the linear slope of the curve;
+%       stat.PeriodFreq is the frequency (in Hz) of the main periodicity;
+%       stat.PeriodAmp is the normalized amplitude of the main periodicity;
+%       stat.PeriodEntropy is the entropy of the periodicity curve.
+%   The main periodicity and periodicity curve are evaluated through the
+%       computation of the autocorrelation sequence related to f.
+%
+%   f can be itself a structure array composed of features. In this case,
+%       stat will be structured the same way.
+%
+% mirstat does not work for multi-channels objects.
+
+if isa(f,'mirstruct')
+    varargout = {set(f,'Stat',1)};
+elseif isstruct(f)
+    if isdesign(f)
+        f.Stat = 1;
+        varargout = {f};
+    else
+        fields = fieldnames(f);
+        for i = 1:length(fields)
+            field = fields{i};
+            ff = f.(field);
+            if iscell(ff) && isa(ff{1},'mirdata')
+                ff = ff{1};
+            end
+            if isa(ff,'mirdata')
+                if i == 1 
+                    la = get(ff,'Label');
+                    if not(isempty(la) || isempty(la{1}))
+                        stat.Class = la;
+                    end
+                end
+                ff = set(ff,'Label','');
+            end
+            stat.(field) = mirstat(ff,'FileNames',0);
+        end
+        if isempty(varargin)
+            f0 = f;
+            while isstruct(f0)
+                fields = fieldnames(f0);
+                f0 = f0.(fields{1});
+            end
+            if iscell(f0)
+                f0 = f0{1};
+            end
+            stat.FileNames = get(f0,'Name');
+        end
+        varargout = {stat};
+    end
+elseif iscell(f)
+    if 0 %ischar(f{1})
+        varargout = {f};
+    else
+        res = zeros(length(f),1);
+        for i = 1:length(f)
+            res(i) = mirstat(f{i});
+        end
+        varargout = {res};
+    end
+elseif isnumeric(f)
+    f(isnan(f)) = [];
+    varargout = {mean(f)};
+else
+            alongfiles.key = 'AlongFiles';
+            alongfiles.type = 'Boolean';
+            alongfiles.default = 0;
+        option.alongfiles = alongfiles;
+
+            filenames.key = 'FileNames';
+            filenames.type = 'Boolean';
+            filenames.default = 1;
+        option.filenames = filenames;
+        
+    specif.option = option;
+
+    specif.nochunk = 1;
+    varargout = mirfunction(@mirstat,f,varargin,nargout,specif,@init,@main);
+end
+
+
+function [x type] = init(x,option)
+type = '';
+
+
+function stat = main(f,option,postoption)
+if iscell(f)
+    f = f{1};
+end
+if isa(f,'mirhisto')
+    warning('WARNING IN MIRSTAT: histograms are not taken into consideration yet.')
+    stat = struct;
+    return
+end
+fp = get(f,'FramePos');
+if haspeaks(f)
+    ppp = get(f,'PeakPrecisePos');
+    if not(isempty(ppp)) && not(isempty(ppp{1}))
+        stat = addstat(struct,ppp,fp,'PeakPos');
+        stat = addstat(stat,get(f,'PeakPreciseVal'),fp,'PeakMag');
+    else
+        if isa(f,'mirkeystrength') || (isa(f,'mirchromagram') && get(f,'Wrap'))
+            stat = struct; % This needs to be defined using some kind of circular statistics..
+        else
+            stat = addstat(struct,get(f,'PeakPosUnit'),fp,'PeakPos');
+        end
+        stat = addstat(stat,get(f,'PeakVal'),fp,'PeakMag');
+    end
+else
+    stat = addstat(struct,get(f,'Data'),fp,'',option.alongfiles,...
+                          get(f,'Name'),get(f,'Label'));
+end
+if option.filenames
+    stat.FileNames = get(f,'Name');
+end
+
+
+function stat = addstat(stat,d,fp,field,alongfiles,filename,labels)
+l = length(d);
+if nargin<5
+    alongfiles = 0;
+end
+if nargin<7
+    labels = {};
+end
+if not(alongfiles) || l == 1
+    anyframe = 0;
+    for i = 1:l
+        if not(iscell(d{i}))
+            d{i} = {d{i}};
+        end
+        for k = 1:length(d{i})
+            dd = d{i}{k};
+            if iscell(dd)
+                if length(dd)>1
+                    anyframe = 1;
+                end
+                dn = cell2array(dd);
+                [m{i}{k},s{i}{k},sl{i}{k},pa{i}{k},pf{i}{k},pe{i}{k}] ...
+                    = computestat(dn,fp{i}{k});
+            elseif size(dd,2) < 2
+                nonan = find(not(isnan(dd)));
+                dn = dd(nonan);
+                if isempty(dn)
+                    m{i}{k} = NaN;
+                else
+                    m{i}{k} = mean(dn,2);
+                end
+                s{i}{k} = NaN;
+                sl{i}{k} = NaN;
+                pa{i}{k} = NaN;
+                pf{i}{k} = NaN;
+                pe{i}{k} = NaN;
+            else
+                anyframe = 1;
+                s1 = size(dd,1);
+                s3 = size(dd,3);
+                dd = mean(dd,4); %mean(dd,3),4);
+                m{i}{k} = NaN(s1,1,s3);
+                s{i}{k} = NaN(s1,1,s3);
+                sl{i}{k} = NaN(s1,1,s3);
+                pa{i}{k} = NaN(s1,1,s3);
+                pf{i}{k} = NaN(s1,1,s3);
+                pe{i}{k} = NaN(s1,1,s3);
+                for h = 1:s3
+                    for j = 1:s1
+                        [m{i}{k}(j,1,h),s{i}{k}(j,1,h),sl{i}{k}(j,1,h),...
+                         pa{i}{k}(j,1,h),pf{i}{k}(j,1,h),pe{i}{k}(j,1,h)] = ...
+                            computestat(dd(j,:,h),fp{i}{k});
+                    end
+                end
+            end
+        end
+    end
+    if anyframe
+        fields = {'Mean','Std','Slope','PeriodFreq','PeriodAmp','PeriodEntropy'};
+        stats = {m,s,sl,pf,pa,pe};   
+    else
+        fields = {'Mean'};
+        stats = {m};   
+    end
+    for i = 1:length(stats)
+        data = stats{i};
+        data = uncell(data,NaN);
+        stat.(strcat(field,fields{i})) = data;
+    end
+else
+    if iscell(d{1}{1})
+        slash = strfind(filename{1},'/');
+        nbfolders = 1;
+        infolder = 0;
+        foldername{1} = filename{1}(1:slash(end)-1);
+        for i = 1:length(d)
+            slash = strfind(filename{i},'/');
+            if not(strcmpi(filename{i}(1:slash(end)-1),foldername))
+                nbfolders = nbfolders + 1;
+                infolder = 0;
+                foldername{nbfolders} = filename{i}(1:slash(end)-1);
+            end
+            infolder = infolder+1;
+            dd{nbfolders}(infolder,:) = cell2array(d{i}{1});
+        end
+        for i = 1:length(dd)
+            figure
+            plot(dd{i}')
+            stat.Mean{i} = mean(dd{i});
+            stat.Std{i} = std(dd{i});
+        end
+    end
+end
+if not(isempty(labels) || isempty(labels{1}))
+    stat.Class = labels;
+end
+
+
+function dn = cell2array(dd)
+dn = zeros(1,length(dd));
+for j = 1:length(dd)
+    if isempty(dd{j})
+        dn(j) = NaN;
+    else
+        dn(j) = dd{j}(1);
+    end
+end
+
+
+function [m,s,sl,pa,pf,pe] = computestat(d,fp)
+m = NaN;
+s = NaN;
+sl = NaN;
+pa = NaN;
+pf = NaN;
+pe = NaN;
+diffp = fp(1,2:end) - fp(1,1:end-1);
+if isempty(diffp) || sum(round((diffp(2:end)-diffp(1:end-1))*1000))
+    % Not regular sampling (in mirattacktime for instance)
+    framesampling = NaN;
+else
+    framesampling = fp(1,2)-fp(1,1);
+end
+nonan = find(not(isnan(d)));
+if not(isempty(nonan))
+    dn = d(nonan);
+    m = mean(dn,2);
+    s = std(dn,0,2);
+    if not(isnan(s))
+        if s
+            dk = (dn-m)/s;
+            tk = linspace(0,1,size(d,2));
+            sl = dk(:)'/tk(nonan);
+        elseif size(s,2) == 1
+            s = NaN;
+        end
+    end
+    if length(dn)>1
+        cor = xcorr(dn',dn','coeff');
+        cor = cor(ceil(length(cor)/2):end);
+        % let's zero the first descending slope of the
+        % autocorrelation function
+        firstmin = find(cor(2:end)>cor(1:end-1));
+        if not(isempty(firstmin) || isnan(framesampling))
+            cor2 = cor;
+            cor2(1:firstmin(1)) = 0;
+            [pa,pfk] = max(cor2);
+            if pfk > 1
+                pf = 1/(pfk-1)/framesampling;
+            end
+        end
+        cor = abs(cor);
+        cor = cor/sum(cor);
+        pe = -sum(cor.*log(cor+1e-12))./log(length(cor));
+    end
+end
+
+
+function b = isdesign(f)
+if iscell(f)
+    f = f{1};
+end
+if isa(f,'mirdesign') || isa(f,'mirstruct')
+    b = 1;
+elseif isa(f,'mirdata') || not(isstruct(f))
+    b = 0;
+else
+    fields = fieldnames(f);
+    b = isdesign(f.(fields{1}));
+end
\ No newline at end of file