diff --git a/docs/usage.rst b/docs/usage.rst index 629ab6a..f717f39 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -40,51 +40,201 @@ Fully automated sorting ``spikoclust_sort`` takes care of all the gory details for you, providing a wrapper for many key steps to spike sorting (extracting spikes, aligning, noise-whitening, cluster). If you want to perform each of these steps separately in the MATLAB command window (perhaps to pipe output to another program, eh em), see below. Here are all of the options you can pass to spikoclust_sort. Note that all options after the second option, the first two being the data matrix and the sampling rate, are as passed parameter/value pairs. -+--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------+-------------------+ -| Parameter | Description | Format | Options | Default | -+====================+==================================================================================+================================+=========================+===================+ -| ``noise_removal`` | Method of noise rejection (common average) | string | ``car,none`` | ``none`` | -+--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------+-------------------+ -| ``car_trim`` | If using common average, trim N/2 percent of data on each end before taking mean | float | N/A | ``40`` | -+--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------+-------------------+ -| ``freq_range`` | Frequency range for filtering | 1-2 element vector of floats | N/A | ``[400]`` | -+--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------+-------------------+ -| ``filt_type`` | Filter class | ``high,low,bandpass`` | string | ``high`` | -+--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------+-------------------+ -| ``filt_order`` | Filter order | integer | N/A | ``3`` | -+--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------+-------------------+ -| ``filt_name`` | Filter type | string | ``butter,ellip,kaiser`` | ``ellip`` | -+--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------+-------------------+ -| ``sigma_t`` | Detection threshold (multiple of robust standard deviation) | float | N/A | ``4`` | -+--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------+-------------------+ -| ``detect_method`` | Detect negative-going spikes, positive-going spikes, or both | string | ``n,p,b`` | | -+--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------+-------------------+ -| ``spike_window`` | Size of spike window (in s before and after spike) | 2 element vector of floats (s) | N/A | ``[.0005 .0005]`` | -+--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------+-------------------+ -| ``interp_f`` | Interpolation factor (interpolate spikes by a factor of N) | integer | N/A | ``8`` | -+--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------+-------------------+ -| ``align_feature`` | Feature used for spike re-alignment | string | ``min,max,com`` | ``min`` | -+--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------+-------------------+ -| ``jitter`` | Limit on number of samples a spike may be moved for re-alignment | integer | N/A | ``10`` | -+--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------+-------------------+ -| ``gui_clust`` | Use the GUI assistant | logic | N/A | ``1`` | -+--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------+-------------------+ -| ``clust_check`` | Number of spikes to check for | vector of integers | N/A | ``[2:8]`` | -+--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------+-------------------+ -| ``pcs`` | Number of principal components to compute/use | integer | N/A | ``2`` | -+--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------+-------------------+ -| ``garbage`` | Use a garbage component in the mixture to exclude outliers? | logic | N/A | ``1`` | -+--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------+-------------------+ -| ``smem`` | Use split-and-merge EM rather than standard EM? | logic | N/A | ``1`` | -+--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------+-------------------+ -| ``modelselection`` | Technique to use for selecting the number of neurons | string | ``icl,bic,aic`` | ``icl`` | -+--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------+-------------------+ -| ``maxnoisetraces`` | Maximum number of traces to use to compute noise covariance | integer | N/A | ``1e6`` | -+--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------+-------------------+ -| ``noisewhiten`` | Enable noise whitening? | logic | N/A | ``1`` | -+--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------+-------------------+ ++--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------------+-------------------+ +| Parameter | Description | Format | Options | Default | ++====================+==================================================================================+================================+===============================+===================+ +| ``noise_removal`` | Method of noise rejection (common average) | string | ``'car','none'`` | ``none`` | ++--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------------+-------------------+ +| ``car_trim`` | If using common average, trim N/2 percent of data on each end before taking mean | float | N/A | ``40`` | ++--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------------+-------------------+ +| ``freq_range`` | Frequency range for filtering | 1-2 element vector of floats | N/A | ``[400]`` | ++--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------------+-------------------+ +| ``filt_type`` | Filter class | ``high,low,bandpass`` | string | ``high`` | ++--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------------+-------------------+ +| ``filt_order`` | Filter order | integer | N/A | ``3`` | ++--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------------+-------------------+ +| ``filt_name`` | Filter type | string | ``'butter','ellip','kaiser'`` | ``'ellip'`` | ++--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------------+-------------------+ +| ``sigma_t`` | Detection threshold (multiple of robust standard deviation) | float | N/A | ``4`` | ++--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------------+-------------------+ +| ``detect_method`` | Detect negative-going spikes, positive-going spikes, or both | string | ``n,p,b`` | | ++--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------------+-------------------+ +| ``spike_window`` | Size of spike window (in s before and after spike) | 2 element vector of floats (s) | N/A | ``[.0005 .0005]`` | ++--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------------+-------------------+ +| ``interp_f`` | Interpolation factor (interpolate spikes by a factor of N) | integer | N/A | ``8`` | ++--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------------+-------------------+ +| ``align_feature`` | Feature used for spike re-alignment | string | ``'min','max','com'`` | ``'min'`` | ++--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------------+-------------------+ +| ``jitter`` | Limit on number of samples a spike may be moved for re-alignment | integer | N/A | ``10`` | ++--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------------+-------------------+ +| ``gui_clust`` | Use the GUI assistant | logic | N/A | ``1`` | ++--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------------+-------------------+ +| ``clust_check`` | Number of spikes to check for | vector of integers | N/A | ``[2:8]`` | ++--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------------+-------------------+ +| ``pcs`` | Number of principal components to compute/use | integer | N/A | ``2`` | ++--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------------+-------------------+ +| ``garbage`` | Use a garbage component in the mixture to exclude outliers? | logic | N/A | ``1`` | ++--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------------+-------------------+ +| ``smem`` | Use split-and-merge EM rather than standard EM? | logic | N/A | ``1`` | ++--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------------+-------------------+ +| ``modelselection`` | Technique to use for selecting the number of neurons | string | ``'icl','bic','aic'`` | ``'icl'`` | ++--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------------+-------------------+ +| ``maxnoisetraces`` | Maximum number of traces to use to compute noise covariance | integer | N/A | ``1e6`` | ++--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------------+-------------------+ +| ``noisewhiten`` | Enable noise whitening? | logic | N/A | ``1`` | ++--------------------+----------------------------------------------------------------------------------+--------------------------------+-------------------------------+-------------------+ Stepwise sorting ---------------- -UNDER CONSTRUCTION \ No newline at end of file +Denoising (optional) +^^^^^^^^^^^^^^^^^^^^ + +Assume you have loaded in a matrix of voltage traces, 40,0000 samples x 10 channels x 1 trial, as the variable ``data``. As a first step you may want to denoise the data using a command trimmed-average reference (this step is completely optional, feel free to skip to the next section if you just want to filter your data). This is achieved with ``spikoclust_denoise_signal``:: + + >>denoised_data=spikoclust_denoise(data,[],[],'car_exclude',5,'car_trim',40,'method','car'); + +The first option passed is the data itself, the second option is a vector specifying the channel numbers for the data (e.g. it could be 2-11 instead of 1-10), the second option specified which channel to output. Typically you'll simply want to simply leave this empty, which will include all channels and return all channels. All options after the third are passed as parameter/value pairs. + ++-----------------+----------------------------------------------------------------------------------+--------+-------------------------+----------+ +| Parameter | Description | Format | Options | Default | ++=================+==================================================================================+========+=========================+==========+ +| ``car_trim`` | If using common average, trim N/2 percent of data on each end before taking mean | float | N/A | ``40`` | ++-----------------+----------------------------------------------------------------------------------+--------+-------------------------+----------+ +| ``car_exclude`` | Channels to exclude from common average | int | N/A | ``[]`` | ++-----------------+----------------------------------------------------------------------------------+--------+-------------------------+----------+ +| ``method`` | Denoising method | string | ``'car'`` or ``'none'`` | ``none`` | ++-----------------+----------------------------------------------------------------------------------+--------+-------------------------+----------+ + +Filtering (optional) +^^^^^^^^^^^^^^^^^^^^ + +If you are working with broadband recordings, you will most likely want to filter out high frequency noise and local field potentials (content ``<300 (Hz)``). This is done through ``spikoclust_condition_signal``:: + + >>filtered_data=spikoclust_condition_signal(data,'single_unit','fs',fs); + +This will use the filter defaults for single unit data (2nd order Butterworth high-pass, corner frequency 800 Hz). They can be overridden using parameter/value pairs. All options after the second option are passed as parameter/value pairs. The second argument will change the defaults, e.g.:: + + >>filtered_data=spikoclust_condition_signal(data,'multi_unit','fs',fs); + +Will use filters more appropriate for multi-unit data. + ++---------------------+------------------------------------------------------------------+-------------------------------+--------------------------------------------+------------+ +| Parameter | Description | Format | Options | Default | ++=====================+==================================================================+===============================+============================================+============+ +| ``freq_range`` | filter corner(s) (Hz) | float (2 floats for bandpass) | N/A | ``800`` | ++---------------------+------------------------------------------------------------------+-------------------------------+--------------------------------------------+------------+ +| ``filt_order`` | filter order | int | N/A | ``2`` | ++---------------------+------------------------------------------------------------------+-------------------------------+--------------------------------------------+------------+ +| ``filt_name`` | name of filter type | string | ``'Butter','Kaiser','Elliptic','Wavelet'`` | ``Butter`` | ++---------------------+------------------------------------------------------------------+-------------------------------+--------------------------------------------+------------+ +| ``demean`` | Demean data? | logical | N/A | ``false`` | ++---------------------+------------------------------------------------------------------+-------------------------------+--------------------------------------------+------------+ +| ``rectify`` | Rectify data? | logical | N/A | ``false`` | ++---------------------+------------------------------------------------------------------+-------------------------------+--------------------------------------------+------------+ +| ``wavelet_denoise`` | Denoise data using a wavelet decomposition | logical | N/A | ``false`` | ++---------------------+------------------------------------------------------------------+-------------------------------+--------------------------------------------+------------+ +| ``decomp_level`` | Decomposition level for wavelet denoising (wavelet_denoise only) | int | N/A | ``7`` | ++---------------------+------------------------------------------------------------------+-------------------------------+--------------------------------------------+------------+ +| ``notch`` | Line filter frequency (Hz) | float | ``[] for no notch filter`` | ``[]`` | ++---------------------+------------------------------------------------------------------+-------------------------------+--------------------------------------------+------------+ +| ``notch_bw`` | Notch bandwidth | float | N/A | ``100`` | ++---------------------+------------------------------------------------------------------+-------------------------------+--------------------------------------------+------------+ +| ``ripple`` | Passband ripple (Elliptic,Kaiser only) | float | N/A | ``.2`` | ++---------------------+------------------------------------------------------------------+-------------------------------+--------------------------------------------+------------+ +| ``attenuation`` | Stopband attenuation (dB; Elliptic,Kaiser only) | float | N/A | ``40`` | ++---------------------+------------------------------------------------------------------+-------------------------------+--------------------------------------------+------------+ +| ``winsigma`` | Gaussian smoothing (sigma, in s) | float | ``[] for no smoothing`` | ``[]`` | ++---------------------+------------------------------------------------------------------+-------------------------------+--------------------------------------------+------------+ + +Spike detection +^^^^^^^^^^^^^^^ + +This is the first obligatory step in the pipeline: extracting spikes from continuous voltage traces using ``spikoclust_spike_detect``. To quickly get a reasonable threshold you can use the [Quirogaetal2004] rule. + +.. math:: \text{Threshold}=4\sigma_n\quad\sigma_n=median\left[\frac{|x|}{.6745}\right] + +To get the threshold use the following command:: + + >>threshold=4*median(abs(sort_data)/.6745); + +Then to detect spikes:: + + >>spikes=spikoclust_spike_detect(sort_data,threshold,fs,'window',[.001 .001],'method','b'); + +This will detect both positive and negative-going spikes and extract a 1 ms window to the left and right of the alignment event. If you want to visualize the spikes:: + + >>figure(); + >>plot(spikes.windows(:,1:100,1),'k-'); + +This will plot the first 100 spikes. Now we have a structure that we can use with the rest of the functions for clustering data. + +Noise whitening +^^^^^^^^^^^^^^^ + +Next we will whiten the noise of the data, a critical step pre-clustering (especially if the model assumes white noise!). First, we need a sample of noise. To approximate this we remove spikes from the voltage traces with ``spikeless_data``:: + + >>spikeless_data=spikoclust_spike_remove(sort_data,spikes); + +Copy the pre-whitened windows to a special field for display later on (the noise-whitened traces are less intuitive to look at):: + + >>spikes.storewindows=spikes.windows; + +Now whiten the spikes with ``spikoclust_noisewhiten``:: + + >>spikes=spikoclust_noisewhiten(spikes,spikeless_data); + >>figure(); + >>plot(spikes.windows(:,1:100,1),'k-') + +Upsampling and realignment +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Now the spikes must be upsampled and realigned with ``spikoclust_upsample_align``, then downsampled again before clustering:: + + >>spikes=spikoclust_upsample_align(spikes,'interpolate_fs',spikes.fs*8,'align_feature','max'); + +This upsamples the spikes by a factor of 8 and realigns them to the global max. + +Packaging tetrode data +^^^^^^^^^^^^^^^^^^^^^^ + +If you're working with tetrodes you'll need to reshape the spike windows (skip this step if you're working with single channel data):: + + >>spikes.windows=reshape(permute(spikes.windows,[1 3 2]),[],ntrials); + >>spikes.storewindows=reshape(permute(spikes.storewindows,[1 3 2]),[],ntrials); + +Study the new matrices to make sure you're good with everything. Spikes should now be concatenated end-to-end + +.. hint:: For tetrode data, spikes in channels 2-4 are slaved to spikes on channel 1. To slave to another channel, swap that channel with channel 1. + +Robust noise-whitened PCA +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Following the algorithm of [Sahanithesis]_, we now use a mixture model to perform PCA:: + + >>[spike_data,pcs,lam,pcamodel]=spikoclust_robpca(spikes.windows',6); + +This returns ``spike_data``, the projection into PC space, ``pcs`` the principal components, the eigenvalues ``lam``, and the model structure ``pcamodel``. + +Fitting a Gaussian mixture model +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A Gaussian mixture model is fit using the split-and-merge algorithm [Uedaetal2000]_ with ``spikoclust_gmmsort``:: + + >>[spike_labels cluster_data cluster_model]=spikoclust_gmmsort(spike_data,'smem',1,'garbage',1,'cluster_check',[1:5],'modelselection','icl'); + +``spike_labels`` is a vector of labels for each spike in ``spikes.windows``, ``cluster_data`` is the data used for clustering, ``cluster_model`` is a structure with the estimated GMM. + +Manual cluster cutting +^^^^^^^^^^^^^^^^^^^^^^ + +Alternatively, a GUI can be used to perform a cluster cut using ``spikoclust_guisort``:: + + >>[labels model]=spikoclust_guisort(spikes,'pcs',[1:5]); + +This will call up a GUI and use the first 5 PCs. Once you're happy with the clustering, simply close the Data Plotter. + +.. [Quirogaetal2004] `Unsupervised Spike Detection and Sorting with Wavelets and Superparamagnetic Clustering `_ +.. [Sahanithesis] `Latent Variable Models for Neural Data Analysis `_ +.. [Uedaetal2000] `Split and Merge EM Algorithm for Improving Gaussian Mixture Density Estimates `_ + diff --git a/helpers/spikoclust_autosort.m b/helpers/spikoclust_autosort.m index 9c5383b..37325a3 100644 --- a/helpers/spikoclust_autosort.m +++ b/helpers/spikoclust_autosort.m @@ -68,14 +68,12 @@ if gap_check gap_stats=evalclusters(SPIKE_DATA,'kmeans','gap','klist',clust_check); - gap_stats clust_check=[gap_stats.OptimalK-1:gap_stats.OptimalK+1]; - clust_check end [idx CLUSTER_DATA MODEL]=spikoclust_gmmsort(SPIKE_DATA,... 'smem',smem,'garbage',garbage,'clust_check',clust_check,... - 'pcs',pcs,'workers',workers,'modelselection',modelselection,'outlierpoints',outlierpoints); + 'workers',workers,'modelselection',modelselection,'outlierpoints',outlierpoints); MODEL.features=PCS; features=size(CLUSTER_DATA,2); % what's the dimensionality of the data used for sorting? diff --git a/helpers/spikoclust_cluster_quality.m b/helpers/spikoclust_cluster_quality.m index 1cbc163..ae30671 100644 --- a/helpers/spikoclust_cluster_quality.m +++ b/helpers/spikoclust_cluster_quality.m @@ -4,6 +4,7 @@ % % + nmodels=size(MODEL.mu,1); clusters=unique(LABELS(LABELS>0)); % how many clusters? diff --git a/helpers/spikoclust_denoise_signal.m b/helpers/spikoclust_denoise_signal.m index 3e9026f..9624e98 100644 --- a/helpers/spikoclust_denoise_signal.m +++ b/helpers/spikoclust_denoise_signal.m @@ -5,6 +5,10 @@ % % +ndims_ephys=ndims(EPHYS_DATA); +[samples,ntrials,nchannels]=size(EPHYS_DATA); + +if nargin<2 | isempty(CHIN), CHIN=1:nchannels; end if nargin<3 | isempty(CHOUT), CHOUT=CHIN; end nparams=length(varargin); @@ -41,9 +45,6 @@ end car_electrodes=setdiff(1:length(CHIN),exclude_channels); % which electrodes are good for CAR? -ndims_ephys=ndims(EPHYS_DATA); - -[samples,ntrials,nchannels]=size(EPHYS_DATA); % map each channel appropriately @@ -99,6 +100,3 @@ end end - - - diff --git a/helpers/spikoclust_gmmsort.m b/helpers/spikoclust_gmmsort.m index 0567fd8..983059e 100644 --- a/helpers/spikoclust_gmmsort.m +++ b/helpers/spikoclust_gmmsort.m @@ -23,8 +23,6 @@ clust_check=varargin{i+1}; case 'clustreplicates' clustreplicates=varargin{i+1}; - case 'pcs' - pcs=varargin{i+1}; case 'garbage' garbage=varargin{i+1}; case 'workers' diff --git a/helpers/spikoclust_guisort.m b/helpers/spikoclust_guisort.m index 36f649b..0ce7e3c 100644 --- a/helpers/spikoclust_guisort.m +++ b/helpers/spikoclust_guisort.m @@ -16,11 +16,11 @@ % all features excluding IFR and SPIKES.times -features_all={'max','min','ne','^2','neo','wid','pgrad','ngrad','PC1','PC2','PC3','PC4'}; -features={'PCA','pose','nege','posgrad','neggrad','min','max','width','ISI'}; +features_all={'max','min','ne','^2','neo','wid','pgrad','ngrad','PC1','PC2','PC3','PC4'}; +features={'PCA','pose','nege','posgrad','neggrad','min','max','width','ISI'}; % possible features include, min, max, PCA, width, energy and wavelet coefficients - + channel_labels=[]; colors={'b','r','g','c','m','y','r','g','b'}; outliercolor='k'; @@ -78,7 +78,7 @@ if nchannels==1 geom_features=spikoclust_shape_features(SPIKES.windows); - + if any(strcmp('max',lower(features))) spike_data=[spike_data geom_features(:,1)]; property_names{end+1}='max'; @@ -424,10 +424,9 @@ function change_cluster(varargin) LABELS=zeros(size(idx)); for i=1:nclust - LABELS(idx==clusters(loc(i)))=i; + LABELS(idx==clusters(loc(i)))=i; end - clustermodel.R(:,1:nclust)=clustermodel.R(:,loc); clustermodel.mixing(1:nclust)=clustermodel.mixing(loc); clustermodel.sigma=clustermodel.sigma(:,:,loc); @@ -451,6 +450,11 @@ function change_cluster(varargin) legend_labels{end+1}='Outliers'; end + +if all(LABELS==0) + LABELS=ones(size(LABELS)); +end + % compute any other stats we want, ISI, etc... [WINDOWS TIMES TRIALS SPIKEDATA ISI STATS]=... spikoclust_cluster_quality(SPIKES.storewindows,SPIKES.times,CLUSTER_DATA,LABELS,SPIKES.trial,MODEL); diff --git a/helpers/spikoclust_robpca.m b/helpers/spikoclust_robpca.m index d79bb64..5b871a8 100644 --- a/helpers/spikoclust_robpca.m +++ b/helpers/spikoclust_robpca.m @@ -1,14 +1,19 @@ -function [PROJ,PCS,LAMBDA,MODEL]=cov_check(DATA,REPLICATES) +function [PROJ,PCS,LAMBDA,MODEL]=spikoclust_robpca(DATA,K,REPLICATES) % % % % % -if nargin<2 + +if nargin<3 | isempty(REPLICATES) REPLICATES=10; end +if nargin<2 | isempty(K) + K=6; +end + likelihood=zeros(1,REPLICATES); for i=1:REPLICATES tmp_newmodel{i}=spikoclust_gmem(DATA,[],1,'garbage',1,'merge',0,'debug',0,'display_mode',0); @@ -19,7 +24,7 @@ [~,loc]=max(likelihood); MODEL=tmp_newmodel{loc(1)}; -[PCS,LAMBDA]=eigs(MODEL.sigma(:,:,1)); +[PCS,LAMBDA]=eigs(MODEL.sigma(:,:,1),K); LAMBDA=diag(LAMBDA); [~,idx]=sort(LAMBDA,'descend'); PCS=PCS(:,idx); diff --git a/helpers/spikoclust_spike_detect.m b/helpers/spikoclust_spike_detect.m index d1d242c..ecc58c7 100644 --- a/helpers/spikoclust_spike_detect.m +++ b/helpers/spikoclust_spike_detect.m @@ -12,12 +12,18 @@ % threshold for detecting spikes (can pass a vector where each element corresponds to threshold for trial) % + + SPIKES=[]; if nargin<1 error('Need the input data to continue!'); end +if isvector(DATA) + DATA=DATA(:); +end + %%%%%%%%%%%%%%%%%%%%%%%%%%% % input argument collection diff --git a/helpers/spikoclust_spike_remove.m b/helpers/spikoclust_spike_remove.m index 998f0eb..49aa3f8 100644 --- a/helpers/spikoclust_spike_remove.m +++ b/helpers/spikoclust_spike_remove.m @@ -5,6 +5,9 @@ % % +if isvector(DATA) + DATA=DATA(:); +end nspikes=length(SPIKES.times); edges=round(SPIKES.frame*SPIKES.fs); @@ -51,4 +54,3 @@ SPIKELESS(counter:counter+nsamples)=DATA(coords(i,1):coords(i,2),coords(i,3)); counter=counter+nsamples+1; end - diff --git a/spikoclust_sort.m b/spikoclust_sort.m index 163babb..9fad497 100644 --- a/spikoclust_sort.m +++ b/spikoclust_sort.m @@ -301,7 +301,7 @@ spikes=spikoclust_noisewhiten(spikes,spikeless,'maxnoisetraces',maxnoisetraces); end -% upsample and align, then downsample and whiten!!! +% upsample and align, then downsample for sorting!!! spikes=spikoclust_upsample_align(spikes,'interpolate_fs',interpolate_fs,'align_feature',align_feature); [nsamples,ntrials,nchannels]=size(spikes.windows);