rordenlab / dcm2niix

dcm2nii DICOM to NIfTI converter: compiled versions available from NITRC
https://www.nitrc.org/plugins/mwiki/index.php/dcm2nii:MainPage
Other
899 stars 229 forks source link

XA60 and XA61 no `MultibandAccelerationFactor` with `cmrr_mbep2d_bold` #870

Closed benoitberanger closed 1 month ago

benoitberanger commented 1 month ago

Describe the bug

The key MultibandAccelerationFactor does not appear in the JSON sidecar on the cmrr_mbep2d_bold sequence in both XA60 and XA61.

To reproduce

dcm2niix -f "%t_%n/S%s_%d/v_%n_S%s_%d" -ba n -o <niftidir> <dicomdir>

Expected behavior

MultibandAccelerationFactor should be present.

Output log

Version

Chris Rorden's dcm2niiX version v1.0.20240202  GCC7.5.0 x86-64 (64-bit Linux)
v1.0.20240202

Troubleshooting

neurolabusc commented 1 month ago

@benoitberanger I do not have access to XA60 hardware. If you want me to help, share a small example with my institutional email. Otherwise, submit a pull request to include the required details.

rorden@mailbox.sc.edu

neurolabusc commented 1 month ago

This is an issue with the source DICOMs and not dcm2niix. The images with multi-band explicitly claim SMS is not enabled in the public tag Parallel Reduction Factor out-of-plane Attribute (0018,9155). dcm2niix assumes that DICOM images are truthful and valid.

        (0018,9069) FD 4                                        #ParallelReductionFactorInPlane
        (0018,9077) CS [YES]                                    #ParallelAcquisition
        (0018,9078) CS [GRAPPA]                                 #ParallelAcquisitionTechnique
        (0018,9081) CS [NO]                                     #PartialFourier
        (0018,9155) FD 1                                        #ParallelReductionFactorOutOfPlane
benoitberanger commented 1 month ago

Here is a sharable DICOM dataset on phantom, made on a 3T Cima.X in XA61.

Dataset

phantom_check_MBfactor_CimaX_XA61.zip

Content

DICOM

PatientID = phantom_check_MBfactor_CimaX_XA61 Series =

S1_loca_3plan_haste/
S2_PRODUCT_ep2d_bold_p2_sms1/
S4_PRODUCT_ep2d_bold_p2_sms2/
S6_PRODUCT_ep2d_bold_p2_sms5/
S8_C2P_cmrr_mbep2d_bold_p2_mb1/
S10_C2P_cmrr_mbep2d_bold_p2_mb2/
S12_C2P_cmrr_mbep2d_bold_p2_mb5/
S14_PRODUCT_ep2d_diff_p2_sms1_TRACEW/
S15_PRODUCT_ep2d_diff_p2_sms2_TRACEW/
S16_C2P_cmrr_mbep2d_diff_p2_mb1/
S18_C2P_cmrr_mbep2d_diff_p2_mb2/

Other

protocol.pdf is the PDF printed from the scanner. All *.pro for each sequence.

neurolabusc commented 1 month ago

@benoitberanger this dataset clearly illustrates the issue. Consider series 4 PRODUCT_ep2d_bold_p2_sms2 where the protocol PDF suggests SMS of 2 while the DICOM public tag Parallel Reduction Factor out-of-plane (0018,9155) explicitly reports a factor of 1. The one thing I notice is that the increase of SMS factor is not influencing the TR, so series 2, 4 and 6 use SMS 1, 2, 5 respectively yet the protocols are not leveraging the benefit of SMS to reduce TR (all report 1230ms for 10 slices).

(0008,1090) LO [MAGNETOM Cima.X]                        #  16, 1 ManufacturerModelName
(0018,1020) LO [syngo MR XA61]                          #  14, 1 SoftwareVersions
 (0018,9155) FD 1   # ParallelReductionFactorOutOfPlane

Screenshot 2024-10-03 at 7 14 49 AM

Perhaps more telling, if you look at the first and second time points in series 2, you will notice that while BOTH report a ParallelReductionFactorOutOfPlane as 1, the CSA header of the first provides slice timing for single-band, while the subsequent one reports multiband:

1st volume:

    "SliceTiming": [
        0.405,
        0,
        0.4875,
        0.08,
        0.5675,
        0.1625,
        0.65,
        0.2425,
        0.73,
        0.325   ],

2nd volume:

    "SliceTiming": [
        0,
        0.725,
        0.2425,
        0.9675,
        0.4825,
        0,
        0.725,
        0.2425,
        0.9675,
        0.4825  ],

So one hypothesis is that the first volume in the series is always a single-band reference, with subsequent volumes applying the multiband. However, if this is the case one should be able to acquire data where the first volume has a longer TR than the subsequent volumes, and the parallel reduction factor changes.

I really do think you need to work with the manufacturer to make sure the DICOMs are truthful.

benoitberanger commented 1 month ago

The one thing I notice is that the increase of SMS factor is not influencing the TR, so series 2, 4 and 6 use SMS 1, 2, 5 respectively yet the protocols are not leveraging the benefit of SMS to reduce TR (all report 1230ms for 10 slices).

This is because I did not change the TR after increasing the acceleration. The objective was to check the DICOM info, I kept all parameters equal as much as possible, so a diff would show the differences in a more readable way.

benoitberanger commented 1 month ago

@eauerbach Do you have any reason to suspect the problem could come from the sequence itself ?

mharms commented 1 month ago

Maybe just run a quick test on the product SMS sequence and check whether its values on (0018,9155) are any different?

neurolabusc commented 1 month ago

@benoitberanger and @mharms the issue is seen in the Siemens product sequences as well as the CMRR research sequences. Therefore, it seems like the root issue must be addressed by the manufacturer. I will see if we can have dcm2niix infer multiband factor from the 2nd volume slice times. dcm2niix already has the core code to do this to deal with a historical issue specific to older CMRR data. However, it is worth noting that dcm2niix assumes that DICOM images are valid and truthful. The public tag (0018,9155) is required for original data with multiband. Therefore, the provided images are not truthful. While I will investigate a kludge to handle this, the opportunity for unintended consequences is great when you disregard explicit details of the specification.

Both product and CMRR sequences are incorrect. You can see this by looking at any of the sequences where SMS > 1:

dcmdump  +P "0018,9155" ./6_PRODUCT_ep2d_bold_p2_sms5/0060_1.3.12.2.1107.5.2.63.213017.2024100310503278136001070.dcm

dcmdump  +P "0018,9155" ./18_C2P_cmrr_mbep2d_diff_p2_mb2/0060_1.3.12.2.1107.5.2.63.213017.2024100311034664642502798.dcm 

dcmdump  +P "0018,9155" ./12_C2P_cmrr_mbep2d_bold_p2_mb5/0060_1.3.12.2.1107.5.2.63.213017.2024100310555488120901609.dcm

all report:

(0018,9155) FD 1 # ParallelReductionFactorOutOfPlane
benoitberanger commented 1 month ago

A ticket to Siemens has been opened by our local Specialist.

benoitberanger commented 1 month ago

Here is a sharable DICOM dataset on phantom, made on a 7T Terra.X in XA60.

Dataset

phantom_check_MBfactor_TerraX_XA60.zip

Content

DICOM

PatientID = phantom_check_MBfactor_TerraX_XA60 Series =

S1_localizer/
S2_PRODUCT_ep2d_bold_p3_sms1/
S4_PRODUCT_ep2d_bold_p3_sms2/
S6_PRODUCT_ep2d_bold_p3_sms5/
S8_C2P_cmrr_mbep2d_bold_p3_mb1/
S10_C2P_cmrr_mbep2d_bold_p3_mb2/
S12_C2P_cmrr_mbep2d_bold_p3_mb5/
S14_PRODUCT_ep2d_diff_p3_sms1/
S16_PRODUCT_ep2d_diff_p3_sms2/
S18_C2P_cmrr_mbep2d_diff_p3_mb1/
S20_C2P_cmrr_mbep2d_diff_p3_mb2/

Other

protocol.pdf is the PDF printed from the scanner. All *.pro for each sequence.

neurolabusc commented 1 month ago

@benoitberanger thanks. This demonstrates that the issue is present in XA60 product sequences as well as XA61:

dcmdump  +P "0018,9155" ./6_PRODUCT_ep2d_bold_p3_sms5/0020_1.3.12.2.1107.5.2.61.237012.2024100414255359638100304.dcm
(0018,9155) FD 1    # ParallelReductionFactorOutOfPlane

Another issue is that the first volume provides single-band slice timing:

    "SliceTiming": [
        0.2125,
        0,
        0.255,
        0.0425,
        0.295,
        0.085,
        0.3375,
        0.1275,
        0.38,
        0.17    ],

While subsequent volumes report multi-band timing

    "SliceTiming": [
        0.615,
        0,
        0.615,
        0,
        0.615,
        0,
        0.615,
        0,
        0.615,
        0   ],

This seems to be a reemergence of historical issues. It seems like three things are required:

  1. Ensure future software releases create valid DICOMs.
  2. Develop a strategy to salvage invalid data.
  3. Understand if the first volume really is a single-band reference or not. For typical multiband acquisitions where the method is explicitly used to reduce the TR this change influences both the event timing for fMRI analyses as well as the contrast in the first volume (in addition to inherent T1 effects). You could measure the RF pulses or the simply record audio that is synchronized with the optical EPI pulse from the scanner to resolve this.
neurolabusc commented 1 month ago

@benoitberanger please test the latest commit to the development branch (v1.0.20241004). Hopefully this use slice timing from the 2nd volume instead of the first if it has a shorter TA, and will estimate multiband with precedence over the value reported in 0018,9155. Both of these events will generate a warning, to help detect unintended consequences. The one caveat here is that it may not detect multiband if the first volume TA matches the second volume (e.g. your prior examples where multiband was used but the TR was the same as single band).

I do hope this kludge resolves the specific issues your data. However, they clearly violate the DICOM specification. I do not consider these images as archival quality and I would suggest that you have your raw DICOMs fixed. All other tools that assume valid and truthful DICOMs will give erroneous results.

julfou81 commented 1 month ago

@neurolabusc , I tried the development version of dcm2niix on our faulty multiband DICOM images in XA60 and the json files were correctly generated with the field MultibandAccelerationFactorcorrectly populated! Thank you so much for being so reactive and so efficient in investigating, explaining and solving this issue! When comparing the json files output by the current stable and development releases of dcm2niix, I noticed the following changes:

$ diff nifti_stable/task-DeepMReyeCalib_run1_bold_20.json nifti_dev/task-DeepMReyeCalib_run1_bold_20.json 
14a15
>   "ConsistencyInfo": "66010002",
16c17
<   "ConversionSoftwareVersion": "v1.0.20240327",
---
>   "ConversionSoftwareVersion": "v1.0.20241004",
38c39,40
<     "NONE"
---
>     "NONE",
>     "MAGNITUDE"
57a60
>   "MultibandAccelerationFactor": 4,
156a160,164
>   "TablePosition": [
>     0,
>     0,
>     -0
>   ],
benoitberanger commented 1 month ago

Like @julfou81, I confirm that 31306908091409cf7402a7686b0dc367c2544c4f fixes the MultibandAccelerationFactor field.

$ grep Multiband nifti_*/*/*/*json
nifti_dev/20241003104114_phantom_check_MBfactor_CimaX_XA61/S10_C2P_cmrr_mbep2d_bold_p2_mb2/v_phantom_check_MBfactor_CimaX_XA61_S10_C2P_cmrr_mbep2d_bold_p2_mb2.json:    "MultibandAccelerationFactor": 2,
nifti_dev/20241003104114_phantom_check_MBfactor_CimaX_XA61/S12_C2P_cmrr_mbep2d_bold_p2_mb5/v_phantom_check_MBfactor_CimaX_XA61_S12_C2P_cmrr_mbep2d_bold_p2_mb5.json:    "MultibandAccelerationFactor": 5,
nifti_dev/20241003104114_phantom_check_MBfactor_CimaX_XA61/S15_PRODUCT_ep2d_diff_p2_sms2_TRACEW/v_phantom_check_MBfactor_CimaX_XA61_S15_PRODUCT_ep2d_diff_p2_sms2_TRACEW.json:  "MultibandAccelerationFactor": 2,
nifti_dev/20241003104114_phantom_check_MBfactor_CimaX_XA61/S18_C2P_cmrr_mbep2d_diff_p2_mb2/v_phantom_check_MBfactor_CimaX_XA61_S18_C2P_cmrr_mbep2d_diff_p2_mb2.json:    "MultibandAccelerationFactor": 2,
nifti_dev/20241003104114_phantom_check_MBfactor_CimaX_XA61/S4_PRODUCT_ep2d_bold_p2_sms2/v_phantom_check_MBfactor_CimaX_XA61_S4_PRODUCT_ep2d_bold_p2_sms2.json:  "MultibandAccelerationFactor": 2,
nifti_dev/20241003104114_phantom_check_MBfactor_CimaX_XA61/S6_PRODUCT_ep2d_bold_p2_sms5/v_phantom_check_MBfactor_CimaX_XA61_S6_PRODUCT_ep2d_bold_p2_sms5.json:  "MultibandAccelerationFactor": 5,
nifti_dev/20241004141746_phantom_check_MBfactor_TerraX_XA60/S10_C2P_cmrr_mbep2d_bold_p3_mb2/v_phantom_check_MBfactor_TerraX_XA60_S10_C2P_cmrr_mbep2d_bold_p3_mb2.json:  "MultibandAccelerationFactor": 2,
nifti_dev/20241004141746_phantom_check_MBfactor_TerraX_XA60/S12_C2P_cmrr_mbep2d_bold_p3_mb5/v_phantom_check_MBfactor_TerraX_XA60_S12_C2P_cmrr_mbep2d_bold_p3_mb5.json:  "MultibandAccelerationFactor": 5,
nifti_dev/20241004141746_phantom_check_MBfactor_TerraX_XA60/S16_PRODUCT_ep2d_diff_p3_sms2/v_phantom_check_MBfactor_TerraX_XA60_S16_PRODUCT_ep2d_diff_p3_sms2.json:  "MultibandAccelerationFactor": 2,
nifti_dev/20241004141746_phantom_check_MBfactor_TerraX_XA60/S20_C2P_cmrr_mbep2d_diff_p3_mb2/v_phantom_check_MBfactor_TerraX_XA60_S20_C2P_cmrr_mbep2d_diff_p3_mb2.json:  "MultibandAccelerationFactor": 2,
nifti_dev/20241004141746_phantom_check_MBfactor_TerraX_XA60/S4_PRODUCT_ep2d_bold_p3_sms2/v_phantom_check_MBfactor_TerraX_XA60_S4_PRODUCT_ep2d_bold_p3_sms2.json:    "MultibandAccelerationFactor": 2,
nifti_dev/20241004141746_phantom_check_MBfactor_TerraX_XA60/S6_PRODUCT_ep2d_bold_p3_sms5/v_phantom_check_MBfactor_TerraX_XA60_S6_PRODUCT_ep2d_bold_p3_sms5.json:    "MultibandAccelerationFactor": 5,

nifti_release/20241003104114_phantom_check_MBfactor_CimaX_XA61/S15_PRODUCT_ep2d_diff_p2_sms2_TRACEW/v_phantom_check_MBfactor_CimaX_XA61_S15_PRODUCT_ep2d_diff_p2_sms2_TRACEW.json:  "MultibandAccelerationFactor": 2,
nifti_release/20241003104114_phantom_check_MBfactor_CimaX_XA61/S4_PRODUCT_ep2d_bold_p2_sms2/v_phantom_check_MBfactor_CimaX_XA61_S4_PRODUCT_ep2d_bold_p2_sms2.json:  "MultibandAccelerationFactor": 2,
nifti_release/20241003104114_phantom_check_MBfactor_CimaX_XA61/S6_PRODUCT_ep2d_bold_p2_sms5/v_phantom_check_MBfactor_CimaX_XA61_S6_PRODUCT_ep2d_bold_p2_sms5.json:  "MultibandAccelerationFactor": 5,
nifti_release/20241004141746_phantom_check_MBfactor_TerraX_XA60/S16_PRODUCT_ep2d_diff_p3_sms2/v_phantom_check_MBfactor_TerraX_XA60_S16_PRODUCT_ep2d_diff_p3_sms2.json:  "MultibandAccelerationFactor": 2,
nifti_release/20241004141746_phantom_check_MBfactor_TerraX_XA60/S4_PRODUCT_ep2d_bold_p3_sms2/v_phantom_check_MBfactor_TerraX_XA60_S4_PRODUCT_ep2d_bold_p3_sms2.json:    "MultibandAccelerationFactor": 2,
nifti_release/20241004141746_phantom_check_MBfactor_TerraX_XA60/S6_PRODUCT_ep2d_bold_p3_sms5/v_phantom_check_MBfactor_TerraX_XA60_S6_PRODUCT_ep2d_bold_p3_sms5.json:    "MultibandAccelerationFactor": 5,

During the nifti conversion, the warnings are visible :

benoit.beranger@icm-cenir-le33: /tmp/dcm2niix $ dcm2niix -f "%t_%n/S%s_%d/v_%n_S%s_%d" -ba n -o /tmp/dcm2niix/nifti_dev/ phantom_check_MBfactor_TerraX_XA60/
Chris Rorden's dcm2niiX version v1.0.20241004  GCC7.5.0 x86-64 (64-bit Linux)
Found 60 DICOM file(s)
slice orientation varies (localizer?) [0 1 0 0 0 -1] != [1 0 0 0 0 -1]
Convert 3 DICOM as /tmp/dcm2niix/nifti_dev/20241004141746_phantom_check_MBfactor_TerraX_XA60/S8_C2P_cmrr_mbep2d_bold_p3_mb1/v_phantom_check_MBfactor_TerraX_XA60_S8_C2P_cmrr_mbep2d_bold_p3_mb1 (64x64x10x3)
slice orientation varies (localizer?) [0 1 0 0 0 -1] != [1 0 0 0 0 -1]
Convert 1 DICOM as /tmp/dcm2niix/nifti_dev/20241004141746_phantom_check_MBfactor_TerraX_XA60/S1_localizer/v_phantom_check_MBfactor_TerraX_XA60_S1_localizer (512x512x13x1)
Convert 7 DICOM as /tmp/dcm2niix/nifti_dev/20241004141746_phantom_check_MBfactor_TerraX_XA60/S14_PRODUCT_ep2d_diff_p3_sms1/v_phantom_check_MBfactor_TerraX_XA60_S14_PRODUCT_ep2d_diff_p3_sms1 (64x64x10x7)
Warning: Issue870: Slice timing range of first volume: range 0..910, TA= 910, TR=3000 ms)
Warning: Issue870: Slice timing range of 2nd volume: range 10115..12515, TA= 2400, TR=3000 ms)
Convert 7 DICOM as /tmp/dcm2niix/nifti_dev/20241004141746_phantom_check_MBfactor_TerraX_XA60/S16_PRODUCT_ep2d_diff_p3_sms2/v_phantom_check_MBfactor_TerraX_XA60_S16_PRODUCT_ep2d_diff_p3_sms2 (64x64x10x7)
Convert 3 DICOM as /tmp/dcm2niix/nifti_dev/20241004141746_phantom_check_MBfactor_TerraX_XA60/S2_PRODUCT_ep2d_bold_p3_sms1/v_phantom_check_MBfactor_TerraX_XA60_S2_PRODUCT_ep2d_bold_p3_sms1 (64x64x10x3)
Warning: Issue870: Slice timing range of first volume: range 0..380, TA= 380, TR=1230 ms)
Warning: Issue870: Slice timing range of 2nd volume: range 6622.5..7237.5, TA= 615, TR=1230 ms)
Convert 3 DICOM as /tmp/dcm2niix/nifti_dev/20241004141746_phantom_check_MBfactor_TerraX_XA60/S6_PRODUCT_ep2d_bold_p3_sms5/v_phantom_check_MBfactor_TerraX_XA60_S6_PRODUCT_ep2d_bold_p3_sms5 (64x64x10x3)
Convert 7 DICOM as /tmp/dcm2niix/nifti_dev/20241004141746_phantom_check_MBfactor_TerraX_XA60/S18_C2P_cmrr_mbep2d_diff_p3_mb1/v_phantom_check_MBfactor_TerraX_XA60_S18_C2P_cmrr_mbep2d_diff_p3_mb1 (64x64x10x7)
Warning: Issue870 ParallelReductionFactorOutOfPlane estimated as 2 but DICOM reports 1
Convert 7 DICOM as /tmp/dcm2niix/nifti_dev/20241004141746_phantom_check_MBfactor_TerraX_XA60/S20_C2P_cmrr_mbep2d_diff_p3_mb2/v_phantom_check_MBfactor_TerraX_XA60_S20_C2P_cmrr_mbep2d_diff_p3_mb2 (64x64x10x7)
Warning: Issue870: Slice timing range of first volume: range 0..370, TA= 370, TR=1230 ms)
Warning: Issue870: Slice timing range of 2nd volume: range 6575..7560, TA= 985, TR=1230 ms)
Convert 3 DICOM as /tmp/dcm2niix/nifti_dev/20241004141746_phantom_check_MBfactor_TerraX_XA60/S4_PRODUCT_ep2d_bold_p3_sms2/v_phantom_check_MBfactor_TerraX_XA60_S4_PRODUCT_ep2d_bold_p3_sms2 (64x64x10x3)
Warning: Issue870 ParallelReductionFactorOutOfPlane estimated as 5 but DICOM reports 1
Convert 3 DICOM as /tmp/dcm2niix/nifti_dev/20241004141746_phantom_check_MBfactor_TerraX_XA60/S12_C2P_cmrr_mbep2d_bold_p3_mb5/v_phantom_check_MBfactor_TerraX_XA60_S12_C2P_cmrr_mbep2d_bold_p3_mb5 (64x64x10x3)
Warning: Issue870 ParallelReductionFactorOutOfPlane estimated as 2 but DICOM reports 1
Convert 3 DICOM as /tmp/dcm2niix/nifti_dev/20241004141746_phantom_check_MBfactor_TerraX_XA60/S10_C2P_cmrr_mbep2d_bold_p3_mb2/v_phantom_check_MBfactor_TerraX_XA60_S10_C2P_cmrr_mbep2d_bold_p3_mb2 (64x64x10x3)
Conversion required 0.082837 seconds (0.065270 for core code).

I'll update the Issue when we have news from Siemens ticket.

Best, Benoît

neurolabusc commented 1 month ago

I am closing this issue. The warnings are clearly warranted. I have no idea whether the first volume is actually a single-band or a multi-band. This clearly impacts timing required for fMRI studies. Further, the DICOM headers clearly violate the DICOM specification. These warnings will disappear once the manufacturer updates their images to conform with the specification.

I do hope my kludge does not have any unintended consequences for valid images. However, these warnings will also flag any regressions.

julfou81 commented 1 month ago

I acquired some test sequences with different acceleration factors on a phantom with Siemens SMS bold sequence. The (0018,9155) field is not present if multiband factor is 1 and GRAPPA is 1. In all the other case the (0018,9155) field is 1. I will also share this with Siemens.

$ list_seq=$(ls -d ep2d*); for seq in $list_seq; do echo "sequence is: $seq"; dcmdump  +P "0018,9155" $seq/3.dcm; done
sequence is: ep2d_bold_s1_p1_2mm_5
sequence is: ep2d_bold_s1_p2_2mm_9
(0018,9155) FD 1                                        #   8, 1 ParallelReductionFactorOutOfPlane
sequence is: ep2d_bold_s2_p1_2mm_7
(0018,9155) FD 1                                        #   8, 1 ParallelReductionFactorOutOfPlane
sequence is: ep2d_bold_s2_p2_2mm_11
(0018,9155) FD 1                                        #   8, 1 ParallelReductionFactorOutOfPlane
benoitberanger commented 1 month ago

Siemens confirmed the fields (0018,9069) and (0018,9155) are incorrect in Enhanced.

neurolabusc commented 1 month ago

The classic DICOMs generated by XA30 have a parallel error. The private tag TimeAfterStart (0021,1104) reports the single-band timing for the first volume, but the multiband timing for subsequent volumes. The error is clearly seen with the discrepancy between this tag and the public tag AcquisitionTime (0008,0032). @jeffreyluci provides a nice example, with the same data saved as enhanced and classic, providing further evidence that the classic data is wrong. This dataset is here 500x_Product_EPI_Sag_Ascending.