MouseLand / Kilosort

Fast spike sorting with drift correction for up to a thousand channels
https://kilosort.readthedocs.io/en/latest/
GNU General Public License v3.0
471 stars 245 forks source link

template_matching.align_U changing shape of learned templates #753

Closed rachelmcassidy closed 1 month ago

rachelmcassidy commented 3 months ago

Hello,

Thanks so much for all the work and documentation for kilosort 4! I've been making some modifications for my data to enforce detection of negative spikes only, and after changing the Th_single_ch and Th_universal steps, I was inspecting the temporal profiles of learned templates to see if there were still non-spike-like waveforms. When I look at the learned templates before and after the alignment to universal templates (alignU) in the template_matching.postprocess_templates step, it looks like many good templates are being changed into an entirely different shape. However, some templates are correctly re-aligned so that the spike trough is where it should be. Do you have any suggestions for getting the desired template shapes from this alignment step? More universal templates or pcs? Or restricting the sign of the correlation? What would be the downsides of skipping the alignU step? Here are a few examples of templates on the channel with maximum amplitude before and after alignment:

TemplateAlignment1

Thanks for any advice!

jacobpennington commented 2 months ago

@rachelmcassidy Just to clarify, are you saying you made changes to the code before generating this example? If so, can you try sorting without those modifications and see what this looks like?

Also, can you please provide more information about the data and which settings you changed, if any?

rachelmcassidy commented 2 months ago

Sure - I am sorting data from a 64 channel linear probe in mouse cortex on a GeForce RTX 3060. With a fresh kilosort install and default parameters except nt=51 (24414 Hz fs), the template alignment looks perfect and I also don't see as many templates that look like overlapping spikes as I did above:

TemplateAlignment_KSdefault

It wouldn't be too big of a deal if the spikes extracted with these positive templates all clustered together, but I find many good units with contamination from these positive waveforms. I also see duplicates of spikes (especially large ones) that I think could be residuals matching with the slightly positive templates and waveforms that seem to be extracted around the AP after-hyperpolarization, while the main spike gets missed.

Maybe using the thresholds as-is but filtering out the positive learned templates would be a better approach?

Here is what I modified previously in spikedetect.py:

  1. Extracting initial spikes using only local minima def extract_snippets(X, nt, twav_min, Th_single_ch, loc_range=[4,5], long_range=[6,30], device=torch.device('cuda')): Xabs = X.abs() Xmax = my_max2d(Xabs, loc_range) ispeak = torch.logical_and(Xmax==Xabs, X < -Th_single_ch).float() ...

  2. After confirming that the 6 universal templates were all negative waveforms after implementing (1), I changed the peak detection after template convolution (spikedetect.template_match) to be only local maxima: #uncommenting to try only negative spikes Aa, imax = torch.max(A, 0) #Aa, imax = torch.max(A.abs(), 0) ... xy = torch.logical_and(Amaxs==As, As > ops['Th_universal']).nonzero()

These changes cleaned up a lot of my clusters and improved the yield of good units, but I still noticed some weird/noisy waveforms. Do you have any other suggestions/cautions for extracting only negative spikes?

jacobpennington commented 2 months ago

After discussing with Marius, it seems like trying to only extract negative spikes is just not a good idea. Many of the templates will have both positive and negative portions, so trying to only use negative peaks for detection could result in the misalignment issues you're seeing, and could affect other steps in the pipeline. So, our recommendation is to sort without making any modifications to the code. If you're set on removing the positive spikes, you could try doing that after sorting is finished, but we expect there to be similar difficulties with that approach.