


TuneArtefactTimes - Fine-tune artefact (e.g. stimulation) times.
  Fine tuning can be done using either the LFP (faster), or the wideband
  data (slower but more accurate). The latter is especially useful in cases
  where the artefacts are no longer visible in the LFP signal due to low-
  pass filtering.
  USAGE
    % Using LFP (pass the actual samples)
    times = TuneArtefactTimes(lfp,artefacts,<options>)
    % Using wideband data (pass the channel ID because the data would not fit
    % in memory, so it will have to be read piecewise from disk)
    times = TuneArtefactTimes(channel,artefacts,<options>)
    lfp            local field potential <a href="matlab:help samples">samples</a>
    channel        recording channel ID (wideband data)
    artefacts      approximate artefact times
    <options>      optional list of property-value pairs (see table below)
    =========================================================================
     Properties    Values
    -------------------------------------------------------------------------
     'method'      artefacts can be detected using either the derivative
                   ('slope', default) or the amplitude ('amplitude') of the
                   signal
     'durations'   interval (in s) around each approximate artefact time
                   where the actual artefact should be sought
                   (default = [-0.0075 0.0075])
     'verbose'     display information about ongoing processing
                   (default = 'off')
    =========================================================================
  SEE
    See also RemoveArtefacts.


0001 function tuned = TuneArtefactTimes(x,times,varargin) 0002 0003 %TuneArtefactTimes - Fine-tune artefact (e.g. stimulation) times. 0004 % 0005 % Fine tuning can be done using either the LFP (faster), or the wideband 0006 % data (slower but more accurate). The latter is especially useful in cases 0007 % where the artefacts are no longer visible in the LFP signal due to low- 0008 % pass filtering. 0009 % 0010 % USAGE 0011 % 0012 % % Using LFP (pass the actual samples) 0013 % times = TuneArtefactTimes(lfp,artefacts,<options>) 0014 % 0015 % % Using wideband data (pass the channel ID because the data would not fit 0016 % % in memory, so it will have to be read piecewise from disk) 0017 % times = TuneArtefactTimes(channel,artefacts,<options>) 0018 % 0019 % lfp local field potential <a href="matlab:help samples">samples</a> 0020 % channel recording channel ID (wideband data) 0021 % artefacts approximate artefact times 0022 % <options> optional list of property-value pairs (see table below) 0023 % 0024 % ========================================================================= 0025 % Properties Values 0026 % ------------------------------------------------------------------------- 0027 % 'method' artefacts can be detected using either the derivative 0028 % ('slope', default) or the amplitude ('amplitude') of the 0029 % signal 0030 % 'durations' interval (in s) around each approximate artefact time 0031 % where the actual artefact should be sought 0032 % (default = [-0.0075 0.0075]) 0033 % 'verbose' display information about ongoing processing 0034 % (default = 'off') 0035 % ========================================================================= 0036 % 0037 % SEE 0038 % 0039 % See also RemoveArtefacts. 0040 0041 % Copyright (C) 2008-2013 by Michaƫl Zugaro 0042 % 0043 % This program is free software; you can redistribute it and/or modify 0044 % it under the terms of the GNU General Public License as published by 0045 % the Free Software Foundation; either version 3 of the License, or 0046 % (at your option) any later version. 0047 0048 % Default values 0049 durations = [-0.0075 0.0075]; 0050 verbose = 'off'; 0051 nChunks = 100; 0052 method = 'slope'; 0053 0054 % Check number of parameters 0055 if nargin < 2 | mod(length(varargin),2) ~= 0, 0056 error('Incorrect number of parameters (type ''help <a href="matlab:help TuneArtefactTimes">TuneArtefactTimes</a>'' for details).'); 0057 end 0058 0059 % LFP or wideband? 0060 if isiscalar(x), 0061 source = 'wideband'; 0062 channel = x; 0063 else 0064 source = 'lfp'; 0065 lfp = x; 0066 if size(lfp,2) ~= 2, 0067 error('Parameter ''lfp'' is not a Nx2 matrix (type ''help <a href="matlab:help TuneArtefactTimes">TuneArtefactTimes</a>'' for details).'); 0068 end 0069 end 0070 0071 % Check parameter sizes 0072 if ~isdvector(times), 0073 error('Parameter ''times'' is not a vector (type ''help <a href="matlab:help TuneArtefactTimes">TuneArtefactTimes</a>'' for details).'); 0074 end 0075 0076 % Parse parameter list 0077 for i = 1:2:length(varargin), 0078 if ~ischar(varargin{i}), 0079 error(['Parameter ' num2str(i+1) ' is not a property (type ''help <a href="matlab:help TuneArtefactTimes">TuneArtefactTimes</a>'' for details).']); 0080 end 0081 switch(lower(varargin{i})), 0082 case 'durations', 0083 durations = varargin{i+1}; 0084 if ~isdvector(durations,'#2','<'), 0085 error('Incorrect value for property ''durations'' (type ''help <a href="matlab:help TuneArtefactTimes">TuneArtefactTimes</a>'' for details).'); 0086 end 0087 case 'method', 0088 method = lower(varargin{i+1}); 0089 if ~isastring(method,'slope','amplitude'), 0090 error('Incorrect value for property ''method'' (type ''help <a href="matlab:help Sync">Sync</a>'' for details).'); 0091 end 0092 case 'verbose', 0093 verbose = lower(varargin{i+1}); 0094 if ~isastring(verbose,'on','off'), 0095 error('Incorrect value for property ''verbose'' (type ''help <a href="matlab:help Sync">Sync</a>'' for details).'); 0096 end 0097 otherwise, 0098 error(['Unknown property ''' num2str(varargin{i}) ''' (type ''help <a href="matlab:help TuneArtefactTimes">TuneArtefactTimes</a>'' for details).']); 0099 0100 end 0101 end 0102 0103 % Discard duplicates 0104 cleaned = unique(times); 0105 if length(times) ~= length(cleaned), 0106 warning('Data contains duplicates - these will be discarded.'); 0107 end 0108 times = cleaned; 0109 0110 if strcmp(source,'lfp'), 0111 % Process LFP all at once 0112 % Time intervals where the artefacts should be sought 0113 intervals = [times+durations(1) times+durations(2)]; 0114 tuned = process(lfp,times,intervals,method,verbose); 0115 else 0116 % Split data in chunks 0117 start = times(1) + durations(1); 0118 stop = times(end) + durations(2); 0119 totalTime = stop-start; 0120 dt = totalTime/nChunks; 0121 tuned = []; 0122 for i = 1:nChunks, 0123 % Time intervals where the artefacts should be sought 0124 t = Restrict(times,[start start+dt]); 0125 if ~isempty(t), 0126 intervals = [t+durations(1) t+durations(2)]; 0127 data = GetWidebandData(channel,'intervals',[start start+dt]); 0128 tuned = [tuned;process(data,t,intervals,method,verbose)]; 0129 end 0130 start = start + dt; 0131 end 0132 end 0133 0134 % Actual processing 0135 0136 function tuned = process(signal,times,intervals,method,verbose) 0137 0138 % Differentiate signal 0139 if strcmp(method,'slope'), 0140 signal(:,2) = [0;diff(signal(:,2))]; 0141 end 0142 0143 % Select the samples within these intervals 0144 [in,i,j] = InIntervals(signal(:,1),intervals,'verbose',verbose); 0145 % Transform this into a matrix where each line contains the data for one artefact, and find minima 0146 m = full(sparse(i(i~=0),j(j~=0),signal(in,2))); 0147 infs = ~logical(full(sparse(i(i~=0),j(j~=0),1))); 0148 m(infs) = inf; 0149 [~,where] = min(m,[],2); 0150 % Build the same matrix for data timestamps 0151 t = full(sparse(i(i~=0),j(j~=0),signal(in,1))); 0152 % Times 0153 s1 = size(m,1); 0154 s2 = size(m,2); 0155 where = logical(full(sparse(1:s1,where,1,s1,s2))); 0156 tuned = sort(t(where));