Skip to content

Commit

Permalink
wf_extractor->analyzer
Browse files Browse the repository at this point in the history
  • Loading branch information
zm711 committed Jul 11, 2024
1 parent 1f84828 commit 7fa83d1
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 21 deletions.
10 changes: 5 additions & 5 deletions doc/modules/comparison.rst
Original file line number Diff line number Diff line change
Expand Up @@ -523,19 +523,19 @@ in the similarity of templates rather than spiking events.
This enables us to use exactly the same tools for both types of comparisons, just by changing the way that agreement
scores are computed.

The functions to compare templates take a list of :py:class:`~spikeinterface.core.WaveformExtractor` objects as input,
The functions to compare templates take a list of :py:class:`~spikeinterface.core.SortingAnalyzer` objects as input,
which are assumed to be from different sessions of the same animal over time. In this case, let's assume we have 5
waveform extractors from day 1 (:code:`we_day1`) to day 5 (:code:`we_day5`):
waveform extractors from day 1 (:code:`analyzer_day1`) to day 5 (:code:`analyzer_day5`):

.. code-block:: python
we_list = [we_day1, we_day2, we_day3, we_day4, we_day5]
analyzer_list = [analyzer_day1, analyzer_day2, analyzer_day3, analyzer_day4, analyzer_day5]
# match only day 1 and 2
p_tcmp = sc.compare_templates(we1=we_day1, we2=we_day2, we1_name="Day1", we2_name="Day2")
p_tcmp = sc.compare_templates(sorting_analyzer_1=analyzer_day1, sorting_analyzer2=analyzer_day2, name1="Day1", name2="Day2")
# match all
m_tcmp = sc.compare_multiple_templates(waveform_list=we_list,
m_tcmp = sc.compare_multiple_templates(waveform_list=analyzer_list,
name_list=["D1", "D2", "D3", "D4", "D5"])
Expand Down
34 changes: 19 additions & 15 deletions doc/modules/core.rst
Original file line number Diff line number Diff line change
Expand Up @@ -496,19 +496,21 @@ Sparsity
In several cases, it is not necessary to have waveforms on all channels. This is especially true for high-density
probes, such as Neuropixels, because the waveforms of a unit will only appear on a small set of channels.
Sparsity is defined as the subset of channels on which waveforms (and related information) are defined. Of course,
sparsity is not global, but it is unit-specific.
sparsity is not global, but it is unit-specific. Importantly, saving sparse waveforms, especially for high-density probes,
dramatically reduces the size of the waveforms extension if computed.

**NOTE** As of version :code:`0.99.0` the default for a :code:`extract_waveforms()` has :code:`sparse=True`, i.e. every :code:`waveform_extractor`
will be sparse by default. Thus for users that wish to have dense waveforms they must set :code:`sparse=False`. Keyword arguments
can still be input into the :code:`extract_wavforms()` to generate the desired sparsity as explained below.
**NOTE** As of :code:`0.101.0` all :code:`SortingAnalyzer`'s have a default of :code:`sparse=True`. This was first
introduced in :code:`0.99.0` for :code:`WaveformExtractor`'s and will be the default going forward. To obtain dense
waveforms you will need to set :code:`sparse=False` at the creation of the :code:`SortingAnalyzer`.

Sparsity can be computed from a :py:class:`~spikeinterface.core.WaveformExtractor` object with the
:py:func:`~spikeinterface.core.compute_sparsity` function:

Sparsity can be computed from a :py:class:`~spikeinterface.core.SortingAnalyzer` object with the
:py:func:`~spikeinterface.core.estimate_sparsity` function:

.. code-block:: python
# in this case 'we' should be a dense waveform_extractor
sparsity = compute_sparsity(we, method="radius", radius_um=40)
# in this case 'analyzer' should be a dense SortingAnalyzer
sparsity = compute_sparsity(analyzer, method="radius", radius_um=40)
The returned :code:`sparsity` is a :py:class:`~spikeinterface.core.ChannelSparsity` object, which has convenient
methods to access the sparsity information in several ways:
Expand All @@ -529,17 +531,19 @@ There are several methods to compute sparsity, including:
* | :code:`method="by_property"`: selects channels based on a property, such as :code:`group`. This method is recommended
| when working with tetrodes.
The computed sparsity can be used in several postprocessing and visualization functions. In addition, a "dense"
:py:class:`~spikeinterface.core.WaveformExtractor` can be saved as "sparse" as follows:
The computed sparsity can be used in several postprocessing and visualization functions. In addition, this sparsity can be
used when creating a :py:class:`~spikeinterface.core.SortingAnalyzer` which cause the :code:`sparse` boolean to be ignored.

.. code-block:: python
we_sparse = we.save(sparsity=sparsity, folder="waveforms_sparse")
analyzer_sparse = si.create_sorting_analyzer(
sorting=sorting,
recording=recording,
sparsity=sparsity,
format='binary_folder',
folder="sparse_analyzer"
)
The :code:`we_sparse` object will now have an associated sparsity (:code:`we.sparsity`), which is automatically taken
into consideration for downstream analysis (with the :py:meth:`~spikeinterface.core.WaveformExtractor.is_sparse`
method). Importantly, saving sparse waveforms, especially for high-density probes, dramatically reduces the size of the
waveforms folder.
.. _save_load:

Expand Down
2 changes: 1 addition & 1 deletion doc/modules/postprocessing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ This extension computes the principal components of the waveforms. There are sev
* "by_channel_global": fits the same PCA model to all channels (also termed temporal PCA)
* "concatenated": concatenates all channels and fits a PCA model on the concatenated data

If the input :code:`WaveformExtractor` is sparse, the sparsity is used when computing the PCA.
If the input :code:`SortingAnalyzer` is sparse, the sparsity is used when computing the PCA.
For dense waveforms, sparsity can also be passed as an argument.

.. code-block:: python
Expand Down

0 comments on commit 7fa83d1

Please sign in to comment.