SpikeInterface / spikeinterface

A Python-based module for creating flexible and robust spike sorting pipelines.
https://spikeinterface.readthedocs.io
MIT License
519 stars 186 forks source link

Multiple template comparison 'm_tcmp' #3485

Open taningh86 opened 1 week ago

taningh86 commented 1 week ago

Hi, I have used pairwise 'p_tcmp' comparisons for matching units in two recording sessions and it works with the agreement scores. However, when I am comparing/matching multiple recordings m_tcmp I am not sure what feature to use, since m_tcmp don't take agreement_scores. My goal is to match units in all recordings at once instead of going through pairs. Doing it pair by pair, which I have been ding so far, is time intensive to match across multiple recordings. Please let me know how could I create something like an agreement scores that will allow me to match the similarity of unit templates across multiple recordings.

Thanks!

alejoe91 commented 1 week ago

You can use the compare_multiple_templates function

taningh86 commented 1 week ago

Thats what I used. But I was expecting something where units across all recordings are matched based on some score based on a template metric similar to agremment scores in pairwise comparisons. Here's the code I used

import spikeinterface as si
import spikeinterface.comparison as sc

from pathlib import Path

folder1 = Path(r'G:\NPX2_2_28_24_2Rght_LHA_RSP_EXP_g0')
folder2 = Path(r'G:\NPX2_3_6_24_2Rght_LHA_RSP_just_FOR_g0')
folder3 = Path(r'G:\NPX2_24_fasted_4_19_24_EXP_g0')
folder4 = Path(r'G:\NPX2_24_fasted_4_19_24_FOR_g0')

# Load the sorting analyzer folders
analyzer_day1 = si.load_sorting_analyzer(folder1/"SA_2_28_24_EXP")
analyzer_day2 = si.load_sorting_analyzer(folder2/"SA_3_6_24_FOR")
analyzer_day3 = si.load_sorting_analyzer(folder3/"SA_4_19_24_FASTED_EXP_New")
analyzer_day4 = si.load_sorting_analyzer(folder4/"SA_4_19_24_FASTED_FOR_New")

analyzer_list = [analyzer_day1, analyzer_day2, analyzer_day3, analyzer_day4]

# match all
m_tcmp = sc.compare_multiple_templates(waveform_list=analyzer_list,
                                       name_list=["D1", "D2", "D3", "D4"])

With this code I get the following output, which i don't quite understand.

Removed node: ('D1', 5)
Removed node: ('D1', 16)
Removed node: ('D1', 39)
Removed node: ('D1', 2)
Removed node: ('D1', 13)
Removed node: ('D1', 17)
Removed node: ('D1', 7)
Removed node: ('D1', 0)
Removed node: ('D1', 9)
Removed node: ('D2', 4)
Removed node: ('D2', 40)
Removed node: ('D2', 67)
Removed node: ('D2', 6)
Removed node: ('D2', 37.0)
Removed node: ('D2', 68)
Removed node: ('D2', 2)...
zm711 commented 1 week ago

@alejoe91, I also don't see where we expose this to the user easily for templates. It looks like the class isn't quite as feature rich as the sorting class. it does the same graph, but then doesn't have an easy to use method for returning the agreements. Or am I wrong?

Thanks for pointing this out Jimmy at least to me.

For templates here: https://github.com/SpikeInterface/spikeinterface/blob/a606364d996aed2f65efc131904e5d3ee0eb0dc7/src/spikeinterface/comparison/multicomparisons.py#L339-L388

compared to for sorting: https://github.com/SpikeInterface/spikeinterface/blob/a606364d996aed2f65efc131904e5d3ee0eb0dc7/src/spikeinterface/comparison/multicomparisons.py#L161-L185

where we have a nice to use (for the user function).

taningh86 commented 6 days ago

of course @zm711

taningh86 commented 6 days ago

@alejoe91 any suggestions?