PlaceFieldQuant.m 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. function field = PlaceFieldQuant(pos_map_trial, pos_map_trial_norm, varargin)
  2. % place fields quantification based on
  3. % Mizuseki 2012 Hippocampus and Harvey 2012 Nature
  4. % identification of place cells and quantificatin of fields
  5. % default values
  6. [nTrial, nBin, nUnit, nPermute] = size(pos_map_trial);
  7. min_size = 8;
  8. max_size = 80;
  9. thrd_min_max = 0.3;
  10. half_nTrial = round(nTrial/2);
  11. third_nTrial = round(nTrial/3); % the number of transients should outnumber 1/3 of trial number;
  12. ratio_in_to_out = 3;
  13. % parse input parameters
  14. % Parse parameter list
  15. for i = 1:2:length(varargin),
  16. if ~ischar(varargin{i}),
  17. error(['Parameter ' num2str(i+2) ' is not a property']);
  18. end
  19. switch(lower(varargin{i}))
  20. case 'ratio_in_to_out',
  21. ratio_in_to_out = varargin{i+1};
  22. if ~isscalar(ratio_in_to_out),
  23. error('Incorrect value for property ''ratio_in_to_out''');
  24. end
  25. case 'min_threshold',
  26. min_threshold = varargin{i+1};
  27. if ~isscalar(min_threshold),
  28. error('Incorrect value for property ''min_threshold''');
  29. end
  30. otherwise,
  31. error(['Unknown property ''' num2str(varargin{i}) '''']);
  32. end
  33. end
  34. placell_id = zeros(nPermute, nUnit);
  35. field_stab = zeros(1, nUnit);
  36. field_width = nan(1, nUnit);
  37. n_fields = nan(1, nUnit);
  38. field_pdist = nan(1, nUnit);
  39. bin_idx = 1:nBin;
  40. for iUnit = 1:nUnit
  41. for iPermute = 1:nPermute
  42. pos_map_trial_this = pos_map_trial_norm(:,:,iUnit, iPermute);
  43. if iPermute == 1
  44. pt_1 = mean(pos_map_trial_this(1:half_nTrial,:),1);
  45. pt_2 = mean(pos_map_trial_this(half_nTrial+1:end,:),1);
  46. field_stab(iUnit) = corr(pt_1', pt_2', 'rows', 'pairwise');
  47. end
  48. pos_tc = mean(pos_map_trial_this(:,:), 1);
  49. thrd_tmp = (max(pos_tc) - min(pos_tc)) * thrd_min_max;
  50. % in_field = find(pos_tc-min(pos_tc) > thrd_tmp);
  51. in_field = pos_tc - min(pos_tc) > thrd_tmp;
  52. [in_field, n_field, field_n] = FindConsecutive(in_field, min_size, max_size);
  53. if ~isempty(in_field)
  54. if n_field > 1 % account for circular nature
  55. first_field = field_n == 1;
  56. last_field = field_n == n_field;
  57. first_field_idx = in_field(first_field);
  58. last_field_idx = in_field(last_field);
  59. if first_field_idx(1) == 1 && last_field_idx(end) == nBin
  60. field_n(last_field) = 1;
  61. n_field = n_field - 1;
  62. end
  63. end
  64. out_field = bin_idx(~ismember(bin_idx, in_field));
  65. in_field_resp = pos_tc(in_field);
  66. out_field_resp = pos_tc(out_field);
  67. if mean(in_field_resp) > ratio_in_to_out * mean(out_field_resp)
  68. [~, peak_idx] = max(pos_map_trial_this(:,:), [], 2);
  69. ok = peak_idx > 1; % exclude silent trials
  70. peak_idx = peak_idx(ok);
  71. if sum(ismember(peak_idx, in_field)) >= third_nTrial
  72. placell_id(iPermute, iUnit) = 1;
  73. pd_mn = 0;
  74. for i = 1:n_field % for more than one field
  75. ok = ismember(peak_idx, in_field(field_n==i));
  76. pd = pdist(peak_idx(ok));
  77. ok = pd <= nBin/2; % 100 bins
  78. pd(~ok) = nBin-pd(~ok);
  79. if ~isempty(pd)
  80. pd_mn = pd_mn + mean(pd);
  81. end
  82. end
  83. if iPermute == 1
  84. field_width(iUnit) = length(in_field)/n_field;
  85. n_fields(iUnit) = n_field;
  86. field_pdist(iUnit) = pd_mn / n_field;
  87. end
  88. end
  89. end
  90. end
  91. end
  92. end
  93. field.placell_id = placell_id;
  94. field.stab = field_stab;
  95. field.width = field_width;
  96. field.nfields = n_fields;
  97. field.pdist = field_pdist; % pairwise drift of field max firing positions across trials
  98. end