pynapple-org / pynapple

PYthon Neural Analysis Package :pineapple:
https://pynapple.org/
MIT License
262 stars 61 forks source link

[ENH] Perievent -> instantaneous firing rate TsdFrame #306

Closed qian-chu closed 3 months ago

qian-chu commented 3 months ago

Computing and plotting instantaneous firing rate is a very common practice. This Pynapple tutorial using Zheng (2022) data already has a very nice example on how to achieve this. I wonder if it would be nice to parameterize the example to take a PETH TsGroup and returns a firing rate TsdFrame? One difficulty might be that there are lots of parameters (bin_size, step_size, win_type, win_center, std [when win_type='gaussian'], etc.) but at least Pynapple can support a few common implementations IMO. Happy to draft a PR if this is conceptually sound.

gviejo commented 3 months ago

Hi are you describing the function nap.compute_event_correlogram ? Otherwise there is the function tsgroup.count that returns a count given a bin size. You can divide by the bin size to get the rate.

qian-chu commented 3 months ago

Hi I don't think nap.compute_event_correlogram quite fits what I'm looking for. But tsgroup.count is indeed the way to calculate PETH which is already common in lots of publications. What I'm proposing builds upon tsgroup.count with extra smoothing (by averaging rolling windows). For example, I'm using this customized function:

def peth_fr(
        peth: perievent,
        bin_size=0.2,
        step_size=0.01,
        std=0.2
        ):
    """
    Compute firing rate
    """
    winsize = int(bin_size / step_size)  # Window size in samples

    fr = peth.count(step_size).as_dataframe().rolling(
        winsize,
        win_type="gaussian",
        min_periods=1,
        center=True
        ).mean(std=std * winsize) * winsize

    fr_TsdFrame = nap.TsdFrame(
        t=fr,
        time_units='s',
        time_support=peth.time_support
        )

    return fr_TsdFrame
gviejo commented 3 months ago

There is now a smooth function in pynapple. You can do tsgroup.count(bin_size).smooth(kernel_size).

For now it's only gaussian kernel but you can also call the convolve function if you have a different kernel.

qian-chu commented 3 months ago

This is nice! Then I think this proposed function is not really necessary. Maybe I can try to update the tutorial using the smoothing function. Thanks!