-
Notifications
You must be signed in to change notification settings - Fork 575
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
ENH: compute grey and white matter masks #2738
Conversation
I got 2 errors (1 error duplicated) in my local machine with pytest in lines 632 and 724 of
I don't understand because at the end of the function |
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.
Thanks for working on this @alpinho ! 👍
I left a few comments below.
@alpinho I looked at the errors you're getting with the empty niimg, and I think they come from the fact that you are using datasets fetchers in The previous behaviour of |
Thanks @NicolasGensollen for the feedback! I am working on your requests. Regarding your last comment about my error, what should I do? Should I just discard this error, since this only happens when running the local tests? Note that the default behavior of |
@NicolasGensollen I did several updates in order to both fix my previous local pytest errors and address your comments. To fix the local pytest errors, I decided to use the load functions instead of the fetch functions. Therefore, I had to download and store in |
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.
Thanks for addressing my comments @alpinho ! 👍
I don't think adding the templates for gm and wm is a problem (@bthirion could confirm this or not). However, I'd be in favor of having something consistent in terms of API and data. I made a few comments below regarding this.
Maybe we should update the brain template also to have the same resolutions:
from nilearn import plotting
from nilearn.datasets.struct import (MNI152_FILE_PATH,
GM_MNI152_FILE_PATH,
WM_MNI152_FILE_PATH)
plotting.plot_img(MNI152_FILE_PATH, colorbar=True)
plotting.plot_img(GM_MNI152_FILE_PATH, colorbar=True)
plotting.plot_img(WM_MNI152_FILE_PATH, colorbar=True)
WDYT?
I also prefer to wait for @bthirion comments. I am actually surprised that they don't share already the same resolution... I downloaded these masks from https://osf.io/7pj92/download, i.e. one of the links used by |
@NicolasGensollen Could you advice what else I should fix?, since I still get many failing tests. I don't get more errors in my local machine with pytest. Thanks in advance! |
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.
@alpinho I left a couple comments to solve the CircleCI failure and to clarify a point I don't understand.
I'll take a look at the test errors you're getting to see what might be causing them.
@alpinho I had a look at the test failure that you get. nilearn/nilearn/input_data/multi_nifti_masker.py Lines 209 to 211 in d066c23
Here is a little snippet that reproduces the issue: import numpy as np
from nilearn.image import get_data
from numpy.testing import assert_array_equal
from nilearn._utils import check_niimg
from nibabel import Nifti1Image
from nilearn.masking import compute_brain_mask
rng = np.random.RandomState(42)
imgs = [Nifti1Image(rng.uniform(size=(9, 9, 5)), np.eye(4)),
Nifti1Image(rng.uniform(size=(9, 9, 5)), np.eye(4))]
item_gen = check_niimg(imgs, return_iterator=True)
for _ in item_gen:
pass
for mask_type in ['whole-brain', 'gm', 'wm']:
print('-'*4 + ' ' + mask_type + ' ' + '-'*4)
mask = compute_brain_mask(imgs[0],
threshold=0.5, # This doen't change the results for gm and wm
connected=True,
opening=2,
mask_type=mask_type)
assert mask.shape == (9, 9, 5)
assert_array_equal(mask.affine, imgs[0].affine)
print(np.sum(get_data(mask)))
Does this make sense? |
@alpinho I think the problem happens here (all selected slices are empty...): nilearn/nilearn/image/resampling.py Lines 579 to 580 in d066c23
We get to this line because we satisfy this condition: nilearn/nilearn/image/resampling.py Lines 552 to 555 in d066c23
I haven't thought too much about it yet, but I think a quick fix would be to force the resampling in resampled_template = cache(resampling.resample_to_img, memory)(template, target_img, force_resample=True) I tried it briefly and it seems to work as expected. WDYT? |
Codecov Report
@@ Coverage Diff @@
## main #2738 +/- ##
==========================================
+ Coverage 88.47% 88.54% +0.07%
==========================================
Files 100 100
Lines 13588 13667 +79
Branches 2652 2670 +18
==========================================
+ Hits 12022 12102 +80
+ Misses 975 974 -1
Partials 591 591
Continue to review full report at Codecov.
|
Thank you very much for your thorough and clear explanation @NicolasGensollen. Your advice also makes sense to me and I have implemented it in my last commit. All checks have passed now. Yet, "Codecov Report" still reports some red segments. Is this problematic? |
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.
Co-authored-by: Jérôme Dockès <jerome@dockes.org>
@jeromedockes But that solution does not work on my side. This is my error log: ---------------------------------------------------------------------------
UnboundLocalError Traceback (most recent call last)
<ipython-input-3-aa844c641ab4> in <module>
----> 1 load_mni152_gm_template()
~/mygit/nilearn/nilearn/datasets/struct.py in load_mni152_gm_template(resolution)
210
211 if resolution is None:
--> 212 if not _MNI_RES_WARNING_ALREADY_SHOWN:
213 warnings.warn("Default resolution of the MNI template will change "
214 "from 2mm to 1mm in version 0.10.0", FutureWarning)
UnboundLocalError: local variable '_MNI_RES_WARNING_ALREADY_SHOWN' referenced before assignment That's why I decided to do a class. Is there any other workaround? |
UnboundLocalError: local variable '_MNI_RES_WARNING_ALREADY_SHOWN' referenced before assignment
```
That's why I decided to do a class. Is there any other workaround?
right, sorry I forgot you need to add
`global _MNI_RES_WARNING_ALREADY_SHOWN`
in the function before using this variable
|
Ah! Great! Yes, now it seems it is working as expected. Well, I guess I have addressed all of your comments. Let us know whether it looks good from your side. Thanks! |
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.
2 small details
Well, I guess I have addressed all of your comments. Let us know whether it looks good from your side. Thanks!
Yes! thanks again for all this work.
when having a final look I saw 2 small issues that will be easily fixed
(see other comments).
otherwise it LGTM!
Let's give @bthirion and @NicolasGensollen time to do another review if
they want then I'll merge it
|
@jeromedockes One last question: codecov is complaining because it seems that the lines of the warning messages are not being tested now. I am not sure how to fix this now with the global var. |
you can add a test like this one in test_struct.py: @pytest.mark.parametrize("part", ["_brain", "_gm", "_wm"])
@pytest.mark.parametrize("kind", ["template", "mask"])
def test_mni152_resolution_warnings(part, kind):
struct._MNI_RES_WARNING_ALREADY_SHOWN = False
if kind == "template" and part == "_brain":
part = ""
loader = getattr(struct, f"load_mni152{part}_{kind}")
try:
loader.cache_clear()
except AttributeError:
pass
with warnings.catch_warnings(record=True) as w:
loader(resolution=1)
assert len(w) == 0
with warnings.catch_warnings(record=True) as w:
loader()
loader()
assert len(w) == 1 |
Co-authored-by: Jérôme Dockès <jerome@dockes.org>
I think functools is throwing some errors for Python <= 3.7 |
Ok. But this last snippet of code is already written in the function, exactly after defining the `loader`, no?
yes, I edited it after posting this comment
|
I think functools is throwing some errors for Python <= 3.7
replace
```
functools.lru_cache
```
with
```
@functools.lru_cache(maxsize=3)
```
|
Hello! @jeromedockes , is there anything else that should be fixed? @NicolasGensollen and @bthirion , let us know what you think. Thx! |
Hello! @jeromedockes , is there anything else that should be fixed? @NicolasGensollen and @bthirion , let us know what you think. Thx!
everything LGTM! I'm just waiting to see if there are more comments from
the other reviewers before merging :)
|
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.
LGTM too! 👍
Thanks a lot!
thanks a lot @alpinho ! |
This PR tries to address the issue #2487.