0001 function [y,w,r]=nt_detrend(x,order,w0,basis,thresh,niter,wsize)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 nt_greetings;
0021
0022
0023 if nargin<2||isempty(order); error('!'); end
0024 if nargin<3; w0=[]; end
0025 if nargin<4||isempty(basis); basis='polynomials'; end
0026 if nargin<5||isempty(thresh); thresh=3; end
0027 if nargin<6||isempty(niter); niter=3; end
0028 if nargin<7; wsize=[]; end
0029
0030 if iscell(x)
0031 if ~isempty(w0); error('not implemented'); end
0032 y={}; w={}; r={};
0033 for iTrial=1:numel(x);
0034 [y{iTrial},w{iTrial},r{iTrial}]=nt_detrend(x{iTrial},order,w0,basis,thresh,niter,wsize);
0035 end
0036 return
0037 end
0038
0039 w=w0;
0040 if ~isempty(w)
0041 w=w(:);
0042 if numel(w)<size(x,1)
0043
0044 idx=w;
0045 w=zeros(size(x,1),1);
0046 w(idx)=1;
0047 end
0048 end
0049
0050 if isempty(wsize) || ~wsize
0051
0052 [y,w,r]=nt_detrend_helper(x,order,w,basis,thresh,niter);
0053 else
0054 wsize=2*floor(wsize/2);
0055
0056
0057 if numel(order)>1; error('!'); end
0058 if ~isempty(w) && ~(size(w,1)==size(x,1)) ; disp(size(w)); error('!'); end
0059 if ~(isempty(basis) || isstring(basis) || ~(isnumeric(basis)&&size(basis,1)==size(x,1))); error('!'); end
0060 if thresh==0; error('thresh=0 is not what you want...'); end
0061 if numel(thresh)>1; error('!'); end
0062 if numel(niter)>1; error('!'); end
0063
0064 dims=size(x); nchans=dims(2);
0065 x=x(:,:);
0066 w=w(:,:);
0067 if isempty(w); w=ones(size(x)); end
0068 if size(w,2)==1; w=repmat(w,1,size(x,2)); end
0069
0070
0071
0072
0073
0074 for iIter=1:niter
0075
0076 y=zeros(size(x));
0077 trend=zeros(size(x));
0078 a=zeros(size(x,1),1);
0079
0080
0081
0082 offset=0;
0083 while true
0084 start=offset+1;
0085 stop=min(size(x,1),offset+wsize);
0086
0087
0088 MAXGROW=1000;
0089 counter=MAXGROW;
0090 while any( sum(w(start:stop,:)) < wsize )...
0091 || any(mean(w(start:stop,:)) < 1/4)
0092 if counter <= 0 ; break; end
0093 start=max(1,start-wsize/2);
0094 stop=min(size(x,1),stop+wsize/2);
0095 counter=counter-1;
0096 end
0097 if rem(stop-start+1,2)==1; stop=stop-1; end
0098 wsize2=stop-start+1;
0099
0100
0101 NITER=1;
0102 if ~sum(w(start:stop)); error('!'); end
0103 yy=nt_detrend_helper(x(start:stop,:),order,w(start:stop,:),basis,thresh,NITER);
0104
0105
0106 if start==1
0107 b=[ones(1,wsize2/2)*wsize2/2, wsize2/2:-1:1]';
0108 elseif stop==size(x,1)
0109 b=[1:wsize2/2, ones(1,wsize2/2)*wsize2/2]';
0110 else
0111 b=[1:wsize2/2, wsize2/2:-1:1]';
0112 end
0113
0114
0115 y(start:stop,:)=y(start:stop,:)+bsxfun(@times,yy,b);
0116 trend(start:stop,:)=trend(start:stop,:)+bsxfun(@times,x(start:stop,:)-yy,b);
0117
0118 a(start:stop,1)=a(start:stop)+b;
0119
0120 offset=offset+wsize/2;
0121 if offset>size(x,1)-wsize/2; break; end
0122 end
0123
0124 if stop<size(x,1); y(end,:)=y(end-1,:); a(end,:)=a(end-1,:); end;
0125
0126 y=bsxfun(@times,y,1./a); y(find(isnan(y)))=0;
0127 trend=bsxfun(@times,trend,1./a); trend(find(isnan(trend)))=0;
0128
0129
0130 d=x-trend;
0131
0132
0133 if ~isempty(w); d=bsxfun(@times,d,w); end
0134 ww=ones(size(x));
0135 ww(find(abs(d)>thresh*repmat(std(d),size(x,1),1))) = 0;
0136 clear d
0137
0138
0139 if isempty(w);
0140 w=ww;
0141 else
0142 w=min(w,ww);
0143 end
0144 clear ww;
0145
0146 end
0147
0148 w=[];r=[];
0149
0150 end
0151
0152 if ~nargout
0153
0154 subplot 411; plot(x); title('raw'); xlim([1,size(x,1)])
0155 subplot 412; plot(y); title('detrended'); xlim([1,size(x,1)])
0156 subplot 413; plot(x-y); title('trend'); xlim([1,size(x,1)])
0157 subplot 414; nt_imagescc(w'); title('weight');
0158 clear y w r
0159 end
0160 end
0161
0162
0163 function [y,w,r]=nt_detrend_helper(x,order,w,basis,thresh,niter)
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197 nt_greetings;
0198
0199
0200 if nargin<2; error('!'); end
0201 if nargin<3; w=[]; end
0202 if nargin<4||isempty(basis); basis='polynomials'; end
0203 if nargin<5||isempty(thresh); thresh=3; end
0204 if nargin<6||isempty(niter); niter=3; end
0205
0206 if thresh==0; error('thresh=0 is not what you want...'); end
0207
0208 dims=size(x);
0209 x=x(:,:);
0210 w=w(:,:);
0211
0212 if size(w,2)==1; w=repmat(w,1,size(x,2)); end
0213
0214
0215 if isnumeric(basis)
0216 r=basis;
0217 else
0218 switch basis
0219 case 'polynomials'
0220 r=zeros(size(x,1),numel(order));
0221 lin=linspace(-1,1,size(x,1));
0222 for k=1:order
0223 r(:,k)=lin.^k;
0224 end
0225 case 'sinusoids'
0226 r=zeros(size(x,1),numel(order)*2);
0227 lin=linspace(-1,1,size(x,1));
0228 for k=1:order
0229 r(:,2*k-1)=sin(2*pi*k*lin/2);
0230 r(:,2*k)=cos(2*pi*k*lin/2);
0231 end
0232 otherwise
0233 error('!');
0234 end
0235 end
0236
0237
0238
0239
0240
0241
0242 for iIter=1:niter
0243
0244
0245 [~,y]=nt_regw(x,r,w);
0246
0247
0248 d=x-y;
0249 if ~isempty(w); d=bsxfun(@times,d,w); end
0250 ww=ones(size(x));
0251 ww(find(abs(d)>thresh*repmat(std(d),size(x,1),1))) = 0;
0252
0253
0254 if isempty(w);
0255 w=ww;
0256 else
0257 w=min(w,ww);
0258 end
0259 clear ww;
0260 end
0261 y=x-y;
0262 y=reshape(y,dims);
0263 w=reshape(w,dims);
0264
0265 end
0266
0267
0268 function test_me
0269 if 0
0270
0271 x=(1:100)'; x=x+ randn(size(x));
0272 WSIZE=30;
0273 y=nt_detrend2(x,1,[],[],[],[],WSIZE);
0274 figure(1); clf; plot([x,y]);
0275 end
0276 if 0
0277
0278 x=(1:100)'; x=x+ randn(size(x));
0279 x(40:50)=0;
0280 WSIZE=30;
0281 [yy,ww]=nt_detrend2(x,1,[],[],2,[],WSIZE);
0282 [y,w]=nt_detrend(x,1);
0283 figure(1); clf; subplot 211;
0284 plot([x,y,yy]);
0285 subplot 212; plot([w,ww],'.-');
0286 end
0287 if 0
0288
0289 x=cumsum(randn(1000,1)+0.1);
0290 WSIZE=200;
0291 [y1,w1]=nt_detrend(x,1,[]);
0292 [y2,w2]=nt_detrend(x,1,[],[],[],[],WSIZE);
0293 figure(1); clf;
0294 plot([x,y1,y2]); legend('before', 'global', 'local');
0295 end
0296 if 0
0297
0298 x=linspace(0,100,1000)';
0299 x=x+3*randn(size(x));
0300 x(1:100,:)=100;
0301 w=ones(size(x)); w(1:100,:)=0;
0302 y=nt_detrend2(x,3,[],[],[],[],WSIZE);
0303 yy=nt_detrend2(x,3,w,[],[],[],WSIZE);
0304 figure(1); clf; plot([x,y,yy]); legend('before', 'unweighted','weighted');
0305 end
0306 if 0
0307 [p,x]=nt_read_data('/users/adc/data/meg/theoldmanandthesea/eeg/mc/MC_aespa_speech_43.mat'); x=x'; x=x(:,1:128);
0308
0309
0310 x=nt_demean(x);
0311 figure(1);
0312 nt_detrend(x,3);
0313 figure(2);
0314 WSIZE=1000;
0315 nt_detrend2(x(:,:),3,[],[],[],[],WSIZE);
0316 end
0317 end
0318
0319