Skip to content
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/WIP] Robust EPI Mask for heavily nonuniform image #1050

Closed
wants to merge 19 commits into from
Closed

[ENH/WIP] Robust EPI Mask for heavily nonuniform image #1050

wants to merge 19 commits into from

Conversation

zhifangy
Copy link
Contributor

Ref #1000

When processing heavily nonuniform bold data (eg, from 64 channels head coils), the MaskEPI step in init_enhance_and_skullstrip_bold_wf often give bad results.

This PR tweaks some parameters in MaskEPI and adds an addition N4 correction step before MaskEPI. I have tested the code on a multiband dataset and several legacy images. Generally it gives better or equal results with little additional computation cost.

@effigies
Copy link
Member

Hi, thanks for this. Sorry about the slow response.

Looking at this, my main concern is that we're adding steps when we may achieve the same result by rearranging. That is init_mask and skullstrip_first_pass are the same command, as are init_correct and n4_correct.

Under the hypothesis that these two steps are doing very little after having been run previously, I would try removing skullstrip_first_pass and n4_correct, and hook the output of n4_mask where skullstrip_first_pass is being used, and see how that affects things.

That said, if 9 steps are required, that's fine. I just want to consider whether we can simplify before we go ahead and add.

@oesteban
Copy link
Member

oesteban commented Apr 19, 2018

I think this is all very reasonable (the proposed solution to a particular problem, and further revision from @effigies).

On the other hand, I have the feeling that we are touching on an edge case here. I checked visually more than 2000 masks (of 10000 which run without errors), and it'd be a waste to have a regression on this.

I propose the following: @ZhifangYe would you be satisfied if we add a flag (say --robust-bold-inu or similar) that enables your tweak?

In a future, if more and more users report they are using the flag, we could make it the default.

WDYT?

@oesteban
Copy link
Member

oesteban commented Apr 19, 2018

Hi all, after discussing this issue, we would like to set up some extra tests to avoid regressions on masking. We plan to work on these new tests along next week. This way this PR can be accepted as is (without implementing new optional arguments etc) when the new tests are passing.

@zhifangy
Copy link
Contributor Author

After review the process, I agree to the comment from @effigies that we can simplify the workflow. The idea here is we need to feed a uniformed image to MaskEPI node. The histogram based masking method in MaskEPI would fail for heavily nonuniform data no matter what parameters we use. As long as we normalize epi data before MaskEPI, I think results should be fine. In my experience, BET always gives a more loose mask for both corrected and uncorrected image. So I think remove skullstrip_first_pass and n4_correct should be OK. I will test this idea and report back.

As for an addition flag suggest by @oesteban , I'm satisfied with it. But I'm little concerned that other users would be confused without context. So if this tweak don't change behaviors on tested data, I think we may want to include it as default. Look forward to the extra tests results.

@oesteban
Copy link
Member

oesteban commented May 2, 2018

I've asked for these data (https://neurostars.org/t/ica-aroma-error-in-fmriprep-mask-and-image-must-be-the-same-size/1605/4) to add in the test battery.

When "prescan normalize" is on, it seems that images are more homogeneous and our masking heuristics get lost. I wonder if this PR would fix that.

@zhifangy
Copy link
Contributor Author

zhifangy commented May 3, 2018

I inspected the report and have a impression that prescan normalization add additional noise in non-brain regions. The noise intensity seems fall into the range of brain signal.

In current PR, the mask from FSL BET before n4 correct is included in final mask calculation. This generally gives a coarse but robust mask which could exclude these noisy voxels.

@oesteban If you could share some test data with me, I would like to test them locally and evaluate the performance.

@oesteban
Copy link
Member

oesteban commented May 3, 2018

@effigies is currently working on setting up the masks tests for current and future implementations of this stage. Will let you know when this is available 👍

@effigies
Copy link
Member

effigies commented Aug 9, 2018

Hi @ZhifangYe. Sorry for taking so long to get back to you on this. #1074 is almost done, so I'm going to merge it in here to see what effect your changes have on our existing datasets.

@effigies
Copy link
Member

effigies commented Aug 9, 2018

Well, that's failing. Running locally to see what the differences are. They could be minor.

combine_masks node is now combine_masks2
@effigies
Copy link
Member

effigies commented Aug 9, 2018

Tests passing at a symmetric overlap threshold of 0.95. Here are the absolute sizes (in voxels) before and after:

1,14c1,14
< ds000116/sub-12_task-visualoddballwithbuttonresponsetotargetstimuli_run-02_bold_mask.nii.gz float32 [ 64,  64,  32] 3.00x3.00x4.00   sform 1:44517
< ds000133/sub-06_ses-post_task-rest_run-01_bold_mask.nii.gz                                  float32 [ 64,  64,  30] 4.00x4.00x4.00   sform 1:24680
< ds000140/sub-32_task-heatpainwithregulationandratings_run-02_bold_mask.nii.gz               float32 [ 80,  80,  42] 2.80x2.80x3.00         1:60263
< ds000157/sub-23_task-passiveimageviewing_bold_mask.nii.gz                                   float32 [ 64,  64,  30] 4.00x4.00x3.99   sform 1:21536
< ds000210/sub-06_task-rest_run-01_echo-1_bold_mask.nii.gz                                    float32 [ 72,  72,  46] 3.00x3.00x3.00   sform 1:57475
< ds000210/sub-06_task-rest_run-01_echo-2_bold_mask.nii.gz                                    float32 [ 72,  72,  46] 3.00x3.00x3.00   sform 1:55082
< ds000210/sub-06_task-rest_run-01_echo-3_bold_mask.nii.gz                                    float32 [ 72,  72,  46] 3.00x3.00x3.00   sform 1:52088
< ds000216/sub-03_task-rest_echo-1_bold_mask.nii.gz                                           float32 [ 80,  80,  36] 3.00x3.00x3.00   sform 1:45485
< ds000216/sub-03_task-rest_echo-2_bold_mask.nii.gz                                           float32 [ 80,  80,  36] 3.00x3.00x3.00   sform 1:42676
< ds000216/sub-03_task-rest_echo-3_bold_mask.nii.gz                                           float32 [ 80,  80,  36] 3.00x3.00x3.00   sform 1:40151
< ds000216/sub-03_task-rest_echo-4_bold_mask.nii.gz                                           float32 [ 80,  80,  36] 3.00x3.00x3.00   sform 1:38029
< ds000237/sub-03_task-MemorySpan_acq-multiband_run-01_bold_mask.nii.gz                       float32 [ 64,  64,  48] 3.00x3.00x3.00   sform 1:60327
< ds000237/sub-06_task-MemorySpan_acq-multiband_run-01_bold_mask.nii.gz                       float32 [ 64,  64,  48] 3.00x3.00x3.00   sform 1:51879
< ds001362/sub-01_task-taskname_run-01_bold_mask.nii.gz                                       float32 [ 88,  88,  64] 2.39x2.39x2.40   sform 1:8526
---
> ds000116/sub-12_task-visualoddballwithbuttonresponsetotargetstimuli_run-02_bold_mask.nii.gz float32 [ 64,  64,  32] 3.00x3.00x4.00   sform 1:42037
> ds000133/sub-06_ses-post_task-rest_run-01_bold_mask.nii.gz                                  float32 [ 64,  64,  30] 4.00x4.00x4.00   sform 1:24342
> ds000140/sub-32_task-heatpainwithregulationandratings_run-02_bold_mask.nii.gz               float32 [ 80,  80,  42] 2.80x2.80x3.00         1:59962
> ds000157/sub-23_task-passiveimageviewing_bold_mask.nii.gz                                   float32 [ 64,  64,  30] 4.00x4.00x3.99   sform 1:21592
> ds000210/sub-06_task-rest_run-01_echo-1_bold_mask.nii.gz                                    float32 [ 72,  72,  46] 3.00x3.00x3.00   sform 1:57717
> ds000210/sub-06_task-rest_run-01_echo-2_bold_mask.nii.gz                                    float32 [ 72,  72,  46] 3.00x3.00x3.00   sform 1:54989
> ds000210/sub-06_task-rest_run-01_echo-3_bold_mask.nii.gz                                    float32 [ 72,  72,  46] 3.00x3.00x3.00   sform 1:51198
> ds000216/sub-03_task-rest_echo-1_bold_mask.nii.gz                                           float32 [ 80,  80,  36] 3.00x3.00x3.00   sform 1:45502
> ds000216/sub-03_task-rest_echo-2_bold_mask.nii.gz                                           float32 [ 80,  80,  36] 3.00x3.00x3.00   sform 1:42192
> ds000216/sub-03_task-rest_echo-3_bold_mask.nii.gz                                           float32 [ 80,  80,  36] 3.00x3.00x3.00   sform 1:38919
> ds000216/sub-03_task-rest_echo-4_bold_mask.nii.gz                                           float32 [ 80,  80,  36] 3.00x3.00x3.00   sform 1:35955
> ds000237/sub-03_task-MemorySpan_acq-multiband_run-01_bold_mask.nii.gz                       float32 [ 64,  64,  48] 3.00x3.00x3.00   sform 1:60031
> ds000237/sub-06_task-MemorySpan_acq-multiband_run-01_bold_mask.nii.gz                       float32 [ 64,  64,  48] 3.00x3.00x3.00   sform 1:52943
> ds001362/sub-01_task-taskname_run-01_bold_mask.nii.gz                                       float32 [ 88,  88,  64] 2.39x2.39x2.40   sform 1:99964

@effigies
Copy link
Member

effigies commented Aug 9, 2018

The multi-echo runs in particular seem to produce more conservative masks. @oesteban I might want your eyes for some of this. It's hard to tell if they're over-conservative, given the overall image contrast level.

@effigies
Copy link
Member

Plots of the old/new masks are being saved as artifacts.

@oesteban
Copy link
Member

What's red and what's green? Can I assume that red == old?

@effigies
Copy link
Member

effigies commented Aug 10, 2018 via email

@effigies
Copy link
Member

Oh, you mean the contours? I think the more conservative masks are the new ones. Which I think does align red/green. But you wrote ROIsPlot, so you'll know better than I.

@chrisgorgo
Copy link
Contributor

Since #1074 wa merged we should work on getting this contribution incorporated in FMRIPREP (since we can check if nothing regresses).

@effigies
Copy link
Member

effigies commented Sep 3, 2018

Right, sorry, Oscar and I discussed off-thread that there are regressions where previously good masks are now (slightly) too conservative. It's unclear whether the best path forward is further tweaking on this PR or permitting options.

@effigies
Copy link
Member

effigies commented Sep 7, 2018

Okay, getting back to this. If I remember correctly, @oesteban's thought was to use a quick affine registration to register a template EPI image, then dilate the mask by a few voxels to create the initial pre-N4 mask. Once that's done, we may be able to otherwise use the existing method.

I'll be looking into this this afternoon.

@chrisgorgo
Copy link
Contributor

@oesteban
Copy link
Member

oesteban commented Oct 16, 2018

Hi @ZhifangYe, it took excessively long for us to set up the regression tests and then summer fell over us quickly.

I've been working on an alternative to the current brain extraction workflow (see #1321), and now I'll test on the dataset you handled us (https://openneuro.org/datasets/ds001240).

First question is: would you be happy if we added the first 50 timepoints of your dataset to our battery of regression tests? Any issues with having for open download just cropped bold files?

Second question is: do you have more failing examples you can test #1321 on?

I think we are going to go ahead with your PR and merge it, however in #1321 we are after a long-term, more robust solution.

These are the regression tests I'm talking about (green is your PR and red our pre-cached results with the current implementation in fmriprep):

Probably, the only case that you would say your idea worked worse than before are https://5097-53175327-gh.circle-artifacts.com/0/tmp/data/reports/ds000216/sub-03_task-rest_echo-3_bold_masks.svg and https://5097-53175327-gh.circle-artifacts.com/0/tmp/data/reports/ds000216/sub-03_task-rest_echo-4_bold_masks.svg. However, in this case it worked better: https://5097-53175327-gh.circle-artifacts.com/0/tmp/data/reports/ds000237/sub-03_task-MemorySpan_acq-multiband_run-01_bold_masks.svg.

@effigies
Copy link
Member

I've added some code to save a bundle of the mask files so that, in cases like this where we change the mask algorithm, we can easily upload the new files to OSF.

@oesteban oesteban changed the title ENH: Robust EPI Mask for heavily nonuniform image [ENH] Robust EPI Mask for heavily nonuniform image Oct 17, 2018
@oesteban
Copy link
Member

@ZhifangYe, in addition to #1050 (comment), please have a look on #1322 (comment) and let us know whether you want to have your name added in the .zenodo.json file

@zhifangy
Copy link
Contributor Author

Hi, @oesteban , thanks for the efforts on this PR. The regression test looks really good.

I'm happy to have my data included in the battery of regression test. The BOLD files should already be anonymized.

I have a quick look at #1321 and feel it is very promising. I will build an image for this PR to test it locally and report back. There're several failed examples in my dataset I could test on.

Also, there's a related issue I recently discovered. For some BOLD image, the N4 correction works fine on the generated reference image before fieldmap unwrapping but fails on the unwrapped image. It produced bad final brain mask even in my current PR. I will see whether #1321 resolve this problem. If not, I think we should look into it.

BTW, I'm already in the .zenodo.json file because of previous PR. Thanks for asking.

@oesteban
Copy link
Member

Okay, then let's hold off merging this PR until we get feedback from you regarding those failing cases. I'll merge #1326 into #1321 so that you can get proper reports.

@oesteban oesteban changed the title [ENH] Robust EPI Mask for heavily nonuniform image [ENH/WIP] Robust EPI Mask for heavily nonuniform image Oct 17, 2018
oesteban added a commit that referenced this pull request Oct 17, 2018
Refs. #1000, #1050, #1321.

Also includes a new filter of branches so builds other than tests
are skipped if the name of the branch starts with ``tests?/``.
@oesteban
Copy link
Member

Closed via #1321

@oesteban oesteban closed this Oct 27, 2018
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.

None yet

4 participants