-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmatch_spike_templates.m
87 lines (79 loc) · 2.89 KB
/
match_spike_templates.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
function [idx,dists,confidence] = match_spike_templates(templates, waveforms)
%--------------------------------------------------------------------------
% match_spike_templates.m - Given a set of spike templates and standard
% deviations, calculates the distance of each spike to a particular
% template, assigns it to a cluster, and returns the distance with respect
% to that cluster.
%
% Note: this function does not use adaptive templates.
%
% Usage: [idx,zscores] = match_spike_templates(templates,std_devs,spikes);
%
% Input: templates * GxCxT set of spike templates (T templates,
% C channels, W time points)
% std_devs * 1xT vector of distance standard deviations
% for each template
% waveforms * CxMxW matrix of M spikes
% Output: idx * 1xM vector of M cluster assignments
% dists * 1xM vector of distances to each cluster
% confidence * 1xM vector of confidence values (0 is high
% confidence, 1 is low confidence)
%
% Written by Marshall Crumiller
% email: [email protected]
%--------------------------------------------------------------------------
[G,C,T]=size(templates);
W=size(waveforms,2);
% no templates!
if(G==0)
idx=zeros(1,W);
dists=idx; confidence=idx;
return;
end
% determine amplitudes of each channel
%{
amps=abs(min(templates,[],3));
amps = amps./repmat(sum(amps,2),1,size(amps,2));
amps=repmat(amps,[1 1 T]);
amps=permute(amps,[3 2 1]);
amps=reshape(amps,T*C,G)';
amps=repmat(amps,[1 1 W]);
%}
% determine max 2 channels for each waveform
if(C>1)
[~,ch]=sort(min(templates,[],3),2,'ascend');
ch=ch(:,1:2);
end
% set up matrices
waveforms=permute(waveforms,[3 1 2]);
waveforms=reshape(waveforms,T*C,[]);
templates=permute(templates,[3 2 1]);
templates=reshape(templates,T*C,[]);
% normalize waveforms and templates to vectors of unit length
wf_len=sqrt(sum(waveforms.^2));
template_len=sqrt(sum(templates.^2));
waveforms=waveforms./repmat(wf_len,C*T,1);
templates=templates./repmat(template_len,C*T,1);
templates=repmat(templates,[1 1 W]);
% Calculate the distances to each template
distances=zeros(W,G);
%for i = 1:G
% distances(:,i) = sqrt(sum( ((waveforms-squeeze(templates(:,i,:))).*squeeze(amps(i,:,:))) .^2));
%end
for i = 1:G
% set up templates to only include the top channel
if(C>1)
locs=false(T,C); locs(:,ch(i,:))=1;
distances(:,i) = sqrt(sum((waveforms(locs,:)-squeeze(templates(locs,i,:))).^2));
else
distances(:,i) = sqrt(sum((waveforms-squeeze(templates(:,i,:))).^2));
end
end
min_dist=repmat(min(distances,[],2),1,G);
confidence = min_dist./distances;
confidence = (sum(confidence,2)-1)/(G-1);
% put distances in terms standard deviations
[~,idx]=min(distances,[],2);
I=sub2ind(size(distances),(1:W)',idx);
dists=distances(I);
idx=idx';