-
Notifications
You must be signed in to change notification settings - Fork 62
Description
Issue summary
Hi!
It seems like the neuromaps.stats.comapre_images function uses the zero/nan mask that is based on the two input arrays on permutated data with different locations of zeros/nans.
Detailed issue description
Thank you very much for developing this super useful toolbox!
I used the neuromaps.alexander_bloch() function to create rotated data. I have a few nan values in my vertex vise data, so I wanted to see if and how neuromaps.stats.compare_images() is handling such a case. I might be missing something obvious, but it seems like the mask that is created based on zeros/nans in src and trg is then applied to the null distributions (if provided). At least when using the alexander_bloch() rotated output, the nans are also rotated and therefore the mask doesn't fit anymore.
I started fixing this and realized that a fix needs adjustments in multiple locations in the code. In case you want to adapt the masking approach in compare_images like I did (rather than e.g., changes in the alexander_bloch() function), I'd be happy to make a pull request.
This is the section of code in neuromaps.stats.compare_images() I am referring to:
def compare_images():
...
# drop NaNs (if nan_policy==`omit`) and zeros (if ignore_zero=True)
zeromask = np.zeros(len(srcdata), dtype=bool)
if ignore_zero:
zeromask = np.logical_or(np.isclose(srcdata, 0),
np.isclose(trgdata, 0))
nanmask = np.logical_or(np.isnan(srcdata), np.isnan(trgdata))
if nan_policy == 'raise':
if np.any(nanmask):
raise ValueError('Inputs contain nan')
elif nan_policy == 'omit':
mask = np.logical_and(np.logical_not(zeromask),
np.logical_not(nanmask))
elif nan_policy == 'propagate':
mask = np.logical_not(zeromask)
srcdata, trgdata = srcdata[mask], trgdata[mask]
if metric in methods:
if metric == 'spearmanr':
srcdata = sstats.rankdata(srcdata)
trgdata = sstats.rankdata(trgdata)
metric = partial(efficient_pearsonr, return_pval=False)
if nulls is not None:
n_perm = nulls.shape[-1]
nulls = nulls[mask]
...
Steps to reproduce issue
I came across this bug in the context of running:
from neuromaps import stats, nulls
rotated = nulls.alexander_bloch(src, atlas='fsaverage', density='10k',
n_perm=100, seed=1234)
corr, pval = stats.compare_images(src, trg, nulls=rotated, ignore_zero=False, nan_policy='omit', metric="pearsonr")
Software version
3.9.6 (default, Nov 11 2024, 03:15:38)
[Clang 16.0.0 (clang-1600.0.26.6)]
0.0.5
Code of Conduct
- I agree to follow the
neuromaps
Code of Conduct