Scheduled service maintenance on November 22


On Friday, November 22, 2024, between 06:00 CET and 18:00 CET, GIN services will undergo planned maintenance. Extended service interruptions should be expected. We will try to keep downtimes to a minimum, but recommend that users avoid critical tasks, large data uploads, or DOI requests during this time.

We apologize for any inconvenience.

Map.m 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. function [map,stats] = Map(v,z,varargin)
  2. %Map - Map z on (x,y) where x, y and z are time-varying variables (samples).
  3. %
  4. % Compute a continuous map, where one time-varying variable z is represented
  5. % as a function of one or two time-varying variables x and y. The variable z
  6. % can either be a point process (typically, a list of spike timestamps) or a
  7. % continuous measure (e.g. the instantaneous velocity of the animal, the
  8. % spectral power of an LFP channel in a given frequency band, the coherence
  9. % between two oscillating LFP channels, etc.) Typical examples of x and y
  10. % include spatial coordinates and angular directions.
  11. %
  12. % An occupancy map is also computed.
  13. %
  14. % USAGE
  15. %
  16. % map = Map([t x y],z,<options>)
  17. %
  18. % t timestamps for x and y
  19. % x x values in [0,1]
  20. % y optional y values in [0,1]
  21. % z list of timestamps or (timestamp,value) pairs
  22. % <options> optional list of property-value pairs (see table below)
  23. %
  24. % =========================================================================
  25. % Properties Values
  26. % -------------------------------------------------------------------------
  27. % 'smooth' smoothing size in bins (0 = no smoothing, default = 2)
  28. % 'nBins' number of horizontal and vertical bins (default = [50 50])
  29. % 'minTime' minimum time spent in each bin (in s, default = 0)
  30. % 'maxGap' z values recorded during time gaps between successive (x,y)
  31. % samples exceeding this threshold (e.g. undetects) will not
  32. % be interpolated; also, such long gaps in (x,y) sampling
  33. % will be clipped to 'maxGap' to compute the occupancy map
  34. % (default = 0.100 s)
  35. % 'type' 'linear' if z is linear (default), 'circular' otherwise
  36. % =========================================================================
  37. %
  38. % OUTPUT
  39. %
  40. % map.x x bins
  41. % map.y y bins
  42. % map.z average map (z continuous)
  43. % or rate map (z point process)
  44. % map.count count map (z point process)
  45. % map.time occupancy map (in s)
  46. %
  47. % NOTES
  48. %
  49. % x values are arranged in columns and y values in rows in all output matrices
  50. % (e.g. 'map.z').
  51. %
  52. % SEE
  53. %
  54. % See also MapStats, FiringMap, PlotColorMap, Accumulate.
  55. % Copyright (C) 2002-2011 by Michael Zugaro
  56. %
  57. % This program is free software; you can redistribute it and/or modify
  58. % it under the terms of the GNU General Public License as published by
  59. % the Free Software Foundation; either version 3 of the License, or
  60. % (at your option) any later version.
  61. % Check number of parameters
  62. if nargin < 2 | mod(length(varargin),2) ~= 0,
  63. error('Incorrect number of parameters');
  64. end
  65. % Check parameter sizes
  66. if size(v,2) < 2,
  67. error('Parameter ''[t x y]'' should have at least 2 columns');
  68. end
  69. if (size(z,2) < 1 || size(z,2) > 2) && ~isempty(z),
  70. error('Parameter ''z'' should have 1 or 2 columns');
  71. end
  72. % Default values
  73. maxGap = 0.1;
  74. map.x = [];
  75. map.y = [];
  76. map.count = [];
  77. map.time = [];
  78. map.z = [];
  79. smooth = 1;
  80. nBins = [100 1];
  81. minTime = 0;
  82. type = 'linear';
  83. % Parse parameter list
  84. for i = 1:2:length(varargin),
  85. if ~ischar(varargin{i}),
  86. error(['Parameter ' num2str(i+2) ' is not a property']);
  87. end
  88. switch(lower(varargin{i})),
  89. case 'smooth',
  90. smooth = varargin{i+1};
  91. if ~isdvector(smooth) | length(smooth) > 2,
  92. error('Incorrect value for property ''smooth''');
  93. end
  94. case 'nbins',
  95. nBins = varargin{i+1};
  96. if ~isivector(nBins) | length(nBins) > 2,
  97. error('Incorrect value for property ''nBins''');
  98. end
  99. case 'mintime',
  100. minTime = varargin{i+1};
  101. if ~isdscalar(minTime,'>=0'),
  102. error('Incorrect value for property ''minTime''');
  103. end
  104. case 'maxgap',
  105. maxGap = varargin{i+1};
  106. if ~isdscalar(maxGap,'>=0'),
  107. error('Incorrect value for property ''maxGap''');
  108. end
  109. case 'type',
  110. type = lower(varargin{i+1});
  111. if ~isstring(type,'circular','linear'),
  112. error('Incorrect value for property ''type''');
  113. end
  114. otherwise,
  115. error(['Unknown property ''' num2str(varargin{i}) '''']);
  116. end
  117. end
  118. if isempty(v), return; end
  119. % Some info about x, y and z
  120. pointProcess = (isempty(z) | size(z,2) == 1);
  121. t = v(:,1);
  122. x = v(:,2);
  123. if size(v,2) >= 3,
  124. y = v(:,3);
  125. else
  126. y = [];
  127. end
  128. % Number of bins for x and y
  129. nBinsX = nBins(1);
  130. if length(nBins) == 1,
  131. nBinsY = nBinsX;
  132. nBins(2) = nBins;
  133. else
  134. nBinsY = nBins(2);
  135. end
  136. % Bin x and y
  137. x = Bin(x,[0 1],nBinsX);
  138. if ~isempty(y),
  139. y = Bin(y,[0 1],nBinsY);
  140. end
  141. % Duration for each (X,Y) sample (clipped to maxGap)
  142. dt = diff(t);dt(end+1)=dt(end);dt(dt>maxGap) = maxGap;
  143. if pointProcess,
  144. % Count occurrences for each (x,y) timestamp
  145. n = CountInIntervals(z,[t t+dt]);
  146. % n = CountInIntervals(z,[t(1:end-1) t(2:end)]);
  147. % n(end+1) = 0;
  148. else
  149. % Interpolate z at (x,y) timestamps
  150. [z,discarded] = Interpolate(z,t,'maxGap',maxGap);
  151. if isempty(z), return; end
  152. if strcmp(type,'circular'),
  153. range = isradians(z(:,2));
  154. z(:,2) = exp(j*z(:,2));
  155. end
  156. n = 1;
  157. end
  158. % Computations
  159. if isempty(y),
  160. % 1D (only x)
  161. map.x = linspace(0,1,nBinsX);
  162. map.count = Smooth(Accumulate(x,n,nBinsX),smooth)';
  163. map.time = Smooth(Accumulate(x,dt,nBinsX),smooth)';
  164. if pointProcess,
  165. map.z = map.count./(map.time+eps);
  166. else
  167. map.z = Smooth(Accumulate(x(~discarded),z(:,2),nBinsX),smooth)';
  168. map.z = map.z./(map.count+eps);
  169. end
  170. else
  171. % 2D (x and y)
  172. map.x = linspace(0,1,nBinsX);
  173. map.y = linspace(0,1,nBinsY);
  174. map.count = Smooth(Accumulate([x y],n,nBins),smooth)';
  175. map.time = Smooth(Accumulate([x y],dt,nBins),smooth)';
  176. if pointProcess,
  177. map.z = map.count./(map.time+eps);
  178. else
  179. map.z = Smooth(Accumulate([x(~discarded) y(~discarded)],z(:,2),nBins),smooth).';
  180. map.z = map.z./(map.count+eps);
  181. end
  182. end
  183. % Circular z
  184. if strcmp(type,'circular'), map.z = wrap(angle(map.z),range); end
  185. % Discard regions with insufficient sampling
  186. map.z(map.time<=minTime) = 0;