-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Phase-slope index using spectral_connectivity_time instead of spectral_connectivity_epochs #210
base: main
Are you sure you want to change the base?
Conversation
for more information, see https://pre-commit.ci
Hi @seqasim, thanks for the PR and sorry for not getting back to you sooner on this. I have a few comments/suggestions which I'll post below, but it's a really good start! If this is something you're still interested in working on, your contributions are of course very welcome, however I realise it's been a while. If you're not able to invest time into this anymore and you don't want your hard work to go to waste, I can pick things up and we can make sure the changes are added. Just let us know. Cheers! |
Just need to make sure that the new mne-connectivity/mne_connectivity/spectral/time.py Lines 72 to 75 in ef0a484
And also an equation entry like for mne-connectivity/mne_connectivity/spectral/time.py Lines 245 to 256 in ef0a484
|
A more general comment for the new |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So just pretty minor comments. There are a couple formatting things (mainly line length) that I would have thought pre-commit
would sort (if you've set that up). Would recommend doing so otherwise getting that CI check to pass will be very tedious...
@@ -559,7 +559,7 @@ def spectral_connectivity_time( | |||
conn_patterns = dict() | |||
for m in method: | |||
# CaCoh complex-valued, all other methods real-valued |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's update the comment to keep it accurate
# CaCoh complex-valued, all other methods real-valued | |
# Cohy and CaCoh complex-valued, all other methods real-valued |
def _cohy(s_xx, s_yy, s_xy): | ||
"""Compute coherencey given the cross spectral density and PSD. | ||
|
||
Parameters | ||
---------- | ||
s_xx : array-like, shape (n_freqs, n_times) | ||
The PSD of channel 'x'. | ||
s_yy : array-like, shape (n_freqs, n_times) | ||
The PSD of channel 'y'. | ||
s_xy : array-like, shape (n_freqs, n_times) | ||
The cross PSD between channel 'x' and channel 'y' across | ||
frequency and time points. | ||
|
||
Returns | ||
------- | ||
cohy : array-like, shape (n_freqs, n_times) | ||
The estimated COHY. | ||
""" | ||
con_num = s_xy.mean(axis=-1, keepdims=True) | ||
con_den = np.sqrt( | ||
s_xx.mean(axis=-1, keepdims=True) * s_yy.mean(axis=-1, keepdims=True) | ||
) | ||
cohy = con_num / con_den | ||
return cohy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
from .base import ( | ||
EpochSpectralConnectivity, | ||
SpectralConnectivity, | ||
SpectroTemporalConnectivity, | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Formatting stuff
from .base import ( | |
EpochSpectralConnectivity, | |
SpectralConnectivity, | |
SpectroTemporalConnectivity, | |
) | |
from .base import ( | |
EpochSpectralConnectivity, SpectralConnectivity, SpectroTemporalConnectivity | |
) |
padding=0, | ||
n_jobs=1, | ||
): | ||
"""Compute the Phase Slope Index (PSI) connectivity measure across time rather than epochs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would need to shorten this. How about something like "Compute the Phase Slope Index (PSI) connectivity measure across time."?
This function computes PSI over time from epoched data. | ||
The data may consist of a single epoch. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this, keeps things consistent with spectral_connectivity_time()
, but what about also having this be the first thing in the docstring, like in the spectral connectivity function?
That would help make it clearer sooner how this func differs to phase_slope_index()
.
See Also | ||
-------- | ||
mne_connectivity.EpochSpectralConnectivity |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if it's good to reiterate that spectral_connectivity_time()
is a relevant function. Though I realise you based this on the existing function docstring which doesn't link to spec_conn_epochs()
.
|
||
Returns | ||
------- | ||
conn : instance of Connectivity |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#214 made a lot of these typehints more explicit (i.e. EpochSpectralConnectivity
instead).
conn : instance of Connectivity | |
conn : instance of EpochSpectralConnectivity |
@verbose | ||
@fill_doc | ||
def phase_slope_index_time(data, | ||
names=None, | ||
indices=None, | ||
sfreq=2 * np.pi, | ||
mode="multitaper", | ||
fmin=None, | ||
fmax=np.inf, | ||
mt_bandwidth=None, | ||
freqs=None, | ||
n_cycles=7, | ||
padding=0, | ||
n_jobs=1, | ||
): | ||
"""Compute the Phase Slope Index (PSI) connectivity measure across time rather than epochs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just make sure you add a verbose parameter. That should get the tests running.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also you shouldn't need both verbose and fill_doc decorators. Verbose will trigger the same things as fill_doc
|
||
Parameters | ||
---------- | ||
data : array-like, shape=(n_epochs, n_signals, n_times) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should also include Epochs
(again, I realise you took this from the existing function which doesn't have this, so should change there too).
def test_psi_time(): | ||
"""Test Phase Slope Index (PSI) estimation across time.""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From a quick glance the test looks good to me, let's see if it passes once the verbose
param is added to the new function.
Hey, Thanks for reviewing things! It's super illuminating for me to see the details I missed. I sadly won't have time to follow through on this for a few months, so if you feel you can wrap it up quickly, please don't wait for me! But if not, I'm happy to pick it up with all your helpful comments later in the year. |
Yeah sounds good, there's no rush! |
Thanks for contributing. If this is your first time,
make sure to read contributing.md
PR Description
Currently, the function for computing phase-slope index is hard-coded to be computed over epochs to produce time-resolved PSI, and there's no option for computing the phase-slope index over time to produce PSI per epoch. This would be useful if you think the average directionality between two signals over the entire timecourse is informative. You could compute this by binning your trials into categories (i.e. good trials v. bad trials) and then computing PSI, but there's no way to compute PSI per epoch and relate it to continuous trial-level predictors.
Here, I add a new function
phase_slope_index_time
tomne_connectivity.effective
that compute PSI over time. I should note that I wasn't able to test this function directly as I'm having trouble getting the forked repo installed, in editable mode, with all necessary dependencies, but have written a test function intests.test_effective
to facilitate this.Merge checklist
Maintainer, please confirm the following before merging: