crosscorrelogram.m 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. function [tsOffsets, ts1idx, ts2idx] = crosscorrelogram(ts1, ts2, window)
  2. % INPUT:
  3. % ts1 - timestamp array, center of cross-correlogram
  4. % ts2 - timestamp array
  5. % window - the window of the timestamps to compute, e.g. [-0.1 0.1] for
  6. % 100 milliseconds around each spike.
  7. %
  8. % OUTPUT:
  9. % tsOffsets - the offsets from each spike in ts1 that has spikes nearby
  10. % ts1idx - the index into ts1 for each offset in tsOffsets
  11. % ts2idx - the index into ts2 for each offset in tsOffsets
  12. %
  13. % If you want to make a cross-correlogram histogram, you can make a bar plot
  14. % hist(tsOffsets, 100);
  15. %
  16. % NOTE:
  17. % If you don't need millisecond precision, you're probably better off
  18. % binning your spikes and using xcorr. If you're hardcore (you're hardcore
  19. % aren't you?) then use this function.
  20. % Make sure that all arrays are single rows, not columns
  21. if size(ts1,1) > size(ts1,2); ts1 = ts1'; end
  22. if size(ts2,1) > size(ts2,2); ts2 = ts2'; end
  23. startWindow = 1;
  24. spikeIdx = 1;
  25. ccInfo = zeros(length(ts1), 3)+NaN; % startIdx, endIdx, spikeTime, instantRate
  26. while spikeIdx <= length(ts1)
  27. % Seek to the beginning of the current spike's window
  28. i = startWindow;
  29. while ts2(i) < (ts1(spikeIdx) + window(1)) && i < length(ts2)
  30. i = i+1;
  31. end
  32. startWindow = i; % save the location for later
  33. if ts2(i) > ( ts1(spikeIdx) + window(2))
  34. spikeIdx = spikeIdx+1;
  35. continue;
  36. end
  37. % Find all the spike indices that fall within the window
  38. while ts2(i) <= (ts1(spikeIdx) + window(2)) && i < length(ts2)
  39. i = i+1;
  40. if i==length(ts2) && ts2(i) <= (ts1(spikeIdx) + window(2))
  41. i = i+1;
  42. break
  43. end
  44. end
  45. endWindow = i-1;
  46. ccInfo(spikeIdx,1) = startWindow;
  47. ccInfo(spikeIdx,2) = endWindow;
  48. ccInfo(spikeIdx,3) = ts1(spikeIdx);
  49. spikeIdx = spikeIdx+1;
  50. end
  51. % Now I've got all of the indices into spikes, and their offset
  52. % from the center-spike is easily calculable.
  53. % I think I'll increment into the array bit by bit.
  54. diffArray = diff(ccInfo (:,1:2),1,2);
  55. done = 0; tsOffsets = []; instantRate = []; ts1idx = []; ts2idx = [];
  56. incr = 0;
  57. while ~done
  58. tmp = find(diffArray >= incr);
  59. if isempty(tmp); done = 1; continue; end
  60. idx = ccInfo(tmp,1)+incr; % brilliant!
  61. centerTimes = ccInfo(tmp,3);
  62. tsOffsets = [tsOffsets ts2(idx)-centerTimes'];
  63. ts1idx = [ts1idx; tmp];
  64. ts2idx = [ts2idx; idx];
  65. incr = incr+1;
  66. end
  67. end