3 % Spikes with an interspike interval smaller
4 % than 75 ms are considered a burst. The results are stored as an
18 % filename name of file containing spikes in the
event table
19 % HDR header structure obtained by SOPEN, SLOAD, or meXSLOAD
20 % dT_Burst [
default: 50e-3 s] am inter-spike-interval (ISI) exceeding
this value,
21 % marks the beginning of a
new burst
22 % dT_Exclude an interspike interval smaller than
this value, indicates a
23 %
double detection, and the second detection is deleted.
24 % in
case of several consecutive ISI
's smaller than this value,
25 % all except the first spikes are deleted.
27 % filename to store the original data together with the newly compuated
28 % burst information. (Remark: this option is only supported if
29 % filename (not HDR) is given as first argument
31 % filename to store event inforamation in GDF format. this is similar to
32 % the outputFile, except that the signal data is not included and is, therefore,
33 % much smaller than the outputFile
35 % filename for the "burst table", containing basic properties of each burst,
36 % (it is an ASCII file in <tab>-delimited format)
39 % HDR header structure as defined in biosig
40 % HDR.EVENT includes the detected spikes and bursts.
41 % HDR.BurstTable contains for each burst (each in a row) the following 5 numbers:
42 % channel number, sweep number, OnsetTime within sweep [s],
43 % number of spikes within burst, average inter-spike interval (ISI) [ms],
44 % and minimum ISI [ms]
45 % data signal data, one channel per column
46 % between segments, NaN values for 0.1s are introduced
51 % $Id: detect_spikes_bursts.m 2739 2011-07-13 15:42:05Z schloegl $
52 % Copyright (C) 2011 by Alois Schloegl <alois.schloegl@gmail.com>
53 % This is part of the BIOSIG-toolbox http://biosig.sf.net/
55 % BioSig is free software: you can redistribute it and/or modify
56 % it under the terms of the GNU General Public License as published by
57 % the Free Software Foundation, either version 3 of the License, or
58 % (at your option) any later version.
60 % BioSig is distributed in the hope that it will be useful,
61 % but WITHOUT ANY WARRANTY; without even the implied warranty of
62 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
63 % GNU General Public License for more details.
65 % You should have received a copy of the GNU General Public License
66 % along with BioSig. If not, see <http://www.gnu.org/licenses/>.
72 %%%%% default settings %%%%%
73 dT_Burst = 50e-3; %%% smaller ISI is a burst [s]
74 dT_Exclude = []; %%% for identifying double detections, spikes with smaller ISI are excluded
80 %%%%% analyze input arguments %%%%%
83 while k <= length(varargin)
84 if ischar(varargin{k})
85 if (strcmp(varargin{k},'-e
'))
87 evtFile = varargin{k};
88 elseif (strcmp(varargin{k},'-b
'))
90 burstFile = varargin{k};
91 elseif (strcmp(varargin{k},'-o
'))
93 outFile = varargin{k};
94 elseif (strcmpi(varargin{k},'dT_Burst
'))
96 dT_Burst = varargin{k};
97 elseif (strcmpi(varargin{k},'dT_Exclude
'))
99 dT_Exclude = varargin{k};
101 warning(sprintf('unknown input argument <%s>- ignored
',varargin{k}));
103 elseif isnumeric(varargin{k})
107 dT_Burst = varargin{k};
109 dT_Exclude = varargin{k};
111 warning(sprintf('unknown input argument <%f> - ignored
',varargin{k}));
118 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
120 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
122 if ischar(fn) && exist(fn,'file
')
123 [s, HDR] = sload(fn);
131 ix = (EVENT.TYP ~= hex2dec('0202
'));
132 %if ~all(ix) warning('previously defined bursts are ignored
'); end;
133 EVENT.POS = EVENT.POS(ix);
134 EVENT.TYP = EVENT.TYP(ix);
135 if ~isfield(EVENT,'DUR
');
136 EVENT.DUR = zeros(size(EVENT.POS));
138 EVENT.DUR = HDR.EVENT.DUR(ix);
140 if ~isfield(EVENT,'CHN
');
141 EVENT.CHN = zeros(size(EVENT.TYP));
143 EVENT.CHN = HDR.EVENT.CHN(ix);
147 chan = unique(EVENT.CHN);
150 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
151 % Set Parameters for Burst Detection
152 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
155 for ch = chan(:)'; % look
for each channel
156 OnsetSpike = EVENT.POS((EVENT.CHN==ch) & (EVENT.TYP==hex2dec(
'0201'))); %% spike onset time [samples]
157 if isempty(OnsetSpike)
161 if ~isempty(dT_Exclude)
162 % --- remove
double detections < 1 ms
163 OnsetSpike = OnsetSpike([1; 1+find(diff(OnsetSpike) > Fs * dT_Exclude)]);
166 %%%%%%% Burst Detection %%%%%%%%%%%%%%%%%%%
167 OnsetBurst = OnsetSpike ( [1; 1 + find( diff(OnsetSpike) > Fs * dT_Burst ) ] );
169 DUR = repmat(NaN, size(OnsetBurst));
170 BurstTable = repmat(NaN, length(OnsetBurst), 6);
171 OnsetBurst(end+1) = inf;
174 t0 = [1; EVENT.POS(EVENT.TYP==hex2dec(
'7ffe'))];
175 for m = 1:length(OnsetBurst)-1, % loop
for each burst candidate
176 tmp = OnsetSpike( OnsetBurst(m) <= OnsetSpike & OnsetSpike < OnsetBurst(m+1) );
178 ix = sum(t0 < OnsetBurst(m)); %% number of sweep
179 T0 = t0(ix); % time since beginning of sweep
182 DUR(m) = length(tmp)*mean(d);
183 BurstTable(m,:) = [ch, ix, (OnsetBurst(m) - T0)/HDR.SampleRate, length(tmp), 1000*mean(d)/HDR.SampleRate, 1000*min(d)/HDR.SampleRate];
184 elseif length(tmp)==1
185 % single spikes are not counted as bursts, DUR(m)==NaN marks them as invalid
186 BurstTable(m,:) = [ch, ix, (OnsetBurst(m) - T0)/HDR.SampleRate, length(tmp), NaN,NaN];
190 % remove single spike bursts
191 HDR.BurstTable = [HDR.BurstTable; BurstTable];
193 EVENT.TYP = [EVENT.TYP; repmat(hex2dec(
'0202'), size(DUR))];
194 EVENT.POS = [EVENT.POS; OnsetBurst(1:end-1)];
195 EVENT.DUR = [EVENT.DUR; DUR];
196 EVENT.CHN = [EVENT.CHN; repmat(ch, size(DUR,1), 1) ];
199 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
201 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
203 H = HDR; %%
return value
204 if ~isempty(burstFile),
205 fid = fopen(burstFile,
'w');
207 fprintf(2,
'Warning can not open file <%s> - burst table not written\n',burstFile);
209 fprintf(fid,
'#Burst\t#chan\t#sweep\tOnset [s] \t#spikes\tavgISI [ms] \tminISI [ms] \n');
210 for m = 1:size(HDR.BurstTable,1);
211 fprintf(fid,
'%3d\t%d\t%d\t%9.5f\t%d\t%6.2f\t%6.2f\n', m, HDR.BurstTable(m,:) );
213 if (fid>3) fclose(fid); end;
217 if ~isempty(outFile) && exist(
's',
'var')
218 %%% write data to output
222 HDR.FileName = outFile;
224 HDR.Dur = 1/HDR.SampleRate;
225 HDR =
sopen(HDR,
'w');
226 if (HDR.FILE.FID < 0)
227 fprintf(2,
'Warning can not open file <%s> - GDF file can not be written\n',HDR.FileName);
236 %%% write data to output
239 %[p,f,e]=fileparts(fn);
241 HDR.FileName = evtFile;
245 HDR.Dur = 1/HDR.SampleRate;
246 HDR = rmfield(HDR,
'AS');
247 HDR =
sopen(HDR,
'w');
249 fprintf(2,
'Warning can not open file <%s> - EVT file can not be written\n',HDR.FileName);