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

Register NIST phantom data to ROI for subsequent quantification #10

Merged
merged 21 commits into from
Aug 4, 2020

Conversation

jcohenadad
Copy link
Collaborator

@jcohenadad jcohenadad commented Jul 27, 2020

Extending on #6, the purpose of this PR is to set up a pipeline to register the NIST phantom data to the ROI for subsequent mask-based quantification.

The following has been done:

  • Download ROIs when running register_t1maps_nist.py
  • Create initial labels for registering the ROI to all NIST phantom data
  • Update the registration parameters to work with synthetic phantom instead of with an arbitrary reference site (previously: gilbert)
  • Apply the inverse transformation of each site to the curated ROI (labeled, eroded).

Additional improvements:

  • Removed FSL dependency (now using nibabel)

Fixes #1

TODO: do this download outside of this CLI (ie should be part of another "install required data" CLI)
These labels {1, 2, 3} are used for the first affine transformation between the ROI image and each NIST site
- now using nibabel
- fixed bug that happened when using fslsplit on 4d single-slice data --> the output image was 2d instead of 3d, which created a blanck image when applying the transfo obtained from the 3d labels
@jcohenadad
Copy link
Collaborator Author

jcohenadad commented Jul 28, 2020

Preliminary results (with ab22c7a) of registration directly to the NIST phantom roi:

results_reg_20200728121800

TODO:

  • Mis-registrations to figure out

@jcohenadad
Copy link
Collaborator Author

Mis-registrations to figure out

This is caused by some sites acquiring data with the phantom flipped along its axis, causing the labels to go from the trigonometric rotation to anti-trigo, causing the label-based registration to fail (because it is a 2d transfo-- so this is an ill-posed registration problem).

a solution would be to detect those cases, and flip the data (along with the labels)

@mathieuboudreau
Copy link
Collaborator

@jcohenadad Do you want me to figure out manually/visually which datasets have that property? (i.e. clockwise decreasing T1 values vs counter-clockwise, if I understand correctly?)

@jcohenadad
Copy link
Collaborator Author

Mis-registrations to figure out

This is caused by some sites acquiring data with the phantom flipped along its axis, causing the labels to go from the trigonometric rotation to anti-trigo, causing the label-based registration to fail (because it is a 2d transfo-- so this is an ill-posed registration problem).

a solution would be to detect those cases, and flip the data (along with the labels)

ha! my bad-- given that i have replaced fslsplit with nibabel, output names are different, so the final gif generation included the 'bad' registration. Things might workout well at the end-- let me re-run with a fresh re-install of the data

@jcohenadad
Copy link
Collaborator Author

jcohenadad commented Jul 28, 2020

yay! 🎉

results_reg_20200728141807

next steps:

  • cleanup (create API for header modif via nibabel)
  • bring labels to native T1 space
  • Update doc

@jcohenadad
Copy link
Collaborator Author

jcohenadad commented Jul 28, 2020

@mathieuboudreau i have a prototype that seems to be working (deb7ba1). Example for one site below (cannot easily aggregate all sites into a single gif, because native spaces have different matrix sizes):

anim

The output masks are generated as: 3T_NIST_T1maps_pooled/*_mask.nii.gz

@mathieuboudreau
Copy link
Collaborator

@mathieuboudreau i have a prototype that seems to be working (deb7ba1). Example for one site below (cannot easily aggregate all sites into a single gif, because native spaces have different matrix sizes):

anim

The output masks are generated as: 3T_NIST_T1maps_pooled/*_mask.nii.gz

Huh, somehow I missed this comment! Must have gotten lost in my email due to the alerts I got from your git commits just after - sorry for the slow response. I'm going to test it now!

@mathieuboudreau
Copy link
Collaborator

@jcohenadad I just ran the script, and it didn't error. However, I encountered two issues so far when looking at the outputs:

1- The ROI mask NIFTIs and T1 maps seem to be in different spaces, or have different orientations, see FSLeyes screenshots:

Capture d’écran 2020-08-02 à 22 10 33

Capture d’écran 2020-08-02 à 22 10 28

2 - Several ROI files are missing in the pooled folder, and I have no idea why. e.g. for the "20200305_ngmaforo_ucla" dataset, the mask files were generated for the two Skyra measurements (Skyra_FS and Skyra_noFS) however the two Prisma measurements don't have accompanying ROI masks in that folder (for Prisma_FS and Prisma_noFS). Masks for other datasets are missing too, such as for the "20201802_jalnefjord" dataset. Searching through the log output from the scripts, these don't appear anywhere in it. They are also missing from both your gif in this current thread (#10 (comment)), and the previous PR (#6 (comment))... They also all are present in the config files, so maybe this is a NIFTI format issue?

Any clue what might be causing both issues, and if there might be quick fixes for them?

@jcohenadad
Copy link
Collaborator Author

@mathieuboudreau looking into it now

@mathieuboudreau
Copy link
Collaborator

Thanks @jcohenadad !

I browsed through the outputs, and these are the ones that appear to have missing output masks/ROIS:

20201802_jalnefjord_sahlgrenska_NIST_Complex_T1map.nii.gz
20200305_ngmaforo_ucla_Prisma_noFS_NIST_Magnitude_T1map.nii.gz
20200305_ngmaforo_ucla_Prisma_FS_NIST_Magnitude_T1map.nii.gz
20200302_wang_MDAnderson_day2_NIST_Complex_T1map.nii.gz
20200302_wang_MDAnderson_day1_NIST_Complex_T1map.nii.gz
20200225_CStehningPhilipsClinicalScienceGermany_Hamburg_MR1_NIST_Complex_T1map.nii.gz
20200225_CStehningPhilipsClinicalScienceGermany_Cologne_MR4_NIST_Complex_T1map.nii.gz
20200225_CStehningPhilipsClinicalScienceGermany_Cologne_MR3_NIST_Complex_T1map.nii.gz
20200225_CStehningPhilipsClinicalScienceGermany_Cologne_MR1_NIST_Complex_T1map.nii.gz
20200225_CStehningPhilipsClinicalScienceGermany_Bonn_MR1_NIST_Complex_T1map.nii.gz
20200225_CStehningPhilipsClinicalScienceGermany_Berlin_MR1_NIST_Complex_T1map.nii.gz
20200225_CStehningPhilipsClinicalScienceGermany_Aachen_MR1_NIST_Complex_T1map.nii.gz
20200210_guillaumegilbert_muhc_NIST_Complex_T1map.nii.gz
20200121_matthewgrechsollars_ICL_NIST_Complex_T1map.nii.gz

@jcohenadad
Copy link
Collaborator Author

1- The ROI mask NIFTIs and T1 maps seem to be in different spaces, or have different orientations, see FSLeyes screenshots:

i can reproduce it. I'm working on it-- shouldn't be too long (just a matter of copying the qform from the T1map).

2 - Several ROI files are missing in the pooled folder, and I have no idea why. e.g. for the "20200305_ngmaforo_ucla" dataset, the mask files were generated for the two Skyra measurements (Skyra_FS and Skyra_noFS) however the two Prisma measurements don't have accompanying ROI masks in that folder (for Prisma_FS and Prisma_noFS). Masks for other datasets are missing too, such as for the "20201802_jalnefjord" dataset. Searching through the log output from the scripts, these don't appear anywhere in it. They are also missing from both your gif in this current thread (#10 (comment)), and the previous PR (#6 (comment))... They also all are present in the config files, so maybe this is a NIFTI format issue?

Oopsi, I think there was a misunderstanding originating from this comment #6 (comment). I wrongly thought that i should only deal with dataType=magnitude data. Sorry about that.

I'll first deal with the first comment, and hopefully the fix for the second comment will be easy (i could see how it can go wrong, so fingers crossed...)

@mathieuboudreau
Copy link
Collaborator

mathieuboudreau commented Aug 3, 2020

2 - Several ROI files are missing in the pooled folder, and I have no idea why. e.g. for the "20200305_ngmaforo_ucla" dataset, the mask files were generated for the two Skyra measurements (Skyra_FS and Skyra_noFS) however the two Prisma measurements don't have accompanying ROI masks in that folder (for Prisma_FS and Prisma_noFS). Masks for other datasets are missing too, such as for the "20201802_jalnefjord" dataset. Searching through the log output from the scripts, these don't appear anywhere in it. They are also missing from both your gif in this current thread (#10 (comment)), and the previous PR (#6 (comment))... They also all are present in the config files, so maybe this is a NIFTI format issue?

Oopsi, I think there was a misunderstanding originating from this comment #6 (comment). I wrongly thought that i should only deal with dataType=magnitude data. Sorry about that.

I'll first deal with the first comment, and hopefully the fix for the second comment will be easy (i could see how it can go wrong, so fingers crossed...)

Ahh kk, well you know, the second problem, it's not the end of the world, because I think all of them are the same "space" as the magnitude data, so I could just deal with replacing "Complex" to "Magnitude" for the rois in my post processing. If anything, it kinda makes more sense to only register the magnitude data, and not do it twice for those datasets.

However, that wouldn't explain why two of the datasets is missing, 20200305_ngmaforo_ucla_Prisma_noFS_NIST_Magnitude_T1map.nii.gz and 20200305_ngmaforo_ucla_Prisma_FS_NIST_Magnitude_T1map.nii.gz, as these are magnitude data.

@jcohenadad
Copy link
Collaborator Author

jcohenadad commented Aug 3, 2020

@mathieuboudreau can you check if f28fa73 fixes the different output space problem (first issue listed)?

important note: the outputs to consider now have the suffix: _T1map_modifheader_mask.nii.gz and _T1map_modifheader.nii.gz

@jcohenadad
Copy link
Collaborator Author

However, that wouldn't explain why two of the datasets is missing, 20200305_ngmaforo_ucla_Prisma_noFS_NIST_Magnitude_T1map.nii.gz and 20200305_ngmaforo_ucla_Prisma_FS_NIST_Magnitude_T1map.nii.gz, as these are magnitude data.

looking into this now

@mathieuboudreau
Copy link
Collaborator

However, that wouldn't explain why two of the datasets is missing, 20200305_ngmaforo_ucla_Prisma_noFS_NIST_Magnitude_T1map.nii.gz and 20200305_ngmaforo_ucla_Prisma_FS_NIST_Magnitude_T1map.nii.gz, as these are magnitude data.

Actually there is at least one more dataset missing, "20201802_jalnefjord_sahlgrenska_NIST_Complex_T1map.nii.gz", as that one doesn't have a magnitude mask.

@jcohenadad
Copy link
Collaborator Author

However, that wouldn't explain why two of the datasets is missing, 20200305_ngmaforo_ucla_Prisma_noFS_NIST_Magnitude_T1map.nii.gz and 20200305_ngmaforo_ucla_Prisma_FS_NIST_Magnitude_T1map.nii.gz, as these are magnitude data.

ah! easy fix: these are not listed in the json file 😉

@jcohenadad
Copy link
Collaborator Author

and this one does not appear because of the datatype issue:

                "dataType": "Complex",
                "real":{
                    "imagePath": "20201802_jalnefjord_sahlgrenska_NIST/20201802_jalnefjord_sahlgrenska_NIST_Real.nii.gz"
                },
                "imaginary":{
                    "imagePath": "20201802_jalnefjord_sahlgrenska_NIST/20201802_jalnefjord_sahlgrenska_NIST_Imaginary.nii.gz"
                }

@jcohenadad
Copy link
Collaborator Author

#10 (comment) @mathieuboudreau i let you update the json file as you have all the info (you can push directly on my branch)

@mathieuboudreau
Copy link
Collaborator

@mathieuboudreau can you check if f28fa73 fixes the different output space problem (first issue listed)?

important note: the outputs to consider now have the suffix: _T1map_modifheader_mask.nii.gz and _T1map_modifheader.nii.gz

Yup, those two files now share the same space, that resolves issue number 1, thanks!

@mathieuboudreau
Copy link
Collaborator

And issue number 2 is mostly resolved, the only dataset that doesn't have an ROI is 20201802_jalnefjord_sahlgrenska_NIST_Complex_T1map.nii.gz as no magnitude dataset exists for this one. But I can make a note of it and we can look into this later on.

@mathieuboudreau
Copy link
Collaborator

@jcohenadad I noticed a third (minor?) issue. It seems like at least one step of the resampling or registration of the masks is not doing nearest neighbour interpolation, such that we have the "fifty shades of grey" issue at the ROI borders. Is this something that could be fixed easily? If not, no worries, thresholding the ROIs as-is could be sufficient for now, and we could fix this later.

@jcohenadad
Copy link
Collaborator Author

you can just add -n NearestNeighbor for the last antsApplyTransforms command (or i can do it tmr morning)

@mathieuboudreau
Copy link
Collaborator

you can just add -n NearestNeighbor for the last antsApplyTransforms command (or i can do it tmr morning)

Done, thanks!

Copy link
Collaborator

@mathieuboudreau mathieuboudreau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jcohenadad I did another test and it seems to be currently working as intended. THANK YOU!!! This pipeline is excellent, I greatly appreciate all the help & time you've given these past few weeks/months.

I've uploaded the ROIs on OSF in a folder called challenge_rois, which has the same directory structure as the raw data and T1 map folders there. I've added a config in the repo for the ROIs too that points to the mask files & osf repos. For the complex datasets, because time is currently tight, I (manually...) copied the masks generated for the magnitude datasets and replace "Magnitude" with "Complex", and added a README explaining why this was done. I also added a README in the 20201802_jalnefjord_sahlgrenska_NIST dataset to explain why the mask is missing there. I'm going to open issues in this repo about it.

Again, thank you!

@mathieuboudreau
Copy link
Collaborator

Just a brief update for record keeping purposes.

Plotted the means and std's for all datasets & rois in the mb/plots branch. Here are the results:

Linear T1 plot:

00_alldatasets

Log-Log T1 plot:

01_alldatasets

Error (%) plot:

02_alldatasets

In the linear plot, a few ROI's have huge standard deviations. This is due to to misregistration, where a few voxels from the background phantom are contaminating the ROI with voxels of very high T1s. E.g.,

Capture d’écran 2020-08-05 à 09 32 27

For that dataset in particular, there's severe warping or slice mispositionning in the original images for some of the spheres (i.e. some spheres are about half the radius as others), so I'm not surprised that a few of them didn't work out perfectly during the registration. This should either manually corrected and noted in the records, or we could attempt to improve the registration if it's feasible. But either of these options should only be done after the meeting.

@jcohenadad
Copy link
Collaborator Author

In the linear plot, a few ROI's have huge standard deviations. This is due to to misregistration, where a few voxels from the background phantom are contaminating the ROI with voxels of very high T1s. E.g.,

in the image you show, given that the majority of the pixels is overlapping with the sphere, how about using another metric less sensitive to outliers, like the median? Of course, the STD will still be affected, but at least the T1 estimate (which is what we mostly care about, right?) will be more accurately represented.

@mathieuboudreau
Copy link
Collaborator

In the linear plot, a few ROI's have huge standard deviations. This is due to to misregistration, where a few voxels from the background phantom are contaminating the ROI with voxels of very high T1s. E.g.,

in the image you show, given that the majority of the pixels is overlapping with the sphere, how about using another metric less sensitive to outliers, like the median? Of course, the STD will still be affected, but at least the T1 estimate (which is what we mostly care about, right?) will be more accurately represented.

Good point - yes, absolutely!

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.

Registration of phantom & human datasets, and ROIs.
2 participants