From b68da168c3203b5951cc92f7cd549a0f0966a9d7 Mon Sep 17 00:00:00 2001 From: Aditya Singh Date: Wed, 5 Aug 2026 06:10:36 -0700 Subject: [PATCH] Correct the pc_features axis order and indexing example The dataset reference gave the in-memory shape for the file on disk, and the sorting user guide indexed pc_feature_ind as a one-dimensional array and described a zero-based PC index as the first PC. phylib reads pc_features.npy and transposes its last two axes, so the file holds (n_spikes, n_pcs, n_channels_loc) and pc_feature_ind is indexed by the spike's template. Correct both pages and note the transpose. Fixes #1364 --- docs/changelog.md | 4 ++++ docs/dataset.md | 2 +- docs/sorting_user_guide.md | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index 4ca30298..977425b0 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -111,6 +111,10 @@ behavior they verify rather than listed separately. - Added a task-oriented documentation navigation, synchronized API, shortcut, and plugin references, and strict documentation checks in continuous integration. +- Corrected the `pc_features.npy` description. The file stores + `(n_spikes, n_pcs, n_channels_loc)`, phy swaps the last two axes on load, + array indices are zero-based, and `pc_feature_ind` is indexed by the + spike's template. ## [2.1.0] — 2026-07-17 diff --git a/docs/dataset.md b/docs/dataset.md index 7c96cac9..a97a190a 100644 --- a/docs/dataset.md +++ b/docs/dataset.md @@ -101,7 +101,7 @@ Most real sorting exports should also contain the following files: | `similar_templates.npy` | `(n_templates, n_templates)` similarity matrix used by the Template GUI's default similarity ranking. Larger values rank first; the score's scale is defined by the exporter. | | `whitening_mat.npy` | `(n_channels, n_channels)` whitening matrix. | | `whitening_mat_inv.npy` | `(n_channels, n_channels)` inverse whitening matrix used to display unwhitened templates. If absent, phy computes and writes it. | -| `pc_features.npy` | `(n_spikes_subset, n_channels_loc, n_pcs)` floating-point principal-component features used by the Feature View. | +| `pc_features.npy` | `(n_spikes_subset, n_pcs, n_channels_loc)` floating-point principal-component features used by the Feature View. phy swaps the last two axes on load, so `model.get_features()` returns `(n_spikes, n_channels, n_pcs)`. | | `pc_feature_ind.npy` | `(n_templates, n_channels_loc)` channel indices corresponding to PC features. | | `template_features.npy` | `(n_spikes_subset, n_template_features)` projections onto nearby templates. | | `template_feature_ind.npy` | `(n_templates, n_template_features)` template indices corresponding to template features. | diff --git a/docs/sorting_user_guide.md b/docs/sorting_user_guide.md index c73daee3..11b8964f 100644 --- a/docs/sorting_user_guide.md +++ b/docs/sorting_user_guide.md @@ -63,7 +63,7 @@ _______________ * `amplitudes.npy` - `[nSpikes, ] double` vector with the amplitude scaling factor that was applied to the template when extracting that spike * `channel_map.npy` - `[nChannels, ] int32` vector with the channel map, i.e. which row of the data file to look in for the channel in question * `channel_positions.npy` - `[nChannels, 2] double` matrix with each row giving the x and y coordinates of that channel. Together with the channel map, this determines how waveforms will be plotted in WaveformView (see below). - * `pc_features.npy` - `[nSpikes, nFeaturesPerChannel, nPCFeatures] single` matrix giving the PC values for each spike. The channels that those features came from are specified in pc_features_ind.npy. E.g. the value at `pc_features[123, 1, 5]` is the projection of the 123rd spike onto the 1st PC on the channel given by `pc_feature_ind[5]`. + * `pc_features.npy` - `[nSpikes, nFeaturesPerChannel, nPCFeatures] single` matrix giving the PC values for each spike. The channels that those features came from are specified in `pc_feature_ind.npy`. All indices are zero-based, so the value at `pc_features[123, 1, 5]` is the projection of the spike with index 123 onto the second PC, on the channel given by `pc_feature_ind[t, 5]`, where `t` is that spike's template, `spike_templates[123]`. phy swaps the last two axes when it loads the file, so `model.get_features()` returns `[nSpikes, nChannels, nFeaturesPerChannel]`. * `pc_feature_ind.npy` - `[nTemplates, nPCFeatures] uint32` matrix specifying which pcFeatures are included in the pc_features matrix. * `similar_templates.npy` - `[nTemplates, nTemplates] single` matrix giving the similarity score (larger is more similar) between each pair of templates * `spike_templates.npy` - `[nSpikes, ] uint32` vector specifying the identity of the template that was used to extract each spike