Skip to content

Conversation

@ecobost
Copy link
Contributor

@ecobost ecobost commented Jan 23, 2026

Template metrics are currently designed to only work for negative spiking neurons (large negative trough followed by small positive peak) but many units spike higher in the positive side (very common in NHP). I adapted here those metrics to deal properly with positive spiking units when peak_sign='pos' (or 'both'). When peak_sign='neg' (default), results are the same.

For reference, here are the templates for a positive spiking unit (each line is a channel).
pos_templates
Currently, the cyan line will be picked as the template, trough will be at ~40 (the dip) and peak will be the largest value after trough (so probably that small peak at 60 or the one at 75). That will produce non-sensical metrics (in this case, peak-to-through distance will be overestimated, halfwidth will be overestimated, peak-to-trough valley might be understimated). This is true for all positive spiking units. I propose that when the unit spikes upwards (as declared by peak_sign='pos'), the positive peak should be the "trough" and the negative dip post-positive spike should be the "peak", which will result in metrics that make sense for this units and is consistent with how peak_sign='pos' is dealt with in other parts of spikeinterface. I don't love the overriding of the name "trough" and "peak" (maybe there are more general terms for that but I didn't wanna change much of the code and the names make sense for the default, more common, peak_sign='neg')

Most metrics work fine whether the spike is positive or negative. A few needed some tweaks; I describe what I changed here (per metric):

  • halfwidth: halfwidth: currently implemented as find the first index before through and last index after through where template is less than threshold; in this PR it is implemented as find the last index before trough and first index after trough where the threshold is crossed (regardless of direction). This computes the halfwidth of the spike ("trough") whether it points downwards or upwards. The slight logic change in how indices are picked is intentional, it deals better with the edge case where another spike in the same template also crosses the threshold (see image)*
    PXL_20260123_151253013 MP
  • repolarization_slope: current implementation finds the first index after trough that is greater than zero; this PR changes it to find the first index after trough where the zero is crossed (which works for negative and positive spikes). if using peak_sign='both', the slope will then be positive for negative/downward spiking units and negative for upwards spiking units, which is nice.
  • velocity_fits: I invert the templates if using peak_sign='pos' so it fits the speed of the positive peaks rather than the negative peaks.

Note: in halfwidth, there is another small change that will affect peak_sign='neg' data. Currently, if a template was [0, -1, 0, 0, 0], code will say the halfwidth was 2, if a template was [0, -1, -1, 0, 0] it will say the half_width is 3 and so on. So there was a one-off error. I fixed that so now if x indices are above the threshold, the halfwidth is x (rather than x + 1), but then most new data will differ by one from previous data (e.g., 30 microseconds shorter halfwidth for neuropixels)

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.

1 participant