Closed jcohenadad closed 4 years ago
Thanks @jcohenadad !
I just had a look at this - installed ANTs from source, created some labels for two images (guillaumegilbert and Aaschen) and mask as you said, but then I hit a bit of a wall when I ran your script. The script runs, but the images that I selected (guillaumegilbert as the reference image, Aaschen as the source image) didn't generate a registered nifti image or jpg for the Aaschen target image.
So then, I tried to process the labels you shared to above (NIST_labels.zip), and for me the script generated some registered images for source nifti images, but didn't for others:
The T1 maps from siyuhanhu, guillaumegilbert, and iveslevesque produced registered niftifi files and jpgs, whereas mrel and Aaschen did not. Any clue of why this might happen for me?
Below is the log file saved using script
from when I ran you scripts.
p.s. I'm using ANTs Version: 2.3.3.dev168-g29bdf
Hum, there was a problem when copying the header from the Gilbert site to another site. I’ll try to reproduce with your version of Ants and after downloading a fresh bundle of the data.
Ok, thanks! If you'd let me know of the version that you have installed, I could try with that one too. Eventually I'll create a Dockerfile for this repo.
@mathieuboudreau i can reproduce your error, with my current configuration, after fresh download of the data. I must have modified some of the headers while playing with the data, which made it work on my end, but forgot to keep track of everything. Working on it... Bad start for reproducible science 😅
the fundamental problem is that some nifti files have a corrupted qform (any idea why? do you know if the files were processed with custom scripts before submitting them to the challenge?), and as a result many ANTs functions will not read them. Example:
PrintHeader Aachen_MR1_Complex_t1map.nii.gz
libc++abi.dylib: terminating with uncaught exception of type itk::ExceptionObject: /Users/julien/temp/ants/build/staging/include/ITK-5.1/itkImageBase.hxx:184:
itk::ERROR: Image(0x7f840dae0310): Bad direction, determinant is 0. Direction is 1 0
0 -0
Abort trap: 6
i'm looking into ways to reset the header, while minimizing the dependencies.
EDIT 2020-06-08 13:09:32: the problem is that ITK checks data integrity before loading, and if there are inconsistencies, it crashes. See here. Note: i've tried SetDirectionByMatrix
as suggested but it also crashes.
@mathieuboudreau i found a fix using fslcpgeom
, is that OK to add this dependency?
@mathieuboudreau i found a fix using
fslcpgeom
, is that OK to add this dependency?
I think that should be ok. The plan was always to make this script into a Dockerfile/docker container. I'll look into installing FSL in one.
@mathieuboudreau can you try 66f1a1cafab9ac824342d741619aba9fae10124d?
the fundamental problem is that some nifti files have a corrupted qform (any idea why? do you know if the files were processed with custom scripts before submitting them to the challenge?), and as a result many ANTs functions will not read them. Example:
PrintHeader Aachen_MR1_Complex_t1map.nii.gz libc++abi.dylib: terminating with uncaught exception of type itk::ExceptionObject: /Users/julien/temp/ants/build/staging/include/ITK-5.1/itkImageBase.hxx:184: itk::ERROR: Image(0x7f840dae0310): Bad direction, determinant is 0. Direction is 1 0 0 -0 Abort trap: 6
i'm looking into ways to reset the header, while minimizing the dependencies.
EDIT 2020-06-08 13:09:32: the problem is that ITK checks data integrity before loading, and if there are inconsistencies, it crashes. See here. Note: i've tried
SetDirectionByMatrix
as suggested but it also crashes.
The only thing that I suspected can't be it. We did encounter an issue with some Philips scans, as the DICOM that's produced by these scanners can be in two different formats ("Classic DICOM" or "Enhanced DICOM"), and these can cause issues for qMRI as the Enhanced DICOM isn't properly consistently between acquisition. For some scans, we had to use tools internal to Philips developers to convert some of their data drom Enhanced DICOM back to Classic DICOM.
However, even though Aaschen is a Philips site, mrel is not (GE). So it's possible that this is simply a result of different Dicom to NIFTI converters, or some scanner-specific differences in how they handle the DICOMs I guess?
@mathieuboudreau can you try 66f1a1c?
That worked for the labelled dataset you provided, thanks!
However, I just tried it on my own labelled dataset, and it appears that something is not working for the labels/masks that I created myself.
No registered mask is produced for Aaschen in my case.
I created the labeled datasets and mask using FSLeyes, following these steps:
single
and double
datatypes)Here is a zipped file with my labels & images: Archive.zip
Did you do your labels with FSLeyes, or another software? Is there a step missing in my workflow, or did I make a mistake somewhere?
@mathieuboudreau i do it differently, see here: https://www.youtube.com/watch?v=HblJ_skvU44
Perfect - that solved it. Thanks for the video instructions!
After trying a fully-automatic method, I realized that some acquisitions are too different from each other. Notably, the positioning of the phantom and acquisition matrix size, makes it difficult to obtain a reliable co-registration to a reference image.
So, the proposed strategy involves the creation of three labels (doesn't need to be exactly at the middle, but roughtly), as illustrated here: .
A first step involves label-based affine realignment, and a second step involves image-based affine registration. This strategy relies on ANTs, so that's an added dependency.
To prevent the registration algorithm from using the phantom edge, I've added a mask (only on the reference image):
Here is are some results on 5 datasets:
(here the reference image was:
20200210_guillaumegilbert_muhc_NIST_Magnitude_t1map.nii.gz
).To reproduce these results, download and unzip the labels + mask under the 3T/NIST folder: NIST_labels.zip
Then run:
Note: this script needs to run from within the image folder.
I realize this is not "perfect", mainly due to a site acquiring the phantom in a non-orthogonal way, which "distorts" the circles. We could get around it by adding a non-linear step to the registration (I've quickly tried BsplineSyN and it gives satisfactory results). Also, using the T1-weighted images could slightly improve results.
Finally, I suggest, for the final analysis pipeline, to apply the inverse composed affine transformed to the masks (created on the ref image), so that noise properties are not altered when computing statistics. Although I think if there is enough voxels, statistics should not be altered too much (mean, variance).
Related to https://github.com/rrsg2020/analysis/issues/1