-
Notifications
You must be signed in to change notification settings - Fork 0
/
processRaw_css.m
235 lines (192 loc) · 8.67 KB
/
processRaw_css.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
%
%processes raw signal, extracts spikes. loads data directly from neuralynx
%file.
%
%filename: full path/name to neuralynx file
%totNrSamples: nr of samples in this file
%Hd: filter specification
%howManyBlocks: >0 do only so many blocks
% 0 : as many as there are
%startWithBlock: 1=start with first block
% >1: dont process first x blocks
%includeRange: from/to timestamps of periods to sort. if empty everything
%is taken.
%
%extractionThreshold: how many times the running std of the energy signal
%to extract ?
%
%prewhiten: yes/no
%
%returns:
%blockOffsets -> start of each processed block in absolute timestamps
%
%
%urut/april04
%updated urut/feb07
%
function [allSpikes, allSpikesNoiseFree, allSpikesCorrFree, allSpikesTimestamps,...
dataSamplesRaw,filteredSignal, rawMean,rawTraceSpikes,runStd2,upperlim,stdEstimates,...
blocksProcessed, noiseTraces, dataSamplesRawUncorrected, blockOffsets ] =...
processRaw_css(filename, totNrSamples, Hd, params ,timestampsRawIN,dataSamplesRawIN)
blockOffsets=[];
howManyBlocks = params.howManyBlocks;
startWithBlock = params.startWithBlock;
includeRange = params.includeRange;
%extractionThreshold = params.extractionThreshold;
%prewhiten = params.prewhiten;
alignMethod = params.alignMethod;
params.nrNoiseTraces=50;
%detect spikes
[runs, blocksize] = determineBlocks( totNrSamples,params.blocksize);
allSpikes=[];
allSpikesTimestamps=[];
allSpikesNoiseFree=[];
allSpikesCorrFree=[];
%returns data of last block processed -- for debugging purposes
% dataSamplesRaw=[];
dataSamplesRawUncorrected=[];
rawMean=[];
filteredSignal=[];
rawTraceSpikes=[];
runStd2=[];
upperlim=[];
stdEstimates=[];
noiseTraces=[];
if runs<startWithBlock
disp(['warning: startWithBlock<runs']);
end
for i=startWithBlock:runs
fromInd=(i-1)*blocksize+1;
tillInd=i*blocksize;
if tillInd>totNrSamples
tillInd=totNrSamples;
end
if params.rawFileVersion<=2 || params.rawFileVersion==6
disp(['CSC run: ' num2str(i) ' of ' num2str(runs) ' ind from ' num2str(ceil(fromInd/512)) ' to ' num2str(tillInd/512)]);
else
disp(['TXT run: ' num2str(i) ' of ' num2str(runs) ' ind from ' num2str(fromInd) ' to ' num2str(tillInd) ]);
end
%load data from file
t1=clock;
dataSamplesRaw = dataSamplesRawIN(fromInd:tillInd);
timestampsRaw = timestampsRawIN(fromInd:tillInd);
% [timestampsRaw,dataSamplesRaw] = getRawData( filename, fromInd, tillInd, params.rawFileVersion, params.samplingFreq );
disp(['time for raw read ' num2str(etime(clock,t1))]);
if params.doGroundNormalization==1
disp( ['normalizing ground to channels ' num2str(params.normalizationChannels) ] );
rawFilePrefix = copyFieldIfExists( params, 'prefix', 'A' ); %file prefix default is Axx.ncs if not set
[ commonGround ] = computeNormalizedGround(params.pathRaw, params.normalizationChannels, fromInd, tillInd, rawFilePrefix, params.rawFilePostfix);
dataSamplesRawUncorrected = dataSamplesRaw;
dataSamplesRaw = dataSamplesRaw - commonGround;
else
disp('dont normalize ground');
end
wasPartialBlock=0; %flag to indicate that block was included that was only partially part of included time range
if size(includeRange,1)>0
includeMask=zeros(1, length(timestampsRaw));
for j=1:size(includeRange,1)
inds = find( timestampsRaw >= includeRange(j,1) & timestampsRaw <= includeRange(j,2) );
if length(inds)>0
includeMask(inds) = 1;
end
end
if sum(includeMask)==0
disp(['all samples in this block are excluded,skip from:' num2str(timestampsRaw(1),10) ' to:' num2str(timestampsRaw(end),10)]);
continue;
else
if sum(includeMask)<length(timestampsRaw)
%only some are excluded
disp(['some samples are excluded,but still include everything. from:' num2str(timestampsRaw(1),10) ' to:' num2str(timestampsRaw(end),10)]);
wasPartialBlock=1;
else
disp(['all samples included. from:' num2str(timestampsRaw(1),10) ' to:' num2str(timestampsRaw(end),10)]);
end
end
end
t1=clock;
[rawMean, filteredSignal, rawTraceSpikes,spikeWaveforms, spikeTimestamps, runStd2, upperlim, noiseTracesTmp] = extractSpikes( dataSamplesRaw, Hd, params );
disp(['time for extraction ' num2str(etime(clock,t1))]);
stdEstimates(i) = std(filteredSignal);
%save(['c:\temp\traces\traces_B' num2str(i) '.mat'],'filteredSignal','spikeWaveforms','noiseTracesTmp');
%add to global storage of noise traces, adding block # into first
%column
if size(noiseTracesTmp,1)>1
noiseTracesTmp2=[];
noiseTracesTmp2(1:size(noiseTracesTmp,1) ,1) = ones( size(noiseTracesTmp,1), 1 )*i;
noiseTracesTmp2(1:size(noiseTracesTmp,1),2:size(noiseTracesTmp,2)+1)=noiseTracesTmp;
noiseTraces = [noiseTraces; noiseTracesTmp2];
end
%upsample and classification
disp(['upsample and classify run ' num2str(i) ' nr spikes ' num2str(size(spikeWaveforms,1))]);
%classify
%[spikeWaveformsNegative, spikeTimestampsNegativeTmp,nrSpikesKilledNegative,killedNegative] = classifySpikes(-1 * spikeWaveformsNegative,spikeTimestampsNegative);
%only denoise if enough traces available
nrNoiseTraces=size(noiseTraces,1);
disp(['nrNoiseTraces ' num2str(nrNoiseTraces)]);
%store orig waveforms for later whitening.
spikeWaveformsOrig = spikeWaveforms; %before upsampling
%upsample and re-align
spikeWaveforms=upsampleSpikes(spikeWaveforms);
spikeWaveforms = realigneSpikes(spikeWaveforms, spikeTimestamps, alignMethod, stdEstimates(i)); %3==type is negative, do not remove any if too much shift
%convert timestamps
spikeTimestampsTmp = spikeTimestamps;
if length( spikeTimestampsTmp ) > 0
spikeTimestampsConverted = convertTimestamps_css( timestampsRaw, spikeTimestampsTmp, params.samplingFreq, params.rawFileVersion );
% spikeTimestampsConverted = convertTimestamps( timestampsRaw, spikeTimestampsTmp, params.samplingFreq, params.rawFileVersion );
[row,~] = size(spikeTimestampsConverted);
if row > 1
spikeTimestampsConverted = transpose(spikeTimestampsConverted);
end
else
spikeTimestampsConverted = [];
end
blockOffsets = [blockOffsets timestampsRaw(1)];
%-- exclude spikes outside of included time range (from partial blocks
%with overlap)
if wasPartialBlock
includeMaskSpikes = zeros(1, length(spikeTimestampsConverted));
for j=1:size(includeRange,1)
inds = find( spikeTimestampsConverted >= includeRange(j,1) & spikeTimestampsConverted <= includeRange(j,2) );
includeMaskSpikes(inds)=1;
end
% only keep timestamps and waveforms of spikes that were included
indsUse = find(includeMaskSpikes);
spikeTimestampsConverted = spikeTimestampsConverted(indsUse);
spikeWaveforms = spikeWaveforms(indsUse,:);
spikeWaveformsOrig = spikeWaveformsOrig(indsUse,:);
disp(['Exclude spikes not in includeRange: ' num2str(length(indsUse)) ' of ' num2str(length(includeMaskSpikes)) ' included.']);
end
%put into global data structure
allSpikes = [allSpikes; spikeWaveforms];
allSpikesTimestamps = [allSpikesTimestamps spikeTimestampsConverted];
allSpikesCorrFree = [ allSpikesCorrFree; spikeWaveformsOrig];
if length(allSpikesTimestamps) ~= size(allSpikes,1)
warning('nr timestamps is not equal to nr waveforms');
end
disp(['== number of spikes found in run ' num2str(i) ' ' num2str( size(spikeWaveforms,1)) ' total ' num2str(size(allSpikes,1)) ]);
%stop as soon as 1000 spikes were detected,positive and negative
if howManyBlocks==9999
if size(allSpikes,1)>=1000
%&& size(allSpikesNegative,1)>=1000
warning('early stop is enabled - stopping detection because 1000 spikes detected.');
blocksProcessed=i;
break;
end
end
%stop early if limit is set (by caller of function)
if howManyBlocks>0
if i>=howManyBlocks
blocksProcessed=i;
disp('early stop is enabled - stop detection because of tillBlocks limit');
break;
end
end
end
blocksProcessed=i;
%whiten
if size(noiseTraces,1)>0 & size(allSpikesCorrFree,1)>0
[trans, transUp, corr, stdWhitened] = posthocWhiten(noiseTraces, allSpikesCorrFree, alignMethod);
allSpikesCorrFree = transUp;
%only store the autocorrelation,not all noise traces
noiseTraces=corr;
end