Git Product home page Git Product logo

kilosort's Introduction

Kilosort4

Documentation Status tests PyPI version Downloads Downloads Python version Licence: GPL v3 Contributors repo size GitHub stars GitHub forks

You can run Kilosort4 without installing it locally using google colab. An example colab notebook is available here: Open In Colab. It will download some test data, run kilosort4 on it, and show some plots. Talk describing Kilosort4 is here.

Example notebooks are provided in the docs/source/tutorials folder and in the docs. The notebooks include:

  1. basic_example: sets up run on example data and shows how to modify parameters
  2. load_data: example data format conversion through SpikeInterface
  3. make_probe: making a custom probe configuration.

If you use Kilosort1-4, please cite the paper:
Pachitariu, M., Sridhar, S., Pennington, J., & Stringer, C. (2024). Spike sorting with Kilosort4.

Reusing parameters from previous versions: This probably will not work well. Kilosort4 is a new algorithm, and the main parameters (the thresholds) can affect the results in a different way for your data. Please start with the default parameters and adjust from there based on what you see in Phy. For descriptions of Kilosort4's parameters, you can mouse-over their names in the GUI or look at kilosort.parameters.py.

Running Kilosort4 with SpikeInterface: We do not provide support for SpikeInterface, and are not involved in their development (or vise-versa). If you encounter problems running Kilosort4 through SpikeInterface, please try running Kilosort4 directly instead. In particular, the KS4 GUI is a useful tool for checking that your probe and data are formatted correctly.

Warning ‼️: There were two bugs in Kilosort 2, 2.5 and 3 (but not 4) which caused fewer spikes to be detected in ~7ms periods at batch boundaries (every 2.1866s, issue #594). The patch1 releases fix these bugs, please use the new default NT and ntbuff parameters.

Installation

System requirements

Linux and Windows 64-bit are supported for running the code. At least 8GB of GPU RAM is required to run the software (see docs for more recommendations). The software has been tested on Windows 10 and Ubuntu 20.04.

Instructions

If you have an older kilosort environment you can remove it with conda env remove -n kilosort before creating a new one.

  1. Install an Anaconda distribution of Python. Note you might need to use an anaconda prompt if you did not add anaconda to the path.
  2. Open an anaconda prompt / command prompt which has conda for python 3 in the path
  3. Create a new environment with conda create --name kilosort python=3.9. Python 3.10 should work as well.
  4. To activate this new environment, run conda activate kilosort
  5. To install kilosort and the GUI, run python -m pip install kilosort[gui]. If you're on a zsh server, you may need to use ' ' around the kilosort[gui] call: `python -m pip install 'kilosort[gui]'.
  6. Instead of 5, you can install the minimal version of kilosort with python -m pip install kilosort.
  7. Next, if the CPU version of pytorch was installed (will happen on Windows), remove it with pip uninstall torch
  8. Then install the GPU version of pytorch conda install pytorch pytorch-cuda=11.8 -c pytorch -c nvidia

Note you will always have to run conda activate kilosort before you run kilosort. If you want to run jupyter notebooks in this environment, then also conda install jupyter or pip install notebook, and python -m pip install matplotlib.

Debugging pytorch installation

If step 8 does not work, you need to make sure the NVIDIA driver for your GPU is installed (available here). You may also need to install the CUDA libraries for it, we recommend CUDA 11.8.

If pytorch installation still fails, follow the instructions here to determine what version of pytorch to install. The Anaconda install is strongly recommended on Windows, and then choose the CUDA version that is supported by your GPU (newer GPUs may need newer CUDA versions > 10.2). For instance this command will install the 11.8 version on Linux and Windows (note the torchvision and torchaudio commands are removed because kilosort doesn't require them):

conda install pytorch pytorch-cuda=11.8 -c pytorch -c nvidia

This video has step-by-step installation instructions for NVIDIA drivers and pytorch in Windows (ignore the environment creation step with the .yml file, we have an environment already, to activate it use conda activate kilosort).

Running kilosort

  1. Open the GUI with python -m kilosort
  2. Select the path to the binary file and optionally the results directory. We recommend putting the binary file on an SSD for faster processing.
  3. Select the probe configuration (mat files recommended, they actually exclude off channels unlike prb files)
  4. Hit LOAD. The data should now be visible.
  5. Hit Run. This will run the pipeline and output the results in a format compatible with Phy, the most popular spike sorting curating software.

Debugging qt.qpa.plugin error

Some users have encountered the following error (or similar ones with slight variations) when attempting to launch the Kilosort4 GUI:

QObject::moveToThread: Current thread (0x2a7734988a0) is not the object's thread (0x2a77349d4e0).
Cannot move to target thread (0x2a7734988a0)

qt.qpa.plugin: Could not load the Qt platform plugin "windows" in "<FILEPATH>" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

Available platform plugins are: minimal, offscreen, webgl, windows.

This is not specific to Kilosort4, it is a general problem with PyQt (the GUI library we chose to develop with) that doesn't appear to have a single cause or fix. If you encounter this error, please check issue 597 and issue 613 for some suggested solutions.

Integration with Phy GUI

Phy provides a manual clustering interface for refining the results of the algorithm. Kilosort4 automatically sets the "good" units in Phy based on a <10% estimated contamination rate with spikes from other neurons (computed from the refractory period violations relative to expected).

Check out the Phy repo for more install instructions. We recommend installing Phy in its own environment to avoid package conflicts.

After installation, activate your Phy environment and navigate to the results directory from Kilosort4 (by default, a folder named kilosort4 in the same directory as the binary data file) and run:

phy template-gui params.py

Developer instructions

To get the most up-to-date changes to the code, clone the repository and install in editable mode in your Kilosort environment, along with the other installation steps mentioned above.

git clone [email protected]:MouseLand/Kilosort.git
conda activate kilosort
pip install -e Kilosort[gui]
pip uninstall torch
conda install pytorch pytorch-cuda=11.8 -c pytorch -c nvidia

For unit testing, you will need to install pytest

pip install pytest

Then run all tests with:

pytest --runslow

To run on GPU:

pytest --gpu --runslow

Omitting the --runslow flag will only run the faster unit tests, not the slower regression tests.

kilosort's People

Contributors

agbondy avatar apjanke avatar bryzgalovdm avatar carsen-stringer avatar czuba avatar danieljdenman avatar dimokaramanlis avatar djoshea avatar geffenlab avatar jacobpennington avatar jd730 avatar jennifercolonell avatar joseguzman avatar jpellman avatar kouichi-c-nakamura avatar kushbanga avatar m-beau avatar mari-sosa avatar marius10p avatar mspacek avatar mwawra avatar nsteinme avatar oliche avatar pbotros avatar rajatsaxena avatar rossant avatar shashwatsridhar avatar thejanzimmermann avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kilosort's Issues

Kilosort2 misses large spikes

I have been trying to fine-tune Kilosort2 parameters with some of our ex-vivo multielectrode array recordings from the retina. Compared to Kilosort, our main issue is that many of the high amplitude spikes are not be assigned to any unit.

Here are some examples (from 2 recordings) of clear spikes (TraceView) left unassigned:

missed
missed2_exp2
missed2_exp2

We use arrays with 252 electrodes, sample at 10kHz, and record for long periods (four to ten hours). The inter-electrode distance is quite large (100 um), so often spikes are captured by only a few electrodes (one to three). As they are ex-vivo, our recordings show usually slow drift (spike amplitude changing slowly). Batch reordering from two example recordings:

drift_correction

drift_correction2

To adapt the algorithm to our lower sampling rate, I set (ops.nt0, ops.nt0min, ops.NT) to (25, 8, 64*512+ ops.ntbuff). Starting from the rest of the default Kilosort2 parameters, I have tried turning off batch reordering, setting minFR to 0 (to avoid template deletion), lowering thresholds (ops.Th), but nothing seems to alleviate our problem. Lower thresholds give more spikes and units, but there are still large spikes that are not detected.

Do you have any suggestions on what I could try next? In principle, I could go back to the original Kilosort, but I guess only Kilosort2 will continue to be developed...

channel numbers are not corrected after removal of bad channels

Once kilosort2 removes bad channels, the channel ID (number) of consecutive channels changes. For instance, if there is a cluster which has its max spike amplitude on channel 100, and kilosort2 has removed channels 10-20 as bad channels, now it appears as if this cluster is closest to channel 90. I can force kilosort2 to use all channels as suggested before but would be nice to use this option and still be able to get the correct channel number at the end.

Adding support for uint16 data?

We're currently saving data in uint16 files because that's the native output from Intan chips. I assume this goes for many ADCs. Would it make sense to you guys to add an option to switch preprocessDataSub from assuming int16 to a uint16 with a (2^16)/2 offset? Looks to me like that would be a very easy addition?

We could of course patch our copy of kilosort, or (as we do now) just convert our files separately, but that seems messier than having a config flag for these cases.

Magic numbers that cause Kilosort2 to crash

Hi Kilosort2 team,

I am looking forward to using the new algorithm. I tried to run Kilosort2 with 252-electrode data, recorded at 10k sampling rate. I set the template length (nt0) to 25 in the config file. However, I encountered errors in different steps of the algorithm, and tried to pinpoint them.

  1. For a small number of batches (I had 195), the indices are out of range. So maybe 1:200 can be 1:min([200 size(cc,1)]). https://github.com/MouseLand/Kilosort2/blob/627bf32d1c3e634b4a32136d15584a664851440a/preProcess/sort_by_rastermap.m#L10

  2. Matrix multiplication doesn't work here, because wPCAd is 61x3, while the first dimension of dWU is nt0 (25). I think this happens because of 61 appearing as a number in multiple places, where it should be nt0.
    https://github.com/MouseLand/Kilosort2/blob/627bf32d1c3e634b4a32136d15584a664851440a/mainLoop/learnAndSolve8b.m#L121

  3. https://github.com/MouseLand/Kilosort2/blob/627bf32d1c3e634b4a32136d15584a664851440a/mainLoop/extractPCfromSnippets.m#L13

  4. https://github.com/MouseLand/Kilosort2/blob/627bf32d1c3e634b4a32136d15584a664851440a/mainLoop/extractTemplatesfromSnippets.m#L13-L17

  5. Below, except for 61, there's also 20 (should be nt0min?).
    https://github.com/MouseLand/Kilosort2/blob/627bf32d1c3e634b4a32136d15584a664851440a/mainLoop/get_SpikeSample.m#L6-L10

  6. From its value, nt0max seems to be the same as nt0min here, maybe a different name could help?
    https://github.com/MouseLand/Kilosort2/blob/627bf32d1c3e634b4a32136d15584a664851440a/mainLoop/getKernels.m#L4

Good luck with adding the final touches, thank you for the great tool!

Best,
Dimos

CUDA ERROR Illegal Address

Hi,

I have tried to run kilosort2 on Ubuntu 16.04, CUDA 9.0, G++ 7.3 using a V100 and on WIN10, CUDA 9.0, MSVS2013 using a 1060. In both machines, I get the following crash:

Error using mexSVDsmall2
An unexpected error occurred during CUDA execution. The CUDA error was:
CUDA_ERROR_ILLEGAL_ADDRESS

Error in learnAndSolve8b (line 141)
    [W, U, mu] = mexSVDsmall2(Params, dWU, W, iC-1, iW-1, Ka, Kb);

Any ideas?

Best,
Noah

Conversion to logical from gpuArray is not possible.

Hi!

First of all thanks for the amazing tool :)

I'm trying to set it up in SpikeInterface (https://github.com/SpikeInterface), a toolbox for easily running and comparing several sorters. Kilosort2 is implemented here: https://github.com/SpikeInterface/spiketoolkit/tree/kilosort2/spiketoolkit/sorters/kilosort2

It runs fine on simulated data until I get this error:

Time   0s. Determining good channels.. 
Warning: The CUDA driver must recompile the GPU libraries because your device
is more recent than the libraries. Recompiling can take several minutes. 
> In get_good_channels (line 20)
  In preprocessDataSub (line 27)
  In kilosort2_master (line 20)
  In run (line 91) 
found 3473 threshold crossings in 201.17 seconds of data 
found 0 bad channels 
Time   3s. Computing whitening matrix.. 
Getting channel whitening matrix... 
Channel-whitening filters computed. 
Time   4s. Loading raw data and applying filters... 
Time   6s. Finished preprocessing 275 batches. 
Obtained 7 PC waveforms in 0.17 seconds 
time 0.16, pre clustered 1 / 275 batches 
time 0.01, compared 1 / 275 batches 
time 3.55, Re-ordered 275 batches. 
Time   4s. Optimizing templates ...
Conversion to logical from gpuArray is not possible.

Error in median (line 153)
        if isnan(x(nCompare))        % Check last index for NaN

Error in learnAndSolve8b (line 263)
            toc, ibatch, niter, Nfilt, sum(nsp), median(mu), numel(st0), ndrop)

Error in kilosort2_master (line 26)
rez = learnAndSolve8b(rez);

I was able to run the eMouse_drift example and I'm running on Ubuntu 18.05, CUDA 9.1, MATLAB 2018b.

Have you experienced this error before?

Thanks!
Alessio

GUI error when updating number channels to be plotted

I found when using a small number of channels that the scroll options in the GUI error when you include all the channels in traceview. To fix this, I added the following after line 1255:

if nCh>numel(cm.chanMap) nCh = numel(cm.chanMap); end

clusterSingleBatches crashes

When running kilosort on a 32 channel recording W0 in clusterSingleBatches is not defined.

It's because this line: W0 = gpuArray.zeros(nPCs, NchanNear, Nfilt, 'single');
only happens if size(uproj,2)>=Nfilt

and this [uproj, call] = extractPCbatch2(rez, wPCA, min(nBatches-1, ibatch), iC); produces a 51X11 uproj matrix.

Have you got any ideas why that might happen? I left the configuration as it is.

Thanks!

Max number of filters per channel?

I'm trying to figure out what the ops.nfilt_factor parameter does. It seems like it tries to limit the number of clusters assigned to each channel. By default, it's set at 4, but I'm not sure what that means. Does that mean that each channel can at max have 4 clusters assigned to it (seems unlikely, I often get many clusters for a given channel):

ErrorMessage: Error using gpuArray/subsasgn Matrix index is out of range for deletion.

Hi,

thank you very much for your great work!

I am just testing kilosort2 on a dataset that I was previously clustering successfully with Kilosort1. Its a 30 min recording with a 2times8 buzsaki probe at 20kHz. I was setting the ChanMap file as for Kilosort1 and also the config file is with default settings except fs.

here is the command out put and also starting to get 2 output figures plotting:

master_kilosort2
Looking for data inside C:\DATA\Kilosort2_test
Time 0s. Determining good channels..
found 25835 threshold crossings in 113.69 seconds of data
found 0 bad channels
Time 11s. Computing whitening matrix..
Getting channel whitening matrix...
Channel-whitening filters computed.
Time 12s. Loading raw data and applying filters...
Time 16s. Finished preprocessing 70 batches.
Obtained 7 PC waveforms in 0.37 seconds
time 0.28, pre clustered 1 / 70 batches
time 0.09, compared 1 / 70 batches
time 2.18, Re-ordered 70 batches.
Time 2s. Optimizing templates ...
2.80 sec, 1 / 142 batches, 3 units, nspks: 0.1469, mu: 10.0000, nst0: 1, merges: 0.1000, 0.0000
Error using gpuArray/subsasgn
Matrix index is out of range for deletion.

Error in triageTemplates2 (line 7)
W(:,idrop,:) = [];

Error in learnAndSolve8b (line 188)
triageTemplates2(ops, iW, C2C, W, U, dWU, mu, nsp, ndrop);

Error in master_kilosort2 (line 39)
rez = learnAndSolve8b(rez);

Here, is the error in debug, it seems to complete the first out of 142 batches, but crashed when doing the second;

triageTemplates2 Line 7, W(:,idrop,:) = [];
W: 61 x 12 x 3 GPU array
idrop: 12 x 12 GPU array

Thank you very much for your help!

Best wishes,
Michael

List Matlab minimum compatible version

KS2 makes heavy use of automatic broadcasting of array operations instead of bsxfun.
It is thus incompatible with Matlab earlier versions than r2016b.
Could we mention this in the installation guide ?

What are plotted on feature view with KS2 results?

Hello,

I've tried kilosort2 and got very positive impact. I don't see double spike templates any more, and drift tracking seems working well. Thanks for sharing such great software.

But now, when loading kilosort2 results to phy, I get confused what is shown on feature views, and what similarity means.

Kilosort2 gives a cluster, whose feature view has two subsets.
175_feature

Features are heterogeneous, but the waveforms seem homogenous.
2019-03-06 9 53 52

After splitting them manually, waveforms are still similar at least on ch 80 and 81, but templates are different.
175_feature-split
175-waveform-split
175-template-split

Also I can see the red cluster has two types of waveforms on ch 78 and 79, but features are uniform on these channels.
175-feature-ch78-79

I thought PC scores of waveforms are shown on feature views, but if so why similar units appear separated?
Also I thought similarity measures how templates are similar, but blue and red ones have high similarity with distinct templates. Are the similarity based on waveform itself, rather than templates?

Another example.
This case, kilosort2 gives 3 different units. Blue units are distant from others on feature view.
257-258-264_feature
But waveforms are very similar, and again, templates are different.
257-258-264-waveform
257-258-264-template

In this case similarity is low although waveforms are similar.

Now I get lost what is plotted on feature views, and of what similarity is shown.

Input data and Kilosort GUI

Hi,

I have started to use Kilosort2 to sort the data gather using TDT, but have had many difficulties when setting everything up. The first difficulty I am having is when I transform the data from .mat to .bin using fwrite(fidOut, datae_f, 'int16'); the data gets downsample, most values are transformed to 0. Therefore the sorting of the data is done incorrectly giving me in most channels an error of bad channel, and when plotted using phy the signal looks like small pulses across time.

The values are presented in micro Volts ranges. I multiply the values by 10000, and got an improvement in the shape of the signal and the sorting but kept observing down sampling on the data. In the other hand when I multiplied by larger values the signal start looking over saturated. Any recommendations towards the input data?

The second issue I am having is when I tried to use the new Kilosort Gui. The first error that showed was that I needed to download the Adds On "GUI Layout Toolbox" after doing this the error change to "No constructor 'handle.listener' with matching signature found"

any suggestions?

Thanks

Strange templates for non neuropixel data

When using Kilosort2 for data acquired with a Neuralynx probe, the extracted templates often do not match the mean waveforms, like in the attached examples. (I pulled these examples from within template-gui from phy) This does not seem to be the case when using Kilosort1 on the same data (or using Kilosort2 on Neuropixel data). Any idea what could cause this?
waveform_68

waveform_24

kslabel good in Phy

The quoted documentation below makes it appear that when KS2 is done and results are saved using the Kilosort GUI, the 'good' units should be labeled as such when the results are opened in Phy. I installed yesterday (March 22, 2019) in Windows 10, according to the Phy install instructions and I am not seeing any labeling. I have found the cluster_KSlabel.tsv and can interpret this in MATLAB, but am not certain how to inform Phy about it's existence. Is this not fully implemented yet or am I missing something in my setup or data management?

Kilosort2 automatically sets the "good" units in Phy based on a <20% estimated contamination rate with spikes from other neurons (computed from the refractory period violations relative to expected).

radix_sort: failed to get memory buffer in get_good_channels line 51

Hi,

For some reason, PreProccessSub fails (without error message) when calling get_good_channels. If I run the problematic lines of code from get_good_channels in the command window I can get to the final output:

found 4921 threshold crossings in 52.44 seconds of data 
found 0 bad channels 

but when I try to execute the function, I get the radix_sort error in the title.

Any ideas?

Thanks,
Noah

Kilosort crashes computer

Hi
We have now run a couple of times into the situation where during sorting, the computer just shuts down unexpectedly. I haven't yet figured out yet the underlying error, all I can find in the system logs is: The system has rebooted without cleanly shutting down first (Event ID 41). Strangely, the sorting usually runs without issue on the second attempt. I was wondering if anyone else has experienced something similar?

Maximum variable size is exceeded vs. memory error.

I'm getting a max variable size error here on a long-ish recording (~7hrs) that seems to come from a large value of nBatches:
time 1591.36, pre clustered 48001 / 48215 batches Error using gpuArray.zeros Maximum variable size allowed on the device is exceeded. Error in clusterSingleBatches (line 111) ccb = gpuArray.zeros(nBatches, 'single');

I am using ops.ntbuff = 64; ops.NT = 32*1024+ ops.ntbuff; , and if I increase NT i'm starting to get out of memory errors. Does this impose a restriction on total recording duration unless I grab a card with more ram or is there some way to circumvent this limit?

Channel Number Changes

Hello.

When running kilosort2 in our raw data we end up getting sorted spikes in less channels than originally recorded from in our actual raw data. We import the channel info in the gui but we only get around 70 from our total of 270 channels. Any ideas why this happens and how we could deal with it?
Thanks!

Can we stop plotting?

The repeated plotting means I basically can't effecitively use other programs at the same time - typing in other program gets put into matlab whenever a matlab fig gets popped up, which then calls over the matlab mainwindow. How can plotting be turned off or delayed until the end of the kilosort run?

Double-counted spikes

It seems like there's a tradeoff between Kilosort's spike threshold and the frequency of putative double-counted spikes. Presumably, this results from spike residuals getting fit by the same template or a different template on the same set of channels. So, the lower the threshold, the higher the likelihood that a residual will get counted as a different spike. Here's an example of a pair of units that has a lots of overlapping spikes at zero time lag, which is unlikely to be physiological:

double-counting_example_sort1_574_326

The good news is that the latest version of Kilosort is performing much better than previously when it comes to double-counting. Even with a lower threshold (ops.Th = [10 4] vs. [12 12] previously), the percentage of units with large zero-lag ACG peaks drops from 10% to 3%. But because false-positive zero-lag synchrony is so dangerous, it would be advantageous to reduce double-counting even further.

A few questions:

  • Do other people see this as well? The easiest way to visualize it in phy is by selecting a block of units from nearby channels and looking for pairs with abnormally large peaks at 0.
  • Are there any parameters besides ops.Th that would help reduce double counting? I tried changing ops.lam to 40, but it didn't have much of an effect.
  • Does double-counting always happen on the last pass, after the residuals are subtracted? Or can the same spike be fit by multiple templates during the main sort?
  • Would it be possible to flag spikes with highly overlapping templates that are detected within +/-2 samples? Nick suggested notifying the user about undetected spikes in #3, and I think adding information about potential double-counted spikes could also be helpful.

learnAndSolve8b (line 332) - Error using gpuArray/subsref Index exceeds matrix dimension.

Hi,

I'm trying to get Kilosort2 to working using the classic method of scripts. For the chanMap, I'm using the same as in Kilosort1 and the config file with the new changes.

I'm running Kilosort2 as a compiled binary since it's meant to be executed in a cluster. It shouldn't be a problem since it worked fine with Kilosort1.

Here is the output of the crash,

ops =
struct with fields:
chanMap: 'neuropixPhase3A_kilosortChanMap.mat'
fbinary: '/tmp/myRun_g4_t0.imec.ap.bin'
datatype: 'bin'
NchanTOT: 385
fproc: 'temp_wh.dat'
fs: 30000
fshigh: 150
minfr_goodchannels: 0.1000
Th: [10 4]
lam: 10
AUCsplit: 0.9000
minFR: 0.0200
momentum: [20 400]
sigmaMask: 30
ThPre: 8
spkTh: -6
GPU: 1
nfilt_factor: 4
ntbuff: 64
NT: 65600
whiteningRange: 32
nSkipCov: 25
scaleproc: 200
nPCs: 3
useRAM: 0
trange: [0 Inf]

Time 0s. Determining good channels..
found 19227 threshold crossings in 29.04 seconds of data
found 55 bad channels
Time 6s. Computing whitening matrix..
Getting channel whitening matrix...
Channel-whitening filters computed.
Time 48s. Loading raw data and applying filters...
Time 51s. Finished preprocessing 14 batches.
Obtained 7 PC waveforms in 0.79 seconds
time 0.93, pre clustered 1 / 14 batches
time 0.21, compared 1 / 14 batches
time 4.91, Re-ordered 14 batches.
Time 5s. Optimizing templates ...
6.86 sec, 1 / 30 batches, 57 units, nspks: 7.9294, mu: 16.7608, nst0: 110, merges: 0.0000, 0.0000
memorized middle timepoint
reverted back to middle timepoint
Elapsed time is 10.237392 seconds.

ntot =

    9252

Error using gpuArray/subsref
Index exceeds matrix dimension.

Error in learnAndSolve8b (line 332)

Error in kilosort_main (line 78)

parallel:array:SubsrefSubscriptExceedsDim

Any idea on what's causing the error?
Thanks!

CPU

Can Kilosort2 be run on the CPU side?

Max number of filters per channel?

I'm trying to figure out what the ops.nfilt_factor parameter does. It seems like it tries to limit the number of clusters assigned to each channel. By default, it's set at 4, but I'm not sure what that means. Does that mean that each channel can at max have 4 clusters assigned to it?

(seems unlikely, I often get many clusters for a given channel):
image

Otherwise, does this just limit the maximum number of clusters that KS will find to 4x the number of good channels? ie. if I had 32 channels, it can find, at most, 32x4 clusters?

Question about spike detection threshold

Hello,

I am following up here a discussion which started during the recent Neuropixel 2019 course. In the course it have been explained that, to set spike detection threshold, we should use the parameter ops.Th = [10 4]. However, I have seen in the config file that there is also another parameter called ops.spkTh = -6, which I thought defines the spike detection threshold in unit of std.

Could you please explain what each of this is doing, how they interact and with which ones we should play, for example, if we want to detect small amplitude spikes?

Thank you,
Best,
Dario

is it possible to continute using previous templates on new binary file

it is pretty common to do several tests and therefore result in several test binary files under one electrodes position, so if we want to consistently sorting spikes into corresponding cluster under the fixed electrodes position when relatively small or slow drifts may occur, we would concatenated the binary files in timely order, and do kilosort on this file.

I am wandering is it possible to use previously saved sorting results including channel templates to start with on new binary files, so that the template and clusters IDs could continually working on new binary files provided they all come from the same electrodes at a fixed position.

I guess it's just the templates from the first batch is not needed, but instead use the ones in previous results and treat the new first batch as the second batch as if the templates already been detected.

Loading previously sorted results in the GUI?

Not sure if this is intended behavior or not: If I sort a recording in the GUI, I can see KS2's prediction and compare to the actual data, which is a nice feature for looking whether/where KS2 is missing spikes. If I have a plotting issue, I can usually exit out of the GUI, restart it, and the same results will load (KS prediction included).

However, if I click the GUI reset button, or exit the GUI, quit Matlab, and open the GUI again, loading that same file from the same working directory (which already includes Kilosort2 results), it no longer shows Kilosort predictions in the GUI, and only gives options to re-preprocess and re-sort the data. I'm curious if this is the intended behavior: it would be nice to be able to reload already sorted results for examination in the GUI without resorting.

(GUI) No constructor 'handle.listener' with matching signature found.

Hi,

I'm trying to launch the GUI after installing the GUI Layout Toolbox and I get this error:

No constructor 'handle.listener' with matching signature found.

Error in uiextras.Container (line 95)
            obj.Listeners{end+1,1} = handle.listener( containerObj, findprop( containerObj, 'PixelBounds' ),
            'PropertyPostSet', @obj.onResized );

Error in uiextras.Box (line 38)
            [email protected]( varargin{:} );

Error in uiextras.VBox (line 44)
            [email protected]( varargin{:} );

Error in ksGUI/build (line 100)
            obj.H.root = uiextras.VBox('Parent', f,...

Error in ksGUI (line 47)
            obj.build(parent);

Error in kilosort (line 17)
h = ksGUI(f);

Apparently, the issue is recent (https://se.mathworks.com/matlabcentral/fileexchange/47982-gui-layout-toolbox - see comment from 7 Mar 2019). I'm using Matlab 2018b on Ubuntu 18.04.

Any workaround?

Thanks,
Alessio

Sorting data from distant electrodes

Thank you very much for the amazing tool!

We record from an array of widely spread 16 electrodes (rec. sites separated by ~0.5mm), s.t. we don't expect to detect a spike on more than one electrode, but we do have lots of highly correlated noise (behavior, electric artifacts, biology :\ ).

We have a hard time to optimize the hyper-parameters for our task:

  • Should we disable the weighted whitening across channels? If so, what is the safe way to achieve it?
  • What is the optimal way to format the array ('probe') layout? Just leave the 'Linear16x1'?
  • Any other way to convey our constraints and assumptions?

I am fully aware that KiloSort was not designed for this task, but even with the default settings it succeeded to impress us!

Alex & Co.

temporal stuttering


NOTE: This issue is [thought to be] related to a separate post #63 documenting anti-phase templates in kilosort2 output clusters


I've been having trouble achieving usable sorting results from Kilosort2, and results are actually so far from usable that I suspect that there must be some underlying initialization or parameterization problem.

The data

  • Examples are based on a single plx file recorded during part of a relatively brief [~40 min] duration & [subjectively] stable session.

    • 32 channel plexon U-probes with stereotrode configuration: 50µm within, 100µm between stereo pairs; 1.5 mm total
    • Sampled continuously 40kHz via Plexon MAP system
      (...old but stable hardware, bootstrapped into the modern era)
    • Converted to .dat files with common median referencing to remove cross channel artifacts
  • Though these examples are from a single file, similar issues are present across many attempts at applying Kilosort2 to files both long (2-3 hr) & concatenated (2-4 consecutively recorded data files), and with varying degrees of drift.

  • All kilosort parameters are set to default values or corresponding equivalents for 40kHz
    (...reverted to defaults after many attempts at tuning parameters to no avail.)

    • e.g.
      % make waveform length independent of sampling rate
      ops.nt0    = ceil( 0.0012 * ops.fs); % width of waveform templates (makes consistent N-ms 
      either side of spike, regardless of sampling rate)
      ops.nt0    = ops.nt0 + mod(ops.nt0-1, 2); % ensure oddity (...forum something about aiding 
      spike trough alignment)
      % define batches in seconds of data, not abstract bit chunks
      batchSec  = 10;  % define batch number in seconds
      ops.NT    = ceil(batchSec*ops.fs/32)*32 +ops.ntbuff; % convert to 32 count increments of 
      samples
  • Batch reordering figure:
    antiphaseWF_batchReorderFig

I'm experiencing two primary failure modes:

1) Temporal stuttering

The most significant & widespread issue seems to be punctate temporal stuttering, where clusters pop in and out of existence:
temporalStuttering

As could be expected, this produces massive over-splitting and nunits rapidly climbs to the upper template limit (set to default 4*nChannels). Every attempt I've made/thought of to encourage less splitting seems to just lead to worse sorting (excessive amplitude clipping & missing [detectable] lower amplitude waveforms)

This example screenshot happens to be one of the subsets from the next example, but they're present throughout all sorting results I've seen. Chosen for similar reasons as below, the waveform is clearly above the noise floor, and far more stable than is apparent in the clustered outputs. (...which is to say that the stuttering is not simply a result of genuine responsivity/selectivity for different stimulus trials during recording)

2) Anti-phase templates

  • [split into issue #63]

...with the futility of further random walks through parameter space, I'm hoping that these dead ends might reflect issues that other users have encountered & defeated, or that the Kilosort authors might be able to chime in on potential causes/solutions.

It seems more than likely that these issues are related, and that part of the temporal stuttering is a result of runaway templates within batches that simultaneously miss & distort (by fitting new templates to the residuals) otherwise corresponding clusters across batches.
Or so one would hope.

Many thanks to any & all who might be able to shed some light on this.

idrop is bigger than W in triageTemplates2

Hi,

I get an error in triageTemplates2. Apparently idrop = nsp<m0 leads to a vector greater than the second dimension of W.

299.90 sec, 1 / 4931 batches, 1008 units, nspks: 16.5796, mu: 10.0000, nst0: 0, merges: 0.1000, 0.0000 
Error using gpuArray/subsasgn
Matrix index is out of range for deletion.

Error in triageTemplates2 (line 7)
W(:,idrop,:) = [];

Error in learnAndSolve8b (line 188)
                triageTemplates2(ops, iW, C2C, W, U, dWU, mu, nsp, ndrop);

Error in MEAAnalysis/getKiloSorting (line 203)
            rez = learnAndSolve8b(rez);

Any ideas?

Cheers,
Noah

Positive crossing detection

Hi!
First of all thanks for the really useful piece of software you have built.
We are a bit confused about the interaction of kilosort with positive spikes. In the wiki it reads:
"First we determine which channels contain significant numbers of negative threshold crossings ". However when we are looking in phy, very often we encounter waveforms like the following:

eg1
eg5

Interestingly, however, these cells tend to get hard cut from the noise very frequently. Hence my question is: does the amplitude view calculate the overall amplitude of the waveform (be it positive or negative) OR does it only take into consideration the negative deflection component of the waveform?

A bug in preprocessDataSub?

In the high pass filtering loop in preprocessDataSub.m,
reading frame progresses by [NT-ops.ntbuff] sample points,
but [NT] sample points are written to temp_wh.dat,
so the filtered signal becomes longer than the original dat.

Is it intentional?
I thought it's a bug, but somehow final results seem fine.

Adjusting FS (Sampling Frequency) from GUI

Thanks a lot for this great tool. It worked 'out of the box' for us for Neuropixel data. However we encountered the following issue when using it with a different probe with different sampling rate.
When running the Kilosort2 from the GUI, it looks like it always uses the default sampling frequency (30'000), at least the field rez.ops.fs is set to 30000, even when in the GUI, a different sampling rate is set. It seems to work when starting kilosort via the master_kilosort.m and adjusting the ops.fs parameter in the config file.

rezToPhy `clusterIDs` are not assigned

Hi,

when I do [spikeTimes, clusterIDs, amplitudes, templates, templateFeatures, ... templateFeatureInds, pcFeatures, pcFeatureInds]=rezToPhy(rez, rootdir); matlab error said it's not assigned, and indeed in rezToPhy function.

it seems the spike_clusters.npy is saved but not reflected in the clusterIDs variable in line 107.

If my guess is correct, the clusterIDs is meant to have the same meaning of spike_cluster.npy, then it could be easily fixed.

Unclear error during automatic sorting

Hello,

Kilosort2 has recently started throwing the following errors during main optimization. Has anyone else encountered this or can think of any posible causes?

ksort2_error

There are no errors on the matlab command line.

It had previously been running fine on the same data format.

Data is from a 32 channel silicon probe sampled at 30 kHz.

Kilosort 1 versus 2

Hello! We run kilosort 1 and kilosort 2 (using the default parameters) for the same data and we are getting significantly less clusters recognized from kilosort 2. Any ideas why that might happen?
Thank you!

Unit channel not accurate

When I run kilosort using the following channel map for our Cambridge P series (2 shank) probe,

Channel map = [21 29 17 27 19 30 18 24 32 31 20 22 23 25 26 28 11 3 15 5 13 4 16 10 2 1 14 12 9 7 8 6]
X coordinates = [1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3 2]
Y coordinates = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
K coordinates = [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]

While I see some good waveforms, the cluserview "best channel" shows channels with little to no amplitude. It's completely off. Could this be an issue with how my channel map is configured? Any advice on how to properly map this 2-shank 32-channel probe? I feel like the geometry of the channels is accurately portrayed by the "probe view" cartoon, but the results don't make much sense with respect to which channels are best and the depth seems to be off too.

CAR computation in GUI includes dead channels

It seems that if running Kilosort2 via the GUI, common median referencing in ksFilter.m is computed with all channels as inputs, including dead channels. This is not the case when running KS2 via the command line. Can you confirm this is true? This can be a bit misleading when trying to probe whether KS2 works as expected using the GUI.
Otherwise, KS2 works great, thank you!

tetrode channel map

Hey,

I have a quick question concerning the channel map. I know that the kcoords variable is an easy way to define which channel belongs to one bundle of electrodes. In case of 4 tetrodes
kcoords=[1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4];

However I am wondering if the xcoords and ycoords have any meaning during the sporting process if the kcoords variable is defined.
Basically you can assume that the depth (ychoords is the same for one tetrode, 4 channels) and that the xchoords is a random value for different tetrodes (depeding on how far away they are from each other)? But do this two values matter if we define kchoords?

Thank your for creating Kilosort2!

Error in clusterSingleBatches (line 18) - error using gpuArray/subasgn (large data set)

I was able to get KiloSort2 working with a small snippet of a data set, both using the GUI and the script. When I tried to run the full data set, I get the following error:

Error using gpuArray/subsasgn
Subscript indices must either be real positive integers or logicals.
Error in isolated_peaks_new (line 17)
peaks([1:nt0 end-nt0:end], :) = 0;
Error in extractPCfromSnippets (line 32)
[row, col, mu] = isolated_peaks_new(dataRAW, ops);
Error in clusterSingleBatches (line 18)
wPCA = extractPCfromSnippets(rez, nPCs);

I dug into it and it seems that it's crashing on batch 43601 (of ~45600). I'm going to try it with more accessible memory, but thought I'd post here in case others run into the same issue.

Thanks!

improvements to kilosort GUI

(1) I'd like to suggest not to reload the previous session when starting kilosort. Usually, I restart kilosort to run a new session, so loading the old session just takes time and RAM. It also causes problems when the old data were already deleted.
(2) When choosing a new data file (after having having chosen a previous one), it would be great if the other 2 folders would be updated.

Compiling problem

Hi,

Really looking forward to try this improved version, I wonder if someone can help with the following error message that I get when I compile using mexGPUall while being in the CUDA folder. Everything goes smooth when compiling Kilosort1 on the same PC. I use Matlab 2018a.

Error using mex
fatbinary fatal   : '96_device.compute_35.cubin' is not in 'keyword=value' format
mexMPnu8.obj
c_mexapi_version.obj



Error in mexcuda (line 157)
    [varargout{1:nargout}] = mex(mexArguments{:});

Error in mexGPUall (line 5)
    mexcuda -largeArrayDims -dynamic mexMPnu8.cu
 

Thanks!

Common Average Referencing (twice?)

Not so much an issue but general question: I noticed that there is an internal option in KS2 to perform CAR on each batch. I'm not sure if this is also the case in KS1, but we typically preprocessed our data with a CAR and high pass filter before passing it to KiloSort. I'm wondering if that is a bad thing to do here, if it is going to subjected to another CAR and high pass filter in KiloSort?

In general, are there consequences to performing a CAR or high pass filter more than once on the same data? From what I gather, all of the thresholds used in KiloSort are not so much based on absolute amplitude, but on some measure of SNR, so I guess I'm wondering if multiple CAR and filtering steps will impact SNR?

Thanks!

tell user about undetected spikes

One idea: run a naive threshold-crossing detection at the end and report times, channels, and amplitudes of anything that is left? have text or graphical output of the rate of such spikes relative to the rate of spikes that were detected?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.