Skip to content

Add per-group ref_channel_ids to common_reference#4601

Open
grahamfindlay wants to merge 2 commits into
SpikeInterface:mainfrom
grahamfindlay:feature/groupwise-cmr
Open

Add per-group ref_channel_ids to common_reference#4601
grahamfindlay wants to merge 2 commits into
SpikeInterface:mainfrom
grahamfindlay:feature/groupwise-cmr

Conversation

@grahamfindlay
Copy link
Copy Markdown
Contributor

With reference="global" and groups passed (i.e. not None), common_reference() referenced each group to its own channels and ignored ref_channel_ids. I'm not sure if this was intended behavior or a bug. I think a bug, because the docstring stated "a list of channels to be applied to each group is expected", and I read that as "a list of channels per group to be applied to that group is expected". That would be useful for tetrode recordings, because the most principled reference for a tetrode may sometimes be the average/median of all OTHER tetrodes (i.e., don't subtract the tetrode's average/median from itself -- especially with small numbers of tetrodes, this could be dangerous).

Therefore this PR has 2 commits. The second just introduces some convenient syntactic sugar for the functionality provided by the first.

  1. The first commit allows ref_channel_ids to be a list of per-group channel-id lists: the reference subtracted from each group is the operator (median/average) over that group's reference set, which may include channels OUTSIDE the group. This enables cross-group referencing (e.g. each tetrode referenced to the median of all channels on the other tetrodes). ref_channel_ids=None (default) keeps the previous own-group behavior.
  2. The second commit adds common_reference(..., ref_channel_ids="complement") as syntactic
    sugar for referencing each group to all channels NOT in it -- it just auto-builds the correctref_channel_ids to accomplish this.

So now if you have groups that represent the tetrodes, you can do tetrode-aware referencing with:

import numpy as np
import spikeinterface.preprocessing as spre

groups = np.asarray(rec.get_property("group"))
cids = np.asarray(rec.get_channel_ids())
tetrodes = [list(cids[groups == g]) for g in sorted(set(groups.tolist()))]

# No sugar
complements = [list(cids[groups != g]) for g in sorted(set(groups.tolist()))]
rec_ct = spre.common_reference(
    rec, reference="global", operator="median",
    groups=tetrodes, ref_channel_ids=complements,
)

or

# With sugar
rec_ct = spre.common_reference(
    rec, reference="global", operator="median",
    groups=tetrodes, ref_channel_ids="complement",
)

…ncing)

With reference="global" + groups, common_reference referenced each group to its
OWN channels and ignored ref_channel_ids, despite the docstring stating "a list
of channels to be applied to each group is expected".

This allows ref_channel_ids to be a list of per-group channel-id lists:
the reference subtracted from each group is the operator (median/average)
over that group's reference set, which may include channels OUTSIDE the group.
This enables cross-group referencing (e.g. each tetrode referenced to the
median of all channels on the other tetrodes). ref_channel_ids=None (default)
keeps the previous own-group behavior.
The most principled reference for a tetrode may sometimes be
the average/median of all OTHER tetrodes.  In other words, each
group is referenced to all channels NOT in it --
ref_channel_ids is each group's complement (with "global"
reference and "groups").

Adds common_reference(..., ref_channel_ids="complement") as syntactic
sugar for this.
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