Skip to content

Commit b5c85ff

Browse files
committed
Working on the private PC decomposition.
1 parent 2a9e082 commit b5c85ff

File tree

2 files changed

+16
-7
lines changed

2 files changed

+16
-7
lines changed

src/spikeinterface/working/load_kilosort_utils.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,7 @@ def compute_spike_amplitude_and_depth(
5959
center of mass from the first PC (or, second PC if no signal on first PC).
6060
See `_get_locations_from_pc_features()` for details.
6161
"""
62-
if isinstance(sorter_output, str):
63-
sorter_output = Path(sorter_output)
64-
65-
if not params["pc_features"]:
62+
if params["pc_features"] is None:
6663
raise ValueError("`pc_features` must be loaded into params. Use `load_ks_dir` with `load_pcs=True`.")
6764

6865
if localised_spikes_only:
@@ -118,10 +115,12 @@ def compute_spike_amplitude_and_depth(
118115

119116
def _get_locations_from_pc_features(params):
120117
"""
118+
Compute locations from the waveform principal component scores.
121119
122120
Notes
123121
-----
124122
Location of of each individual spike is computed from its low-dimensional projection.
123+
During sorting, kilosort computes the '
125124
`pc_features` (num_spikes, num_PC, num_channels) holds the PC values for each spike.
126125
Taking the first component, the subset of 32 channels associated with this
127126
spike are indexed to get the actual channel locations (in um). Then, the channel
@@ -131,6 +130,13 @@ def _get_locations_from_pc_features(params):
131130
https://github.com/cortex-lab/spikes
132131
"""
133132
# Compute spike depths
133+
134+
# for each spike, a PCA is computed just on that spike (n samples x n channels).
135+
# the components are all different between spikes, so are not saved.
136+
# This gives a (n pc = 3, num channels) set of scores.
137+
# but then how it is possible for some spikes to have zero score onto the principal channel?
138+
139+
breakpoint()
134140
pc_features = params["pc_features"][:, 0, :]
135141
pc_features[pc_features < 0] = 0
136142

@@ -153,7 +159,7 @@ def _get_locations_from_pc_features(params):
153159

154160
pc_features[no_pc1_signal_spikes] = pc_features_2[no_pc1_signal_spikes]
155161

156-
if any(np.sum(pc_features, axis=1) == 0):
162+
if np.any(np.sum(pc_features, axis=1) == 0):
157163
raise RuntimeError(
158164
"Some spikes do not load at all onto the first"
159165
"or second principal component. It is necessary"
@@ -319,7 +325,8 @@ def load_ks_dir(sorter_output: Path, exclude_noise: bool = True, load_pcs: bool
319325
As this function strips the spikes and units based on only these two
320326
data structures, they will work following manual reassignment in Phy.
321327
"""
322-
sorter_output = Path(sorter_output)
328+
if isinstance(sorter_output, str):
329+
sorter_output = Path(sorter_output)
323330

324331
params = read_python(sorter_output / "params.py")
325332

src/spikeinterface/working/plot_kilosort_drift_map.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,10 @@ def plot_matplotlib(self, data_plot: dict, **unused_kwargs) -> None:
106106

107107
dp = to_attr(data_plot)
108108

109+
params = load_kilosort_utils.load_ks_dir(dp.sorter_output, load_pcs=True, exclude_noise=dp.exclude_noise)
110+
109111
spike_indexes, spike_amplitudes, spike_locations, _ = load_kilosort_utils.compute_spike_amplitude_and_depth(
110-
dp.sorter_output, dp.localised_spikes_only, dp.exclude_noise, dp.gain, dp.localised_spikes_channel_cutoff
112+
params, dp.localised_spikes_only, dp.gain, dp.localised_spikes_channel_cutoff
111113
)
112114
spike_times = spike_indexes / 30000
113115
spike_depths = spike_locations[:, 1]

0 commit comments

Comments
 (0)