在MATLAB中计算PSTH(peristimulus时间直方图)的矢量化方法

时间:2016-08-14 11:29:01

标签: matlab vectorization neuroscience

我有一个尖峰时间矢量(来自神经元的动作电位)和一个刺激事件时间戳矢量。我想创建一个PSTH,看看刺激是否会影响神经元的尖峰率。我可以通过循环每个刺激事件来做到这一点(参见下面的简单示例),但对于长期实验而言,这是非常缓慢的,其中有超过30,000个刺激事件并且正在记录许多神经元。

如果没有for循环,怎么办呢?

缓慢的方式示例:

loadFromJSON

2 个答案:

答案 0 :(得分:0)

这是一个解决方案,在所有峰值和两个假设上都有一个循环:

  • 刺激时间是固定的间隔
  • 刺激间隔大于PSTH间隔

假设刺激时间是固定的:

delta_times = mean(diff(stimTimes));
assert(max(abs(diff(stimTimes)-delta_times))<1e-3);

现在我们在第一次刺激之前将尖峰时间与preStimTime对齐:

spikeTimes0 = spikeTimes - stimTimes(1) + preStimTime;

现在我们希望使用第二个假设计算每个峰值计数的刺激:

assert((postStimTime-preStimTime)<dekta_times);
stimuli_index = floor(spikeTimes0 / delta_times); 

相对于刺激计算:

spike_time_from_stimuli = spikeTimes0 - stimuli_index*delta_times;

现在让我们建立PSTH,预定值为0.01(与所有其他时间相同):

dt = 0.01;
times_around_stimuli = preStimTime:dt:postStimTime;
n_time_bins = length(times_around_stimuli);
n_stimuli = length(stimTimes);
PSTH = zeros(n_stimuli, n_time_bins)
for i=1:length(spikeTimes)
     time_index = ceil(spike_time_from_stimuli(i) / dt);
     % Ignore time-bins far from the event
     if time_index > n_time_bins
           continue;
     end
     PSTH(stimuli_index(i),time_index) = PSTH(stimuli_index(i),time_index) + 1;
end

答案 1 :(得分:0)

最好的方法是使用现有的直方图函数。他们非常快,应该为您提供所需的所有信息。当然,这假设箱不重叠。给出您的示例数据:

spikeTimes = [0.9 1.1 1.2 2.5 2.8 3.1];
stimTimes = [1 2 3 4 5];        
preStimTime = 0.2;
postStimTime = 0.3;
你可以像这样构建垃圾箱:

bins = sort([stimTimes - preStimTime, stimTimes + postStimTime])

bins = [stimTimes - preStimTime; stimTimes + postStimTime];
bins = bins(:).'

bins =
   0.80000   1.30000   1.80000   2.30000   2.80000   3.30000   3.80000   4.30000   4.80000   5.30000

然后,您可以使用histcountsdiscretizehistc,具体取决于您所需的结果以及您拥有的MATLAB版本。我将使用histc(因为我没有那些花哨的东西),但所有三个函数的输入都相同。您有一个histcounts的额外输出(edges,这对我们没用),而discretize则少一个(实际计数)。

[N, IDX] = histc(spikeTimes, bins)

N =    
   3   0   0   1   2   0   0   0   0   0

IDX =    
   1   1   1   4   5   5

由于这些垃圾箱包含(T(i) + postStimTime)(T(i+1) - preStimTime)之间的时间,我们需要抓住其他所有垃圾箱:

N = N(1:2:end)

N =
   3   0   2   0   0

同样,我们只对奇数时隙中发生的尖峰感兴趣,我们需要调整索引以匹配新的IDX

v = mod(IDX, 2)

v =
   1   1   1   0   1   1

IDX = ((IDX+1)/2).*v

IDX =
   1   1   1   0   3   3

结果与我们最初获得的结果一致:bin 3中有3个峰值,bin 3中有2个峰值。