-
Notifications
You must be signed in to change notification settings - Fork 84
/
Copy pathgetWaveForms.m
68 lines (62 loc) · 3.58 KB
/
getWaveForms.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
function wf = getWaveForms(gwfparams)
% function wf = getWaveForms(gwfparams)
%
% Extracts individual spike waveforms from the raw datafile, for multiple
% clusters. Returns the waveforms and their means within clusters.
%
% Contributed by C. Schoonover and A. Fink
%
% % EXAMPLE INPUT
% gwfparams.dataDir = '/path/to/data/'; % KiloSort/Phy output folder
% gwfparams.fileName = 'data.dat'; % .dat file containing the raw
% gwfparams.dataType = 'int16'; % Data type of .dat file (this should be BP filtered)
% gwfparams.nCh = 32; % Number of channels that were streamed to disk in .dat file
% gwfparams.wfWin = [-40 41]; % Number of samples before and after spiketime to include in waveform
% gwfparams.nWf = 2000; % Number of waveforms per unit to pull out
% gwfparams.spikeTimes = [2,3,5,7,8,9]; % Vector of cluster spike times (in samples) same length as .spikeClusters
% gwfparams.spikeClusters = [1,2,1,1,1,2]; % Vector of cluster IDs (Phy nomenclature) same length as .spikeTimes
%
% % OUTPUT
% wf.unitIDs % [nClu,1] List of cluster IDs; defines order used in all wf.* variables
% wf.spikeTimeKeeps % [nClu,nWf] Which spike times were used for the waveforms
% wf.waveForms % [nClu,nWf,nCh,nSWf] Individual waveforms
% wf.waveFormsMean % [nClu,nCh,nSWf] Average of all waveforms (per channel)
% % nClu: number of different clusters in .spikeClusters
% % nSWf: number of samples per waveform
%
% % USAGE
% wf = getWaveForms(gwfparams);
% Load .dat and KiloSort/Phy output
fileName = fullfile(gwfparams.dataDir,gwfparams.fileName);
filenamestruct = dir(fileName);
dataTypeNBytes = numel(typecast(cast(0, gwfparams.dataType), 'uint8')); % determine number of bytes per sample
nSamp = filenamestruct.bytes/(gwfparams.nCh*dataTypeNBytes); % Number of samples per channel
wfNSamples = length(gwfparams.wfWin(1):gwfparams.wfWin(end));
mmf = memmapfile(fileName, 'Format', {gwfparams.dataType, [gwfparams.nCh nSamp], 'x'});
chMap = readNPY(fullfile(gwfparams.dataDir, 'channel_map.npy'))+1; % Order in which data was streamed to disk; must be 1-indexed for Matlab
nChInMap = numel(chMap);
% Read spike time-centered waveforms
unitIDs = unique(gwfparams.spikeClusters);
numUnits = size(unitIDs,1);
spikeTimeKeeps = nan(numUnits,gwfparams.nWf);
waveForms = nan(numUnits,gwfparams.nWf,nChInMap,wfNSamples);
waveFormsMean = nan(numUnits,nChInMap,wfNSamples);
for curUnitInd=1:numUnits
curUnitID = unitIDs(curUnitInd);
curSpikeTimes = gwfparams.spikeTimes(gwfparams.spikeClusters==curUnitID);
curUnitnSpikes = size(curSpikeTimes,1);
spikeTimesRP = curSpikeTimes(randperm(curUnitnSpikes));
spikeTimeKeeps(curUnitInd,1:min([gwfparams.nWf curUnitnSpikes])) = sort(spikeTimesRP(1:min([gwfparams.nWf curUnitnSpikes])));
for curSpikeTime = 1:min([gwfparams.nWf curUnitnSpikes])
tmpWf = mmf.Data.x(1:gwfparams.nCh,spikeTimeKeeps(curUnitInd,curSpikeTime)+gwfparams.wfWin(1):spikeTimeKeeps(curUnitInd,curSpikeTime)+gwfparams.wfWin(end));
waveForms(curUnitInd,curSpikeTime,:,:) = tmpWf(chMap,:);
end
waveFormsMean(curUnitInd,:,:) = squeeze(nanmean(waveForms(curUnitInd,:,:,:),2));
disp(['Completed ' int2str(curUnitInd) ' units of ' int2str(numUnits) '.']);
end
% Package in wf struct
wf.unitIDs = unitIDs;
wf.spikeTimeKeeps = spikeTimeKeeps;
wf.waveForms = waveForms;
wf.waveFormsMean = waveFormsMean;
end