classdef SignalObj < handle
properties (SetAccess = private)
name
time
data
dimension
minTime
maxTime
xlabelval
xunits
yunits
dataLabels
dataMask
sampleRate
plotProps
end
properties (Hidden)
origSampleRate
originalTime
originalData
end
methods
function s=SignalObj(time, data, name, xlabelval, xunits, yunits, dataLabels, plotProps)
if(nargin<6)
yunits='';
end
if(nargin<5)
xunits='s';
end
if(nargin<4)
xlabelval='time';
end
if(nargin<3)
name='';
end
[l,w]=size(time);
if(l>=w)
if(w>1)
error('Time vector can only have one dimension');
else
s.time=time;
end
elseif(l<=w)
if(l>1)
error('Time vector can only have one dimension');
else
s.time=time';
end
end
s.originalTime=s.time;
[l,w]=size(data);
if(l==length(s.time));
s.data=data;
s.dimension =w;
elseif(w==length(s.time))
s.data=data';
s.dimension=l;
else
error('Data dimensions do not match the time vector specified');
end
s.originalData = s.data;
if(nargin <7)
if(s.dimension==0)
dataLabels ='';
else
for i=1:s.dimension
dataLabels{i} = '';
end
end
end
s.dataMask = ones(1,s.dimension);
if(nargin<8)
plotProps = cell(s.dimension,1);
end
deltaT=mean(diff(s.time));
if(~isfinite(deltaT) || deltaT<=0)
deltaT=0.001;
end
s.sampleRate = 1/deltaT;
s.origSampleRate = s.sampleRate;
s.name=name;
s.xlabelval=xlabelval;
s.xunits=xunits;
s.yunits=yunits;
s.minTime=min(s.time);
s.maxTime=max(s.time);
s.setPlotProps(plotProps);
s.setDataLabels(dataLabels);
end
function setName(sObj,name)
if(isa(name,'char'))
sObj.name = name;
else
error('Name must be a string!');
end
end
function setXlabel(sObj,name)
sObj.xlabelval = name;
end
function setYLabel(sObj,name)
sObj.setName(name);
end
function setUnits(sObj, xUnits, yUnits)
if(nargin==3)
if(isa(yUnits,'char'))
sObj.setYunits(yUnits);
end
end
if(nargin>=2)
if(isa(xUnits,'char'))
sObj.setXunits(xUnits);
end
end
end
function setXUnits(sObj, units)
if(isa(units, 'char'))
sObj.xunits = units;
end
end
function setYUnits(sObj, units)
if(isa(units,'char'))
sObj.yunits = units;
end
end
function setSampleRate(sObj, sampleRate)
if(sObj.sampleRate~=sampleRate)
if(~(floor(sampleRate*1000)/1000==floor(sObj.sampleRate*1000)/1000))
if(sampleRate>sObj.sampleRate)
else
end
sObj.resampleMe(sampleRate);
end
end
end
function setDataLabels(sObj,dataLabels)
if(~isempty(dataLabels))
if(isa(dataLabels,'char'))
if(sObj.dimension==1)
sObj.dataLabels{1}=dataLabels;
else
display('Adding single dataLabel to a SignalObj with more that 1 dimension. All dimensions have same label now!');
for i=1:sObj.dimension
sObj.dataLabels{i} = dataLabels;
end
end
elseif(isa(dataLabels,'cell'))
if(length(dataLabels)==sObj.dimension)
sObj.dataLabels = dataLabels;
else
error('Need the number of labels to match the number of dimensions of the SignalObj');
end
end
else
if(sObj.dimension==1)
sObj.dataLabels='';
else
for i=1:sObj.dimension
sObj.dataLabels{i}='';
end
end
end
end
function setMinTime(sObj,minTime,holdVals)
if(nargin<3)
holdVals=0;
end
if(nargin<2)
minTime=sObj.time(1);
end
timeVec=sObj.getTime;
if(minTime<min(timeVec))
maxTime=max(timeVec);
newTime=minTime:1/sObj.sampleRate:maxTime;
newTime=newTime';
numSamples = length(newTime)-length(timeVec);
if(holdVals==1)
newData=[ones(numSamples,1)*sObj.data(1,:);sObj.data];
else
newData=[zeros(numSamples,sObj.dimension);sObj.data];
end
sObj.data=newData;
sObj.time=newTime;
sObj.minTime=min(sObj.time);
elseif(min(timeVec)==minTime)
else
startIndex = sObj.findNearestTimeIndex(minTime);
sObj.time=sObj.time(startIndex:end);
sObj.data=sObj.data(startIndex:end,:);
end
sObj.minTime=min(sObj.time);
end
function setMaxTime(sObj,maxTime, holdVals)
if(nargin<3)
holdVals=0;
end
if(nargin<2)
maxTime=sObj.time(end);
end
timeVec=sObj.getTime;
if(max(timeVec)<maxTime)
minTime=min(timeVec);
newTime=linspace(minTime,maxTime,(sObj.sampleRate)*(maxTime-minTime)+1);
newTime = newTime';
numSamples = length(newTime)-length(timeVec);
if(holdVals==1)
newData=[sObj.data;ones(numSamples,1)*sObj.data(end,:)];
else
newData=[sObj.data;zeros(numSamples,sObj.dimension)];
end
sObj.data=newData;
sObj.time=newTime;
sObj.maxTime=max(sObj.time);
elseif(max(timeVec)==maxTime)
else
endIndex = sObj.findNearestTimeIndex(maxTime);
sObj.time=sObj.time(1:endIndex);
sObj.data=sObj.data(1:endIndex,:);
end
sObj.maxTime=max(sObj.time);
end
function setPlotProps(sObj, plotProps,index)
if(nargin<=2)
if(isa(plotProps,'cell'))
if(length(plotProps) == sObj.dimension)
for i=1:sObj.dimension
sObj.plotProps{i} = cell2str(plotProps{i});
end
elseif(length(plotProps)==1)
for i=1:sObj.dimension
sObj.plotProps{i} = cell2str(plotProps);
end
else
error('Index not specified and more than 1 plotProp specified. Need to number of plotProps same as sObj.dimension or length 1');
end
elseif(isa(plotProps,'char'))
for i=1:sObj.dimension
sObj.plotProps{i} = cell2str(plotProps);
end
display('All dimensions set to have same plotting properties')
end
else
if(isa(plotProps,'cell') && length(plotProps)==1)
if(index>0 && index<=sObj.dimension)
sObj.plotProps{index} = plotProps{:};
else
error('Index out of bounds during setPlotProps');
end
elseif(isa(plotProps,'char'))
if(index>0 && index<=sObj.dimension)
sObj.plotProps{index} = plotProps;
else
error('Index out of bounds during setPlotProps');
end
end
end
end
function setMask(sObj, mask)
if(nargin<2)
mask=zeros(1,sObj.dimension);
sObj.setDataMask(mask);
return;
end
if(isa(mask,'cell'))
if(isa(mask{1},'char'))
sObj.setMaskByLabels(mask);
else
error('Mask cells must contains strings!');
end
elseif(isa(mask,'double'))
sObj.setMaskByInd(mask);
else
error('Can only set datamask with strings or indices')
end
end
function tVec = getTime(sObj)
tVec=sObj.time;
end
function data = getData(sObj)
data=sObj.dataToMatrix;
end
function [t,d] = getOriginalData(sObj)
t=sObj.originalTime;
d=sObj.originalData;
end
function s = getOrigDataSig(sObj)
[time,data]=sObj.getOriginalData;
name=sObj.name;
xlabelval=sObj.xlabelval;
xunits=sObj.xunits;
yunits=sObj.yunits;
dataLabels=sObj.dataLabels;
plotProps=sObj.plotProps;
ctorHandle = str2func(class(sObj));
s = ctorHandle(time, data,name, xlabelval, xunits, yunits,dataLabels,plotProps);
end
function val = getValueAt(sObj,x)
[l,w]=size(x);
if(w>l)
x=x';
end
val = interp1(sObj.time,sObj.data,x,'nearest',0);
end
function PropsStr = getPlotProps(sObj,index)
if(index>0 && index<=sObj.dimension)
PropsStr = cell2str(sObj.plotProps{index});
else
error('index is out of bounds!');
end
end
function indices = getIndicesFromLabels(sObj,label)
if(isa(label,'cell'))
indices =cell(1,length(label));
numInd =zeros(1,length(label));
for i=1:length(label)
tempInd = sObj.getIndexFromLabel(label{i});
if(~isempty(tempInd))
numInd(i) = length(tempInd);
indices{i}=tempInd;
else
error('Label does not exist!');
end
end
elseif(isa(label,'char'))
indices = sObj.getIndexFromLabel(label);
numInd(1) = length(indices);
end
if(max(numInd)==1)
if(isa(indices,'cell'))
for i=1:length(numInd)
tempInd(i) = indices{i};
end
indices = tempInd;
end
end
end
function s3 = plus(s1,s2)
if(isa(s1,'SignalObj') && isa(s2,'SignalObj'))
if(s1.dimension == s2.dimension)
[s1c,s2c] = makeCompatible(s1,s2);
s3=s1c.copySignal;
s3.data = s1c.data+s2c.data;
for i=1:length(s3.dataLabels)
if(~s2c.areDataLabelsEmpty && ~isempty(s2c.dataLabels{i}))
if(strcmp(s2c.dataLabels{i}(1),'-'))
s3.dataLabels{i} = [s1c.dataLabels{i} '-' s2c.dataLabels{i}(2:end)];
else
s3.dataLabels{i} = [s1c.dataLabels{i} '+' s2c.dataLabels{i}];
end
end
end
else
error('Can only add signals if they have the same dimension');
end
elseif(isa(s1,'double') || isa(s2,'double'))
if(isa(s1,'double'))
s3=s2.copySignal;
[l,w] = size(s1);
if(w==s3.dimension && l==1)
s3.data = s3.data+ones(length(s3.data),1)*s1;
for i=1:length(s3.dataLabels)
if(sign(s1(i))==-1)
s3.dataLabels{i} = [s2.dataLabels{i} '-' num2str(abs(s1(i)))];
else
s3.dataLabels{i} = [s2.dataLabels{i} '+' num2str(abs(s1(i)))];
end
end
else
s3.data = s3.data+s1;
end
else
s3=s1.copySignal;
[l,w] = size(s2);
if(w==s3.dimension && l==1)
s3.data = s3.data+ones(length(s3.data),1)*s2;
for i=1:length(s3.dataLabels)
if(sign(s2(i))==-1)
s3.dataLabels{i} = [s1.dataLabels{i} '-' num2str(abs(s2(i)))];
else
s3.dataLabels{i} = [s1.dataLabels{i} '+' num2str(abs(s2(i)))];
end
end
else
s3.data = s3.data+s2;
end
end
else
error('only Signals or doubles are currently supported');
end
end
function s3 = minus(s1,s2)
s3=plus(s1,-s2);
end
function s3 = uplus(s1)
s3=s1.copySignal;
end
function s3 = uminus(s1)
s3=s1.copySignal;
s3.data=-s3.data;
for i=1:length(s3.dataLabels)
s3.dataLabels{i} = strcat('-',s1.dataLabels{i});
end
end
function s3 = power(s1,exponent)
if(isa(exponent,'double'))
s3=s1.copySignal;
s3.data=s3.data.^exponent;
else
error('Exponent should be a double');
end
end
function s3 = sqrt(s1)
s3=s1.copySignal;
s3.data=sqrt(s3.data);
end
function s3 = times(s1,s2)
if(isa(s1,'SignalObj') && isa(s2,'SignalObj'))
if(s1.dimension == s2.dimension)
[s1c,s2c] = makeCompatible(s1,s2);
s3 = s1c;
s3.data = s1c.data.*s2c.data;
else
error('can only multiply signals with same dimension');
end
elseif(isa(s1,'double') || isa(s2,'double'))
if(isa(s1,'double'))
s3=s2.copySignal;
[l,w] = size(s1);
if(w==s3.dimension && l==1)
s3.data = s3.data.*(ones(length(s3.data),1)*s1);
else
s3.data = s3.data.*s1;
end
else
s3=s1.copySignal;
[l,w] = size(s2);
if(w==s3.dimension && l==1)
s3.data = s3.data.*(ones(length(s3.data),1)*s2);
else
s3.data = s3.data.*s2;
end
end
end
end
function s3 = mtimes(s1,s2)
if(isa(s1,'SignalObj') && isa(s2,'SignalObj'))
s3 = s1.copySignal;
s3.data = s1.data.*s2.data;
elseif(isa(s1,'double') || isa(s2,'double'))
if(isa(s1,'double'))
s3=s2.copySignal;
s3.data = (s1*s3.data')';
else
s3=s1.copySignal;
s3.data = (s3.data'*s2)';
end
end
end
function s3 = rdivide(s1,s2)
if(isa(s1,'SignalObj') && isa(s2,'SignalObj'))
if(s1.dimension == s2.dimension)
[s1c,s2c] = makeCompatible(s1,s2);
s3 = s1c;
s3.data = s1c.data./s2c.data;
else
error('can only multiply signals with same dimension');
end
elseif(isa(s1,'double') || isa(s2,'double'))
if(isa(s1,'double'))
s3=s2.copySignal;
s3.data = s1./s3.data;
else
s3=s1.copySignal;
s3.data = s3.data./s2;
end
end
end
function s3 = ldivide(s1,s2)
if(isa(s1,'SignalObj') && isa(s2,'SignalObj'))
if(s1.dimension == s2.dimension)
[s1c,s2c] = makeCompatible(s1,s2);
s3 = s1c;
s3.data = s1c.data.\s2c.data;
else
error('can only multiply signals with same dimension');
end
elseif(isa(s1,'double') || isa(s2,'double'))
if(isa(s1,'double'))
s3=s2.copySignal;
s3.data = s1.\s3.data;
else
s3=s1.copySignal;
s3.data = s3.data.\s2;
end
end
end
function s3 = ctranspose(s1)
s3=s1.copySignal;
s3.data=s3.data.';
[l,w]=size(s3.data);
s3.dimension=w;
end
function s3 = transpose(s1)
s3=s1.copySignal;
s3.data=s3.data.';
[l,w]=size(s3.data);
s3.dimension=w;
end
function s3 = derivative(sObj)
s3=sObj.copySignal;
tData=diff(s3.data)*s3.sampleRate;
tData=[zeros(1,s3.dimension); tData];
s3.data=tData;
s3.setYUnits(strcat('\frac{',s3.yunits,'}{',s3.xunits,'}'));
denomstr = strcat('d', s3.xlabelval(1));
s3.setName(strcat('\frac{d}{',denomstr,'}',s3.name));
for i=1:s3.dimension
if(s3.dimension ==1)
if(~strcmp(sObj.dataLabels,''))
s3.dataLabels{i}= strcat('\frac{d}{',denomstr,'}',s3.dataLabels);
end
else
if(~strcmp(sObj.dataLabels{i},''))
s3.dataLabels{i}= strcat('\frac{d}{',denomstr,'}',s3.dataLabels{i});
end
end
end
end
function val = derivativeAt(sObj,x0)
sTemp = sObj.derivative;
val = sTemp.getValueAt(x0);
end
function s3 = integral(sObj,t0,tf)
if(nargin<3)
tf=sObj.maxTime;
end
if(nargin<2)
t0=sObj.minTime;
end
B=1*1/sObj.sampleRate;
A=[1 -1];
s3=sObj.getSigInTimeWindow(t0,tf);
s3=s3.filter(B,A);
s3.setYUnits(strcat(s3.yunits,'*',s3.xunits));
dtstr = strcat(' d','\tau');
s3.setName(['\int_',num2str(s3.minTime),'^',s3.xlabelval(1),'\!\!{',[s3.name dtstr],'}']);
if(~sObj.areDataLabelsEmpty)
for i=1:s3.dimension
if(~strcmp(sObj.dataLabels{i},''))
s3.dataLabels{i}= ['\int_',num2str(s3.minTime),'^',s3.xlabelval(1),'\!\!{',[s3.dataLabels{i} dtstr],'}'];
else
s3.dataLabels{i} = '';
end
end
end
end
function s3 = filter(sObj, B,A)
s3=sObj.copySignal;
s3.data = filter(B,A,s3.data);
end
function s3 = filtfilt(sObj,B,A)
s3=sObj.copySignal;
s3.data = filtfilt(B,A,s3.data);
end
function [s1c,s2c] = makeCompatible(s1,s2,holdVals)
if(nargin<3)
holdVals=0;
end
if(s1.minTime~=s2.minTime || s1.maxTime~=s2.maxTime || s1.sampleRate ~=s2.sampleRate)
s1c = s1.copySignal; s2c = s2.copySignal;
minTime=min(s1c.minTime,s2c.minTime);
maxTime=max(s1c.maxTime,s2c.maxTime);
sampleRate=max(s1c.sampleRate,s2c.sampleRate);
s1c.setSampleRate(sampleRate); s2c.setSampleRate(sampleRate);
s1c.setMinTime(minTime,holdVals); s2c.setMinTime(minTime,holdVals);
s1c.setMaxTime(maxTime,holdVals); s2c.setMaxTime(maxTime,holdVals);
data = interp1(s2c.time,s2c.data,s1c.time,'nearest',0);
s2c.time = s1c.time;
[nrows,ncolumns] = size(data);
if(nrows>ncolumns)
s2c.data = data;
else
s2c.data = data';
end
else
s1c = s1;
s2c = s2;
end
end
function s = abs(sObj)
absData=abs(sObj.data);
[nrows,ncolumns]=size(absData);
name = ['|', sObj.name '|'];
plotProps = sObj.plotProps;
if(~sObj.areDataLabelsEmpty)
dataLabels = cell(size(sObj.dataLabels));
for i=1:sObj.dimension
dataLabels{i} = strcat('|',sObj.dataLabels{i},'|');
end
evalstring = strcat('s=',class(sObj),'(sObj.time, absData,name,sObj.xlabelval, sObj.xunits,sObj.yunits,dataLabels,plotProps);');
else
evalstring = strcat('s=',class(sObj),'(sObj.time, absData,name,sObj.xlabelval, sObj.xunits,sObj.yunits,[],plotProps);');
end
eval(evalstring);
end
function s = log(sObj)
logData=log(sObj.data);
[nrows,ncolumns]=size(logData);
name = ['ln(' sObj.name ')'];
yunits = ['ln(' sObj.yunits ')'];
plotProps = sObj.plotProps;
if(~sObj.areDataLabelsEmpty)
dataLabels = cell(size(sObj.dataLabels));
for i=1:sObj.dimension
dataLabels{i} = strcat('ln(',sObj.dataLabels{i},')');
end
evalstring = strcat('s=',class(sObj),'(sObj.time, logData,name,sObj.xlabelval, sObj.xunits,yunits,dataLabels,plotProps);');
else
evalstring = strcat('s=',class(sObj),'(sObj.time, logData,name,sObj.xlabelval, sObj.xunits,yunits,[],plotProps);');
end
eval(evalstring);
end
function m=median(sObj,varargin)
mdata=median(sObj.data,varargin{:});
[nrows,ncolumns]=size(mdata);
if( (nrows==length(sObj.time)) && (ncolumns==1) )
name = ['median(', sObj.name ')'];
evalstring = strcat('m=',class(sObj),'(sObj.time, mdata,name,sObj.xlabelval, sObj.xunits,sObj.yunits);');
eval(evalstring);
elseif( (nrows==1) && (ncolumns == sObj.dimension) )
if(~sObj.areDataLabelsEmpty)
dataLabels = cell(size(sObj.dataLabels));
for i=1:sObj.dimension
dataLabels{i} = strcat('median(',sObj.dataLabels{i},')');
end
name = ['median(', sObj.name ')'];
evalstring = strcat('m=',class(sObj),'([sObj.time(1); sObj.time(end)], [mdata;mdata],name,sObj.xlabelval, sObj.xunits,sObj.yunits,dataLabels);');
eval(evalstring);
else
name = ['median(', sObj.name ')'];
evalstring = strcat('m=',class(sObj),'([sObj.time(1); sObj.time(end)], [mdata;mdata],name,sObj.xlabelval, sObj.xunits,sObj.yunits);');
eval(evalstring);
end
end
end
function m=mode(sObj,varargin)
mdata=mode(sObj.data,varargin{:});
[nrows,ncolumns]=size(mdata);
if( (nrows==length(sObj.time)) && (ncolumns==1) )
name = ['mode(', sObj.name ')'];
evalstring = strcat('m=',class(sObj),'(sObj.time, mdata,name,sObj.xlabelval, sObj.xunits,sObj.yunits);');
eval(evalstring);
elseif( (nrows==1) && (ncolumns == sObj.dimension) )
if(~sObj.areDataLabelsEmpty)
dataLabels = cell(size(sObj.dataLabels));
for i=1:sObj.dimension
dataLabels{i} = strcat('mode(',sObj.dataLabels{i},')');
end
name = ['mode(', sObj.name ')'];
evalstring = strcat('m=',class(sObj),'([sObj.time(1); sObj.time(end)], [mdata;mdata],name,sObj.xlabelval, sObj.xunits,sObj.yunits,dataLabels);');
eval(evalstring);
else
name = ['mode(', sObj.name ')'];
evalstring = strcat('m=',class(sObj),'([sObj.time(1); sObj.time(end)], [mdata;mdata],name,sObj.xlabelval, sObj.xunits,sObj.yunits);');
eval(evalstring);
end
end
end
function m=mean(sObj,varargin)
mdata=mean(sObj.data,varargin{:});
[nrows,ncolumns]=size(mdata);
if( (nrows==length(sObj.time)) && (ncolumns==1) )
name = ['\mu(', sObj.name ')'];
evalstring = strcat('m=',class(sObj),'(sObj.time, mdata,name,sObj.xlabelval, sObj.xunits,sObj.yunits);');
eval(evalstring);
elseif( (nrows==1) && (ncolumns == sObj.dimension) )
if(~sObj.areDataLabelsEmpty)
dataLabels = cell(size(sObj.dataLabels));
for i=1:sObj.dimension
dataLabels{i} = strcat('\mu(',sObj.dataLabels{i},')');
end
name = ['\mu(', sObj.name ')'];
evalstring = strcat('m=',class(sObj),'([sObj.time(1); sObj.time(end)], [mdata;mdata],name,sObj.xlabelval, sObj.xunits,sObj.yunits,dataLabels);');
eval(evalstring);
else
name = ['\mu(', sObj.name ')'];
evalstring = strcat('m=',class(sObj),'([sObj.time(1); sObj.time(end)], [mdata;mdata],name,sObj.xlabelval, sObj.xunits,sObj.yunits);');
eval(evalstring);
end
end
end
function m=std(sObj,varargin)
stdData=std(sObj.data,varargin{:});
[nrows,ncolumns]=size(stdData);
if( (nrows==length(sObj.time)) && (ncolumns==1) )
name=['\sigma(' sObj.name ')'];
evalstring = strcat('m=',class(sObj),'(sObj.time, stdData,name,sObj.xlabelval, sObj.xunits,sObj.yunits);');
eval(evalstring);
elseif( (nrows==1) && (ncolumns == sObj.dimension) )
if(~sObj.areDataLabelsEmpty)
dataLabels = cell(size(sObj.dataLabels));
for i=1:sObj.dimension
dataLabels{i} = strcat('\sigma(',sObj.dataLabels{i},')');
end
name=['\sigma(' sObj.name ')'];
evalstring = strcat('m=',class(sObj),'([sObj.time(1); sObj.time(end)], [stdData;stdData],name,sObj.xlabelval, sObj.xunits,sObj.yunits,dataLabels);');
eval(evalstring);
else
name=['\sigma(' sObj.name ')'];
evalstring = strcat('m=',class(sObj),'([sObj.time(1); sObj.time(end)], [stdData;stdData],name,sObj.xlabelval, sObj.xunits,sObj.yunits);');
eval(evalstring);
end
end
end
function [m, index,time]=max(sObj,varargin)
[m,index]=max(sObj.data,varargin{:});
time = sObj.time(index);
end
function [m,index,time]=min(sObj,varargin)
[m,index]=min(sObj.data,varargin{:});
time = sObj.time(index);
end
function s = autocorrelation(sObj)
if(sObj.dimension==1)
[ACF,lags,bounds] = crosscorr(sObj.data,sObj.data,length(sObj.data)-1);
s=SignalObj(lags/sObj.sampleRate, ACF,['ACF(' sObj.name, ')'], 'Lag', sObj.xunits, [sObj.yunits '^2']);
else
for i=1:sObj.dimension
[ACF(:,i),lags,bounds] = crosscor(sObj.data(:,i),sObj.data(:,i),length(sObj.data(:,i))-1);
end
s=SignalObj(lags/sObj.sampleRate, ACF,['ACF(' sObj.name, ')'], 'Lag', sObj.xunits, [sObj.yunits '^2']);
end
end
function s = crosscorrelation(sObj, s2)
if(and(sObj.dimension ==1, s2.dimension==1))
[xcf,lags,bounds] = crosscorr(sObj.data, s2.data,length(sObj.data)-1);
s=SignalObj(lags/sObj.sampleRate, xcf,['XCORF(' sObj.name, ')'], 'Lag', sObj.xunits, [sObj.yunits '^2']);
else
error('Does not support multidimensional signals');
end
end
function periodogram = periodogram(sObj)
fs = sObj.sampleRate;
periodogram = cell(1,sObj.dimension);
for i=1:sObj.dimension
xn = sObj.data(:,i);
Hs = spectrum.periodogram('rectangular');
switch sObj.dimension
case 2
subplot(1,2,i)
case 3
subplot(1,3,i)
case 4
subplot(2,2,i)
case 5
subplot(3,2,i)
case 6
subplot(3,2,i)
otherwise
h=gcf;figure(h);
end
periodogram{i}=psd(Hs,xn,'Fs',fs,'NFFT',1024);
if(~isempty(sObj.dataLabels))
h=periodogram{i}.plot;legend(h, sObj.dataLabels{i});
else
h=periodogram{i}.plot;
end
end
end
function mtmSpec = MTMspectrum(sObj,NW,NFFT,Pval)
if(nargin<4)
Pval=.95;
end
if(nargin<3)
NFFT=[];
end
if(nargin<2)
NW=4;
end
Fs=sObj.sampleRate;
mtmSpec = cell(1,sObj.dimension);
for i=1:sObj.dimension
xn=sObj.data(:,i);
[Pxx,Pxxc,f] = pmtm(xn,NW,NFFT,Fs,Pval);
hpsd = dspdata.psd([Pxx Pxxc],'Fs',Fs);
mtmSpec{i} = hpsd;
switch sObj.dimension
case 2
subplot(1,2,i)
case 3
subplot(1,3,i)
case 4
subplot(2,2,i)
case 5
subplot(3,2,i)
case 6
subplot(3,2,i)
otherwise
h=gcf;figure(h);
end
str1=strcat(num2str(Pval*100), '% Conf. Int.');
h=plot(hpsd); legend(h, sObj.dataLabels{i},strcat('-',str1),strcat('+',str1));
end
end
function [spectrogramData,h] = spectrogram(sObj,freqVec,h)
if(nargin<3 ||isempty(h))
h=figure;
end
if(nargin<2 || isempty(freqVec))
freqVec=0:.1:50;
end
t=sObj.time;
x=sObj.data;
F = freqVec;
window=kaiser(round(length(t)/20));
nooverlap = round(round(length(t)/40));
clear y f t p;
for i=1:sObj.dimension
[y{i},f{i},t{i},p{i}] = spectrogram(x(:,i),window,nooverlap,F,sObj.sampleRate);
t{i} = t{i}+min(sObj.time);
surf(t{i},f{i},10*log10(abs(p{i})),'EdgeColor','none');
axis xy; axis tight; colormap(jet); view(0,90);
xlabel('time [s]');
ylabel('frequency [Hz]');
end
if(sObj.dimension>1)
for i=1:sObj.dimension
spectrogramData{i}.t = t{i};
spectrogramData{i}.f = f{i};
spectrogramData{i}.p = p{i};
spectrogramData{i}.y = y{i};
end
else
spectrogramData.t = t{i};
spectrogramData.f = f{i};
spectrogramData.p = p{i};
spectrogramData.y = y{i};
end
end
function sxCorr= xcorr(s1,s2,varargin)
if(nargin<2)
s2=s1;
end
[s1c,s2c] = makeCompatible(s1,s2);
if(~isempty(varargin))
[tempC tempLags] =xcorr([s1c.data, s2c.data],varargin{1});
else
[tempC tempLags] =xcorr([s1c.data, s2c.data]);
end
index=[];
for i=1:s1c.dimension
offset(i)=(i-1)*(s1c.dimension+s2c.dimension);
index = [index, (offset(i)+s1c.dimension+1):(offset(i)+s1c.dimension+s2c.dimension)];
end
sum=0;
dataLabels = cell(1,length(index));
for i=1:s1c.dimension
for j=1:s2c.dimension
sum = sum+1;
dataLabels{sum} = strcat('corr(',s1c.dataLabels{i},',',s2c.dataLabels{j}, ']');
end
end
M=length(s1c.data);
if(nargin<2)
data=tempC(M-1:end,index);
lags=tempLags(M-1:end)./s1c.sampleRate;
else
data=tempC(1:end,index);
lags=tempLags(1:end)./s1c.sampleRate;
end
name = [ 'corr(' s1.name ',' s2.name ')'];
evalstring=strcat('sxCorr=',class(s1),'(lags,data,name,''\Delta \tau'',''s'',dataLabels);');
eval(evalstring);
end
function sxCov = xcov(s1,s2,varargin)
if(nargin<2)
s2=s1;
end
[s1c,s2c] = makeCompatible(s1,s2);
if(~isempty(varargin))
[tempC tempLags] =xcov([s1c.data, s2c.data],varargin{1});
else
[tempC tempLags] =xcov([s1c.data, s2c.data]);
end
index=[];
for i=1:s1c.dimension
offset(i)=(i-1)*(s1c.dimension+s2c.dimension);
index = [index, (offset(i)+s1c.dimension+1):(offset(i)+s1c.dimension+s2c.dimension)];
end
sum=0;
dataLabels = cell(1,length(index));
for i=1:s1c.dimension
for j=1:s2c.dimension
sum = sum+1;
dataLabels{sum} = strcat('cov(',s1c.dataLabels{i},',',s2c.dataLabels{j}, ']');
end
end
M=length(s1c.data);
if(nargin<2)
data=tempC(M-1:end,index);
lags=tempLags(M-1:end)./s1c.sampleRate;
else
data=tempC(1:end,index);
lags=tempLags(1:end)./s1c.sampleRate;
end
name = [ 'cov(' s1.name ',' s2.name ')'];
evalstring=strcat('sxCov=',class(s1),'(lags,data,name,''\Delta \tau'',''s'',dataLabels);');
eval(evalstring);
end
function mergedSig = merge(sObj,varargin)
numToMerge=0;
holdVals=0;
for i=1:length(varargin)
if(isa(varargin{i},'SignalObj'))
numToMerge = numToMerge+1;
end
if(isa(varargin{i},'double')&&i==length(varargin))
holdVals = varargin{i};
end
end
if(numToMerge == 1)
[s1c, s2c] = sObj.makeCompatible(varargin{1},holdVals);
data=[s1c.dataToMatrix, s2c.dataToMatrix];
dataLabels = cell(s1c.dimension+s2c.dimension,1);
for i=1:s1c.dimension
dataLabels{i} = s1c.dataLabels{i};
end
for i=1:s2c.dimension
dataLabels{s1c.dimension+i}=s2c.dataLabels{i};
end
name = s1c.name;
evalstring = strcat('mergedSig = ',class(sObj),'(s1c.time, data, name, s1c.xlabelval,s1c.xunits, s1c.yunits, dataLabels);');
eval(evalstring);
else
mergedSig = sObj.merge(varargin{1},holdVals);
for i=2:numToMerge
mergedSig = mergedSig.merge(varargin{i},holdVals);
end
end
end
function sigOut=copySignal(sigIn)
time=sigIn.time;
data=sigIn.data;
name=sigIn.name;
xlabelval=sigIn.xlabelval;
xunits=sigIn.xunits;
yunits=sigIn.yunits;
dataLabels=sigIn.dataLabels;
plotProps=sigIn.plotProps;
evalstring = strcat('sigOut=',class(sigIn),'(time, data,name, xlabelval, xunits, yunits,dataLabels,plotProps);');
eval(evalstring);
sigOut.dataMask = sigIn.dataMask;
end
function sObjOut=resample(sObj, newSampleRate)
if(sObj.sampleRate ~=newSampleRate)
sObjOut = sObj.copySignal;
if(or(~isnan(sObjOut.sampleRate),size(sObjOut.data,1)>1))
sObjOut.resampleMe(newSampleRate);
end
else
sObjOut = sObj.copySignal;
end
end
function resampleMe(sObj, newSampleRate)
if(sObj.sampleRate~=newSampleRate)
sObj.restoreToOriginal;
minTime=sObj.minTime;
maxTime=sObj.maxTime;
newTime=minTime:1/newSampleRate:maxTime;
newData=zeros(length(newTime),sObj.dimension);
if(size(sObj.data,1)>1)
for i=1:sObj.dimension
newData(:,i)= interp1(sObj.time,sObj.data(:,i),newTime,'spline',0);
end
else
newData = sObj.data;
end
sObj.time=newTime';
sObj.data=newData;
sObj.sampleRate=newSampleRate;
end
end
function restoreToOriginal(sObj,rMask)
if(nargin<2)
rMask = 0;
end
[time,data]=sObj.getOriginalData;
sObj.time=time;
sObj.data=data;
sObj.minTime=min(time);
sObj.maxTime=max(time);
sObj.sampleRate = 1/mean(diff(time));
if(rMask==1)
sObj.resetMask;
end
end
function resetMask(sObj)
sObj.dataMask = ones(1,sObj.dimension);
end
function ind = findIndFromDataMask(sObj)
ind = find(sObj.dataMask ==1);
end
function ind = findNearestTimeIndices(sObj,times)
ind = zeros(size(times));
for i=1:length(ind)
ind(i) = sObj.findNearestTimeIndex(times(i));
end
end
function ind=findNearestTimeIndex(sObj, time)
if(time<sObj.minTime)
ind=1;
elseif(time>sObj.maxTime)
ind=length(sObj.time);
else
ind1=find(sObj.time>=time,1,'first');
ind2=find(sObj.time<=time,1,'last');
if(abs(sObj.time(ind1)-time)<=abs(sObj.time(ind2)-time))
ind=ind1;
else
ind=ind2;
end
end
end
function sOut = shift(sObj, deltaT,updateLabels)
if(nargin<3)
updateLabels =0;
end
sOut=sObj.copySignal;
if(deltaT~=0)
newMinTime = sOut.minTime+deltaT;
newMaxTime = sOut.maxTime+deltaT;
newTime = sOut.time + deltaT;
sOut.time = newTime;
sOut.minTime = newMinTime;
sOut.maxTime = newMaxTime;
if(updateLabels)
dataLabels = strcat(sObj.dataLabels,'(t-',num2str(deltaT),')');
sOut.setName(strcat(sObj.name,'(t-',num2str(deltaT),')'));
sOut.setDataLabels(dataLabels);
end
end
end
function shiftMe(sObj,deltaT,updateLabels)
if(nargin<3)
updateLabels=0;
end
sTemp = sObj.shift(deltaT,updateLabels);
sObj.data=sTemp.data;
sObj.time=sTemp.time;
end
function alignTime(sObj, timeMarker,newTime)
if(sObj.minTime<=timeMarker && sObj.maxTime>=timeMarker)
deltaT=newTime-timeMarker;
sObj.shiftMe(deltaT);
end
end
function answer = plotPropsSet(sObj)
answer =0;
for i=1:sObj.dimension
if(~strcmp(sObj.getPlotProps(i),''))
answer=1;
break;
end
end
end
function answer = areDataLabelsEmpty(sObj)
answer = 1;
for i=1:length(sObj.dataLabels);
if(~strcmp(sObj.dataLabels{i},''))
answer = 0;
break;
end
end
end
function answer = isLabelPresent(sObj, label)
if(isa(label,'char'))
if(strcmp(label,'all')||~isempty(sObj.getIndexFromLabel(label)))
answer=1;
else
answer=0;
end
else
error('Labels must be a char');
end
end
function answer = isMaskSet(sObj)
answer=any(sObj.dataMask==0);
end
function sArray = convertNamesToIndices(sObj, selectorArray)
if(sObj.areDataLabelsEmpty)
sArray = 1:sObj.dimension;
fprintf('tried to find data by labels but data doesnot have labels assigned');
else
if(isa(selectorArray, 'char'))
if(strcmp(selectorArray,'all'))
sArray=1:sObj.dimension;
elseif(sObj.isLabelPresent(selectorArray))
sArray=sObj.getIndexFromLabel(selectorArray);
else
error('Specified label does not match data label');
end
elseif(isa(selectorArray, 'double'))
sArray=selectorArray;
elseif(isa(selectorArray, 'cell'))
sArray = zeros(1, length(selectorArray));
for i=1:length(sArray)
if(sObj.isLabelPresent(selectorArray{i}))
sArray(i) = sObj.getIndexFromLabel(selectorArray{i});
end
end
else
error('selectorArray cells must contain text');
end
end
end
function [sAligned,meanTime] = alignToMax(sObj)
[indices,values] = sObj.findGlobalPeak('maxima');
meanTime = mean(indices);
deltaT = -(indices-meanTime);
for i=1:sObj.dimension
if(i==1)
sAligned = sObj.getSubSignal(i).shift(deltaT(i));
else
sAligned = sAligned.merge(sObj.getSubSignal(i).shift(deltaT(i)));
end
end
end
function [ind, val] = findGlobalPeak(sObj,type)
if(nargin<2)
type='maxima';
end
if(strcmp(type,'maxima'))
[val,index] = max(sObj.data);
ind = sObj.time(index);
elseif(strcmp(type,'minima'))
[val,index] = min(sOBj.data);
ind = sObj.time(index);
end
end
function [indices, values] = findPeaks(sObj,type,minDistance)
if(nargin<3)
minDistance = round(sObj.sampleRate*(sObj.maxTime-sObj.minTime)/10);
end
if(nargin<2)
type='maxima';
end
values=cell(1,sObj.dimension);
indices=cell(1,sObj.dimension);
if(strcmp(type,'maxima'))
for i=1:sObj.dimension
[values{i},indices{i}] = findpeaks(sObj.data(:,i),'MINPEAKDISTANCE',minDistance);
end
elseif(strcmp(type,'minima'))
for i=1:sObj.dimension
[values{i},indices{i}] = findpeaks(sObj.data(:,i),'MINPEAKDISTANCE',minDistance);
end
end
end
function [indices, values] = findMaxima(sObj)
[indices,values]=sObj.findPeaks('maxima');
end
function [indices, values] = findMinima(sObj)
[indices,values]= sObj.findPeaks('minima');
end
function clearPlotProps(sObj,index)
if(nargin<2)
index=1:sObj.dimension;
end
tempCell = cell(length(index),1);
for i=index
sObj.plotProps{i} = cell2str(tempCell{i});
end
end
function structure=dataToStructure(sObj,selectorArray)
if(nargin<2)
if(sObj.isMaskSet)
selectorArray=sObj.findIndFromDataMask;
else
selectorArray=1:sObj.dimension;
end
end
structure.time=sObj.time;
structure.signals.values=sObj.dataToMatrix(selectorArray);
structure.name = sObj.name;
structure.dimension = min(sObj.dimension,length(selectorArray));
structure.signals.dimensions = min(sObj.dimension,length(selectorArray));
structure.minTime = sObj.minTime;
structure.maxTime = sObj.maxTime;
structure.xlabelval = sObj.xlabelval;
structure.xunits = sObj.xunits;
structure.yunits = sObj.yunits;
if(isa(sObj.dataLabels,'char'))
structure.dataLabels = sObj.dataLabels;
elseif(isa(sObj.dataLabels,'cell'))
structure.dataLabels = sObj.dataLabels(selectorArray);
else
structure.dataLabels = [];
end
structure.dataMask = sObj.dataMask(selectorArray);
structure.sampleRate = sObj.sampleRate;
structure.plotProps = sObj.plotProps(selectorArray);
end
function dataMat=dataToMatrix(sObj,selectorArray)
if(nargin<2)
if(sObj.isMaskSet)
selectorArray=sObj.findIndFromDataMask;
else
selectorArray=1:sObj.dimension;
end
end
dataMat=sObj.data(:,selectorArray);
end
function sOut = getSubSignal(sObj,identifier)
if(isa(identifier,'cell'))
if(isa(identifier{1},'char'))
sOut = sObj.getSubSignalFromNames(identifier);
elseif(isa(identifier{1},'double'))
sOut = sObj.getSubSignalFromInd(identifier);
else
error('Cells must contain strings!');
end
elseif(isa(identifier,'char'))
sOut = sObj.getSubSignalFromNames(identifier);
elseif(isa(identifier,'double'))
sOut = sObj.getSubSignalFromInd(identifier);
end
end
function sOut = normWindowedSignal(sObj,windowTimes,numPoints,lbound,ubound)
if(nargin<5)
if(nargin>4)
ubound = lbound;
else
ubound = [];
end
end
if(nargin<4 || isempty(lbound));
lbound=[];
end
if(nargin<3 || isempty(numPoints))
numPoints =100;
end
if(sObj.dimension == 1)
data=[];
for i=1:length(windowTimes)-1
minTime = windowTimes(i);
maxTime = windowTimes(i+1);
if(and(~isempty(lbound),~isempty(ubound)))
if(and(abs(maxTime-minTime)<=(ubound),abs(maxTime-minTime)>=(lbound)))
dim=size(data,2);
time = linspace(minTime,maxTime,numPoints);
actSig= sObj.getSigInTimeWindow(minTime, maxTime);
data(:,dim+1) = interp1(actSig.time,actSig.data,time,'nearest',0)';
end
else
time = linspace(minTime,maxTime,numPoints);
actSig= sObj.getSigInTimeWindow(minTime, maxTime);
data(:,i) = interp1(actSig.time,actSig.data,time,'nearest',0)';
end
end
actTime = (0:1:numPoints-1)./numPoints;
name = sObj.name;
xlabelval = sObj.xlabelval;
xunits = '%';
yunits = sObj.yunits;
dataLabels(1:size(data,2)) =sObj.dataLabels;
evalstring = strcat('sOut=',class(sObj),'(actTime, data,name, xlabelval, xunits, yunits,dataLabels);');
eval(evalstring);
end
end
function sOut = windowedSignal(sObj,windowTimes)
if(sObj.dimension == 1)
for i=1:length(windowTimes)-1
if(i==1)
sOut = sObj.getSigInTimeWindow(windowTimes(1), windowTimes(2));
else
temp =sObj.getSigInTimeWindow(windowTimes(i), windowTimes(i+1));
temp = temp.shift(-windowTimes(i));
sOut=sOut.merge(temp);
end
end
end
end
function wSignals = getSigInTimeWindow(sObj,wMin,wMax,holdVals)
if(nargin<4)
holdVals =0;
end
if(nargin<3)
wMax=sObj.maxTime;
end
if(nargin<2)
wMin=sObj.minTime;
end
if(length(wMin)~=length(wMax))
error('Window minTimes must contain the same number of elements as window maxTimes');
end
if(length(wMin)==1 && sObj.minTime==wMin && sObj.maxTime==wMax)
wSignals = sObj.copySignal;
else
for i=1:length(wMin)
wSignal = sObj.copySignal;
if(wMin(i)<wSignal.minTime)
wSignal.setMinTime(wMin(i),holdVals);
end
if(wMax(i)>wSignal.maxTime)
wSignal.setMaxTime(wMax(i),holdVals);
end
startIndex= wSignal.findNearestTimeIndex(wMin(i));
endIndex = wSignal.findNearestTimeIndex(wMax(i));
wSignal.time=wSignal.time(startIndex:endIndex);
wSignal.data=wSignal.data(startIndex:endIndex,:);
if(length(wMin)>1)
for j=1:wSignal.dimension
dataLabels{j} = strcat(wSignal.dataLabels{j},'_{',num2str(i),'}');
end
else
if(wSignal.dimension==1)
dataLabels = wSignal.dataLabels;
else
for j=1:wSignal.dimension
dataLabels{j} = wSignal.dataLabels{j};
end
end
end
wSignal.setDataLabels(dataLabels);
wSignal.setMinTime;
wSignal.setMaxTime;
if(i==1)
wSignals = wSignal;
else
wSignals = wSignals.merge(wSignal);
end
end
end
end
function [s sigIndex]=getSubSignalsWithinNStd(sObj,nStd)
mSig=mean(sObj.data,2);
stdSig = std(sObj.data,0,2);
minVal = mSig-nStd*stdSig;
maxVal = mSig+nStd*stdSig;
indMin= find(sum(sObj.data-minVal*ones(1,sObj.dimension)<0)==0);
indMax=find(sum(sObj.data-maxVal*ones(1,sObj.dimension)>0)==0);
sigIndex = intersect(indMin,indMax);
s=sObj.getSubSignal(sigIndex);
end
function h=plot(sObj,selectorArray,plotPropsIn,handle)
if(nargin<4)
handle=gca;
end
if((nargin<3) || isempty(plotPropsIn))
plotPropsIn=sObj.plotProps;
end
if((nargin<2) || isempty(selectorArray))
if(sObj.isMaskSet)
selectorArray=sObj.findIndFromDataMask;
if(isempty(selectorArray))
h=[];
return;
end
else
selectorArray=1:sObj.dimension;
end
end
if(isa(selectorArray,'cell'))
sArray = sObj.convertNamesToIndices(selectorArray);
elseif(isa(selectorArray,'char'))
sArray = sObj.convertNamesToIndices(selectorArray);
elseif(isa(selectorArray,'double'))
sArray = selectorArray;
else
error('selectorArray must contain either dataLabels or their indices');
end
if(length(plotPropsIn)==length(sArray))
for i=1:length(sArray)
sObj.setPlotProps(plotPropsIn{i},sArray(i));
end
elseif(length(plotPropsIn)<=length(sArray) && length(plotPropsIn)==1)
for i=1:length(sArray)
sObj.setPlotProps(plotPropsIn,sArray(i));
end
end
if((nargin>=3) && ~isempty(plotPropsIn))
for i=sArray
plotStr=cell2str(sObj.getPlotProps(i));
if(~strcmp(plotStr,'') && ~isempty(plotStr))
evalstring = strcat('h(',num2str(find(sArray==i)),')=plot(handle,sObj.time,sObj.data(:,',num2str(i),'),', plotStr,');');
eval(evalstring); hold on;
else
axes(handle);
evalstring = strcat('h(',num2str(find(sArray==i)),')=plot(sObj.time,sObj.data(:,',num2str(i),'));');
eval(evalstring); hold on;
end
end
elseif(sObj.plotPropsSet)
for i=sArray
plotStr =cell2str(sObj.getPlotProps(i));
if(~strcmp(plotStr,'') && ~isempty(plotStr))
evalstring = strcat('h(',num2str(i),')=plot(handle,sObj.time,sObj.data(:,',num2str(i),'),', plotStr,');');
else
evalstring = strcat('h(',num2str(i),')=plot(handle,sObj.time,sObj.data(:,',num2str(i),'));');
end
if(~isempty(sObj.data(:,i)))
eval(evalstring); hold on;
end
end
else
set(gcf,'CurrentAxes',handle);
h=plot(handle,sObj.time,sObj.data(:,sArray));
end
sObj.setupPlots(handle,sArray);
end
function setupPlots(sObj,handle,sArray)
warning off;
if(~strcmp(sObj.xunits,''))
xunitsStr=strcat('\; [',sObj.xunits,']');
else
xunitsStr='';
end
if(~strcmp(sObj.yunits,''))
yunitsStr=strcat('\; [',sObj.yunits,']');
else
yunitsStr='';
end
if(strcmp(sObj.xlabelval,''))
xlabel(strcat('$$',xunitsStr,'$$'),'Interpreter','latex');
else
xlabel(strcat('$$',[sObj.xlabelval xunitsStr],'$$'),'Interpreter','latex');
end
if(~strcmp(sObj.name,''))
if(~strcmp(yunitsStr,''))
ylabel(strcat('$$',[sObj.name yunitsStr],'$$'),'Interpreter','latex');
else
ylabel(strcat('$$',sObj.name,'$$'),'Interpreter','latex');
end
end
if(~sObj.areDataLabelsEmpty)
rawLabels = sObj.dataLabels(sArray);
labelArray = cell(1,length(rawLabels));
for i=1:length(rawLabels)
currLabel = rawLabels{i};
while iscell(currLabel) && numel(currLabel)==1
currLabel = currLabel{1};
end
if isstring(currLabel)
currLabel = char(currLabel);
elseif isnumeric(currLabel) || islogical(currLabel)
currLabel = num2str(currLabel);
elseif ~ischar(currLabel)
currLabel = '';
end
if isempty(currLabel)
currLabel = sprintf('Signal %d',sArray(i));
end
labelArray{i} = currLabel;
end
legend(handle,labelArray);
end
axis tight;
warning on;
end
function h=plotVariability(sObj,selectorArray)
if(nargin<2)
if(~sObj.areDataLabelsEmpty)
uLabels =unique(sObj.dataLabels);
for i=1:length(uLabels)
selectorArray{i} = sObj.getIndicesFromLabels(uLabels{i});
end
else
selectorArray = 1:sObj.dimension;
end
end
if(isa(selectorArray,'cell'))
[numSubSignals]=length(selectorArray);
for i=1:numSubSignals
h(i)=sObj.getSubSignal(selectorArray{i}).plotAllVariability(getAvailableColor(i));
end
elseif(isa(selectorArray,'double'))
h=sObj.getSubSignal(selectorArray).plotAllVariability;
end
end
function h=plotAllVariability(sObj,faceColor,linewidth,ciUpper,ciLower)
if(nargin<4 || isempty(ciUpper))
ciUpper =1.96;
end
if(nargin<=4)
ciLower=ciUpper;
end
if(nargin<2 || isempty(faceColor))
faceColor=getAvailableColor(1);
end
if(nargin<3 || isempty(linewidth))
linewidth=3;
end
meanSig = mean(sObj,2);
stdSig = std(sObj,[],2);
if(length(ciUpper)==1)
ciTop=meanSig+ciUpper.*stdSig;
elseif(length(ciUpper)==length(sObj.time))
ciTop=meanSig+ciUpper;
else
error('Upper confidence interval must be either length 1 or same length as the time vector');
end
if(length(ciLower)==1)
ciBottom=meanSig-ciLower.*stdSig;
elseif(length(ciUpper)==length(sObj.time))
ciBottom=meanSig-ciLower;
else
error('Lower confidence interval must be either length 1 or same length as the time vector');
end
ci2=ciTop.dataToMatrix;
ci1=ciBottom.dataToMatrix;
p=patch([reshape(sObj.time,[1 length(sObj.time)]) reshape(fliplr(sObj.time'),[1 length(sObj.time)])],...
[reshape(ci1',[1 length(sObj.time)]) reshape(fliplr(ci2'),[1,length(sObj.time)])],strcat('',faceColor,''));
set(p,'facecolor',faceColor,'edgecolor','none');
alpha(.5);hold on;
h=plot(sObj.time,meanSig.dataToMatrix,'k-','linewidth',linewidth);
sArray=1;
meanSig.setupPlots(sArray);
end
end
methods (Access = private)
function index = getIndexFromLabel(sObj,label)
index=[];
for i=1:length(sObj.dataLabels)
if(strcmp(label, sObj.dataLabels{i}))
index = [index i];
end
end
end
function setDataMask(sObj, dataMask)
if(length(dataMask)==sObj.dimension)
sObj.dataMask = dataMask;
end
end
function setMaskByInd(sObj,index)
if(length(index)==sObj.dimension)
sObj.setDataMask(index);
else
mask=zeros(1,sObj.dimension);
mask(index)=1;
sObj.setDataMask(mask);
end
end
function setMaskByLabels(sObj,labels)
ind=sObj.getIndicesFromLabels(labels);
mask=zeros(1,sObj.dimension);
mask(ind)=1;
sObj.setDataMask(mask);
end
function sOut = getSubSignalFromInd(sObj, selectorArray)
if(nargin<2)
if(sObj.isDataMaskSet)
selectorArray=sObj.findIndFromDataMask;
else
selectorArray=1:sObj.dimension;
end
end
s3 = sObj.copySignal;
time = s3.time;
if(isa(selectorArray,'cell'))
data=[];
for i=1:length(selectorArray)
offset=0;
data = [data s3.data(:,selectorArray{i})];
for j=1:length(selectorArray{i})
dataLabels{offset + j} = s3.dataLabels{selectorArray{i}(j)};
if(~isempty(s3.plotProps))
plotProps{offset+ j} = s3.plotProps{selectorArray{i}(j)};
end
end
offset = offset + length(selectorArray{i});
end
else
data = s3.data(:,selectorArray);
dataLabels = cell(1,length(selectorArray));
plotProps = [];
for i=1:length(selectorArray)
dataLabels{i}= s3.dataLabels{selectorArray(i)};
if(~isempty(s3.plotProps))
plotProps{i} = s3.plotProps{selectorArray(i)};
end
end
end
name = s3.name;
xlabelval = s3.xlabelval; xunits=s3.xunits; yunits = s3.yunits;
evalstring = strcat('sOut=',class(sObj),'(time, data,name, xlabelval, xunits, yunits,dataLabels,plotProps);');
eval(evalstring);
end
function sOut = getSubSignalFromNames(sObj,labels)
ind = sObj.getIndicesFromLabels(labels);
if(isa(ind,'cell'))
if(length(ind)>1)
for i=1:length(ind)
s{i} = getSubSignalFromInd(ind{i});
end
sOut = s{1}.merge(s{2:end});
else
sOut = sObj.getSubSignalFromInd(ind{1});
end
elseif(isa(ind,'double'))
sOut = sObj.getSubSignalFromInd(ind);
end
end
end
methods (Static)
function sObj =signalFromStruct(structure)
fNames = {'time','signals','name','xlabelval','xunits','yunits','dataLabels','plotProps'};
structField = fields(structure);
for i=1:length(fNames)
if(~any(strcmp(structField,fNames{i})))
error(['Field ' fNames{i} 'not present is structure! Needed to make a signal from a structure']);
end
end
sObj=SignalObj(structure.time, structure.signals.values, structure.name, structure.xlabelval, structure.xunits, structure.yunits, structure.dataLabels, structure.plotProps);
sObj.setMask(structure.dataMask);
end
function simpleStructure = convertSigStructureToStructure(sigStructure)
if(isa(sigStructure,'struct'))
fNames = fields(sigStructure);
for i=1:length(fNames)
if(isa(sigStructure.(fNames{i}),'SignalObj'))
simpleStructure.(fNames{i}) = sigStructure.(fNames{i}).dataToStructure;
end
end
end
end
function sigStructure = convertSimpleStructureToSigStructure(simpleStructure)
if(isa(simpleStructure,'struct'))
fNames = fields(simpleStructure);
for i=1:length(fNames)
if(isa(simpleStructure.(fNames{i}),'struct'))
sigStructure.(fNames{i}) = SignalObj.signalFromStruct(simpleStructure.(fNames{i}));
end
end
end
end
end
end
function stringout=cell2str(input)
if(isempty(input))
stringout = '';
else
if(isa(input,'char'))
stringout=input;
elseif(isa(input,'cell'))
stringout=cell2str(input{1});
end
end
end
function color=getAvailableColor(index)
availableColors = {'g','b','r','y','c','m','k'};
color=availableColors{mod(index,length(availableColors))+1};
end