0001 function [map,stats] = Map(v,z,varargin)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073 if nargin < 2 | mod(length(varargin),2) ~= 0,
0074 error('Incorrect number of parameters (type ''help <a href="matlab:help Map">Map</a>'' for details).');
0075 end
0076
0077
0078 if size(v,2) < 2,
0079 error('Parameter ''[t x y]'' should have at least 2 columns (type ''help <a href="matlab:help Map">Map</a>'' for details).');
0080 end
0081 if (size(z,2) < 1 || size(z,2) > 2) && ~isempty(z),
0082 error('Parameter ''z'' should have 1 or 2 columns (type ''help <a href="matlab:help Map">Map</a>'' for details).');
0083 end
0084
0085
0086 maxGap = 0.1;
0087 map.x = [];
0088 map.y = [];
0089 map.count = [];
0090 map.time = [];
0091 map.z = [];
0092 smooth = 2;
0093 nBins = 50;
0094 minTime = 0;
0095 type = 'lll';
0096 modePointProcess = 'discard';
0097 modeContinuous = 'interpolate';
0098 maxDistance = 5;
0099
0100 if isempty(v) || size(v,1) < 2, return; end
0101
0102
0103 pointProcess = (isempty(z) | size(z,2) == 1);
0104 if pointProcess,
0105 mode = modePointProcess;
0106 else
0107 mode = modeContinuous;
0108 end
0109 t = v(:,1);
0110 x = v(:,2);
0111 if size(v,2) >= 3,
0112 y = v(:,3);
0113 else
0114 y = [];
0115 end
0116
0117
0118 for i = 1:2:length(varargin),
0119 if ~ischar(varargin{i}),
0120 error(['Parameter ' num2str(i+2) ' is not a property (type ''help <a href="matlab:help Map">Map</a>'' for details).']);
0121 end
0122 switch(lower(varargin{i})),
0123
0124 case 'smooth',
0125 smooth = varargin{i+1};
0126 if ~isdvector(smooth,'>=0') || length(smooth) > 2,
0127 error('Incorrect value for property ''smooth'' (type ''help <a href="matlab:help Map">Map</a>'' for details).');
0128 end
0129
0130 case 'nbins',
0131 nBins = varargin{i+1};
0132 if ~isivector(nBins,'>0') || length(nBins) > 2,
0133 error('Incorrect value for property ''nBins'' (type ''help <a href="matlab:help Map">Map</a>'' for details).');
0134 end
0135
0136 case 'mintime',
0137 minTime = varargin{i+1};
0138 if ~isdscalar(minTime,'>=0'),
0139 error('Incorrect value for property ''minTime'' (type ''help <a href="matlab:help Map">Map</a>'' for details).');
0140 end
0141
0142 case 'maxgap',
0143 maxGap = varargin{i+1};
0144 if ~isdscalar(maxGap,'>=0'),
0145 error('Incorrect value for property ''maxGap'' (type ''help <a href="matlab:help Map">Map</a>'' for details).');
0146 end
0147
0148 case 'maxdistance',
0149 maxDistance = varargin{i+1};
0150 if ~isdscalar(maxDistance,'>=0'),
0151 error('Incorrect value for property ''maxDistance'' (type ''help <a href="matlab:help Map">Map</a>'' for details).');
0152 end
0153
0154 case 'mode',
0155 mode = lower(varargin{i+1});
0156 if ~isastring(mode,'interpolate','discard'),
0157 error('Incorrect value for property ''mode'' (type ''help <a href="matlab:help Map">Map</a>'' for details).');
0158 end
0159
0160 case 'type',
0161 type = lower(varargin{i+1});
0162 if (isempty(y) && ~isastring(type,'cc','cl','lc','ll')) || (~isempty(y) && ~isastring(type,'ccl','cll','lcl','lll','ccc','clc','lcc','llc')),
0163 error('Incorrect value for property ''type'' (type ''help <a href="matlab:help Map">Map</a>'' for details).');
0164 end
0165
0166 otherwise,
0167 error(['Unknown property ''' num2str(varargin{i}) ''' (type ''help <a href="matlab:help Map">Map</a>'' for details).']);
0168
0169 end
0170 end
0171
0172
0173 if max(x) > 1 || min(x) < 0,
0174 x = ZeroToOne(x);
0175 warning('Parameter ''x'' should contain values in [0 1]. The data will now be transformed accordingly.');
0176 end
0177 if ~isempty(y),
0178 if max(y) > 1 || min(y) < 0,
0179 y = ZeroToOne(y);
0180 warning('Parameter ''y'' should contain values in [0 1]. The data will now be transformed accordingly.');
0181 end
0182 end
0183
0184
0185 nBinsX = nBins(1);
0186 if length(nBins) == 1,
0187 nBinsY = nBinsX;
0188 nBins(2) = nBins;
0189 else
0190 nBinsY = nBins(2);
0191 end
0192
0193
0194 x = Bin(x,[0 1],nBinsX);
0195 if ~isempty(y),
0196 y = Bin(y,[0 1],nBinsY);
0197 end
0198
0199
0200 dt = diff(t);dt(end+1)=dt(end);dt(dt>maxGap) = maxGap;
0201
0202 if pointProcess,
0203
0204 n = CountInIntervals(z,[t t+dt]);
0205 else
0206
0207 [z,discarded] = Interpolate(z,t,'maxGap',maxGap);
0208 if isempty(z), return; end
0209 if strcmp(type(end),'c'),
0210 range = isradians(z(:,2));
0211 z(:,2) = exp(j*z(:,2));
0212 end
0213
0214 if any(discarded),
0215 x(discarded,:) = [];
0216 dt(discarded,:) = [];
0217 if ~isempty(y), y(discarded) = []; end
0218 end
0219 n = 1;
0220 end
0221
0222
0223 if isempty(y),
0224
0225 map.x = linspace(0,1,nBinsX);
0226 map.count = Accumulate(x,n,nBinsX);
0227 map.time = Accumulate(x,dt,nBinsX);
0228 valid = map.time > minTime;
0229 map.count = Smooth(Interpolate1(map.x,map.count,valid,mode,maxDistance),smooth,'type',type(1))';
0230 map.time = Smooth(Interpolate1(map.x,map.time,valid,mode,maxDistance),smooth,'type',type(1))';
0231 if pointProcess,
0232 map.z = map.count./(map.time+eps);
0233 else
0234 map.z = Accumulate(x,z(:,2),nBinsX);
0235 map.z = Smooth(Interpolate1(map.x,map.z,valid,mode,maxDistance),smooth,'type',type(1))';
0236 map.z = map.z./(map.count+eps);
0237 end
0238 else
0239
0240 map.x = linspace(0,1,nBinsX);
0241 map.y = linspace(0,1,nBinsY);
0242 map.count = Accumulate([x y],n,nBins);
0243 map.time = Accumulate([x y],dt,nBins);
0244 valid = map.time > minTime;
0245 map.count = Smooth(Interpolate2(map.x,map.y,map.count,valid,mode,maxDistance),smooth,'type',type(1:2))';
0246 map.time = Smooth(Interpolate2(map.x,map.y,map.time,valid,mode,maxDistance),smooth,'type',type(1:2))';
0247 if pointProcess,
0248 map.z = map.count./(map.time+eps);
0249 else
0250 map.z = Accumulate([x y],z(:,2),nBins);
0251 map.z = Smooth(Interpolate2(map.x,map.y,map.z,valid,mode,maxDistance),smooth,'type',type(1:2)).';
0252 map.z = map.z./(map.count+eps);
0253 end
0254 end
0255
0256
0257 if strcmp(type(end),'c'), map.z = wrap(angle(map.z),range); end
0258
0259
0260
0261 if strcmp(mode,'discard'),
0262 map.z(map.time<=minTime) = 0;
0263 end
0264
0265
0266
0267
0268 function yint = Interpolate1(x,y,valid,mode,maxDistance)
0269
0270 if strcmp(mode,'discard'),
0271 yint = y;
0272 else
0273 yint = interp1(x(valid),y(valid),x);
0274 end
0275
0276
0277 function zint = Interpolate2(x,y,z,valid,mode,maxDistance)
0278
0279 if strcmp(mode,'discard'),
0280
0281 zint = z;
0282 else
0283
0284 d = DistanceTransform(valid);
0285 xx = repmat(x',1,length(y));
0286 yy = repmat(y,length(x),1);
0287 if exist('scatteredInterpolant') == 2,
0288 F = scatteredInterpolant(xx(d==0),yy(d==0),z(d==0));
0289 zint = F(xx,yy);
0290 else
0291 if any(imag(z(:))),
0292 Freal = TriScatteredInterp(xx(d==0),yy(d==0),real(z(d==0)));
0293 zintReal = Freal(xx,yy);
0294 Fimaginary = TriScatteredInterp(xx(d==0),yy(d==0),imag(z(d==0)));
0295 zintImaginary = Fimaginary(xx,yy);
0296 zint = zintReal + 1i.*zintImaginary;
0297 else
0298 F = TriScatteredInterp(xx(d==0),yy(d==0),z(d==0));
0299 zint = F(xx,yy);
0300 end
0301 end
0302
0303 zint(d>maxDistance) = z(d>maxDistance);
0304 zint(isnan(zint)) = z(isnan(zint));
0305 end
0306