Skip to content

Fix sparse template handling in kilosort reader for SI-exported Phy data#20

Merged
kushalbakshi merged 1 commit into
mainfrom
fix/sparse-templates-spike-sites
Feb 9, 2026
Merged

Fix sparse template handling in kilosort reader for SI-exported Phy data#20
kushalbakshi merged 1 commit into
mainfrom
fix/sparse-templates-spike-sites

Conversation

@ttngu207
Copy link
Copy Markdown

Summary

  • Fixes incorrect spike_sites and best_channel values when reading SpikeInterface-exported Phy curations
  • SpikeInterface's export_to_phy exports sparse templates by default (since v0.101.0)
  • The existing code assumed dense templates (all channels), causing incorrect channel lookups

Problem

SpikeInterface exports templates.npy with shape (n_templates, n_samples, max_sparse_channels) where:

  • max_sparse_channels is the maximum number of sparse channels across all units (not all channels)
  • A companion file templates_ind.npy maps (template_idx, sparse_channel_idx) -> actual_channel_idx
  • Padding positions use -1

The existing code used argmax to find the channel with max amplitude, but this returns an index into the sparse representation (0, 1, 2...), not the actual channel index.

Solution

Updated get_best_channel() and extract_spike_depths() to:

  1. Check if templates_ind.npy exists (indicates SI-exported sparse format)
  2. Use templates_ind to map sparse indices to actual channel indices
  3. Fall back to original behavior for native Kilosort (dense) format

Test plan

  • Test with SI-exported Phy curation data (MBA probes)
  • Verify spike_sites values match expected channel indices
  • Verify backward compatibility with native Kilosort output

Related

🤖 Generated with Claude Code

SpikeInterface's export_to_phy exports sparse templates by default (since
v0.101.0), with templates.npy shape (n_templates, n_samples, max_sparse_channels)
instead of the full (n_templates, n_samples, n_channels) format from native
Kilosort.

The companion file templates_ind.npy maps (template_idx, sparse_channel_idx)
to actual channel indices, with -1 indicating padding.

This fix updates get_best_channel() and extract_spike_depths() to:
- Check if templates_ind exists (indicates SI-exported sparse format)
- Use templates_ind to map sparse indices to actual channel indices
- Fall back to original behavior for native Kilosort (dense) format

Without this fix, spike_sites and best_channel values are incorrect when
reading SI-exported Phy curations, as argmax returns indices into the
sparse representation rather than actual channel indices.

Related: dj-sciops/nei_nienborg#111 (Issue #2)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@kushalbakshi kushalbakshi merged commit cde6aad into main Feb 9, 2026
0 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants