Bad DICOM headers and wrong Bits_Stored value

Hi,

I am currently looking at a dataset of 2D Dicom files collected from Philips 3T scanner. So far, I’ve encountered two problems in the dataset:

(1) Bad DICOM headers - assuming oblique scaling direction!

This warning showed up when I ran
Dimon -infile_pattern ‘*.dcm’ -GERT_Reco -quit -use_last_elem -use_slice_loc -dicom_org -sort_by_acq_time -save_details dimon_details
in the data folder (resting state fMRI data). Dimon version 4.14. I then ran the GERT_Reco script to produce AFNI datasets.

I did a bit google search and found in another thread where Daniel Glen suggested that " This will only be important if you export to NIFTI format for cardinal data." I just wanted to convert the dicom files to AFNI datasets and run afni_proc.py, so I assumed this warning can be ignored.

However, out of curiosity, I also tried using dcm2niix on the dicom files and then 3dcopy xxx.nii xxx+orig to produce AFNI datasets. When I compared the datasets obtained through dcm2niix + 3dcopy and that from Dimon+to3d, the images looked similar. But when I clicked on ‘Graph’ on the AFNI GUI, the time series of the two datasets did not seem to match.

So my question is: does this mean I should not ignore this error? What can I do to address this error?

(2) xxx.dcm has Bits_Stored=16 and High_Bit=11
This also happened when I ran the above Dimon command. Normally, my dicom files have Bits_Stored=12 and High_Bit=11, but some subjects have Bits_Stored=16 and High_Bit=11 and Dimon reports a warning. Is this something I should be worry about, or can this just be a typo from someone’s manual input?

Thank you! :slight_smile:

Philips data can have its own special scale factor slope and intercept. dcm2niix has an option for converting Philips slope and intercept scaling that Dimon and to3D do not, so that may be responsible for the difference. I think this is through the dcm2niix -p option, but I’m not really sure. For most EPI or structural data, this doesn’t make much difference, but it is important when dealing with some other image acquisition protocols like DCE-MRI where every TR gets scaled differently.

I got this information a number of years ago from the interoperability manager at Philips regarding scale factors :

[size=medium]There are 2 subsequent scaling processes, each having their own scaling parameters.
Internal floating point (FP) → SCALING → Stored Values (SV) → RE-SCALING and windowing → display values (DP)
Currently there are 4 parameters that play a role in scaling:
SI: Scale Intercept (2005,100D) scale shift mostly 0, except e.g. for Real Images, value is stored in a private DICOM field
SS: Scale Slope (2005,100E) the factor that creates Stored Values (SV) in the range of 0-4096, is private DICOM field
RI: Rescale Intercept (0028,1052) the scale shift, mostly 0.
RS: Rescale Slope (0028,1053) the factor that creates display values in the required unit. for non quantitative images this is unit-less.
RI and RS are influenced by the Control Reconstruction Parameters: fixed scale factor type and fixed scale factor (see below)
and by the service setting: “Combine Rescaling” (when Combine Rescaling = YES, RI and RS are forced to 0 and 1 resp.)
Of course the window settings are adapted accordingly, to get a familiar display on the workstation = equal to that of the console display.
WL: Window Center (Level) (0028,1050)
WW: Window Width (0028,1051)
For your reference: these values may be overruled by those in a Presentation State (GSPS) object, but for quantification this is not relevant.
We have the following MR values:
FP internal Floating Point MR values
SV Stored Values, the DICOM Pixel Data (7FE0,0010)
DV Display values: this is the value as calculated by ROI statistics on the MR console
When we restrict ourselves here to Modulus (Magnitude) images, then the SCALE Intercept is always : 0. This also holds for the Rescale Intercept
The following relations apply (sorry John, your maths are different from ours, but for RI = 0, the result is the same).
eq 1: SV = FP * SS + SI (from internal floats to Stored Values)
eq 2: DV = SV * RS +RI (from Stored Values to Display Values)
If you can take the SV values directly from the DICOM file (or the REC file or the NII file (values appear to be equal)) then from eq 1:
FP = (SV-SI) / SS
Otherwise you will need to process the DV values with all 4 parameters. Substituting SV in eq 2 results in :
FP = (DV-RI- (SIRS))/ (RSSS)
SS and SI are defined in the reconstruction process, and are depending on the technique and the noise measurement in the preparation phase.
The values may be kept at a fixed level over scans, when the control recon parameter “fixed scale factor type” is set to “DOTS” or to “Abs MR signal”.
This will yield displayed values that are directly proportional to the MR signal and to the so called floating point scale of the images within the reconstruction software.
The proportionality factor can be set using the control recon parameter “fixed scale factor”.
The setting of this parameter is arbitrary, but it should be kept constant over scans that should show amplitude consistency.[/size]

These are some relevant links about this topic with suggestions:

https://www.nitrc.org/forum/forum.php?thread_id=7322&forum_id=4703
https://www.nitrc.org/forum/message.php?msg_id=20990
https://www.jiscmail.ac.uk/cgi-bin/webadmin?A2=MRICRO;72607100.1512
https://afni.nimh.nih.gov/afni/community/board/read.php?1,120877,121168#msg-121168
https://afni.nimh.nih.gov/afni/community/board/read.php?1,142584,142594#msg-142594

Hi Daniel,

Thank you! I tried dcm2niix, and a concern to me is that it does not seem to capture any slice timing information.
When I did: 3dinfo -slice_timing xxx.nii, the output was just 0,000000|0,000000|…

Did you mean that the ‘Bad DICOM headers - assuming oblique scaling direction!’ warning is from Dimon and to3d being confused about the Philips scaling? If that’s the case I might be able to just ignore the warning, since I am just doing normal resting-state fMRI analysis.

How about the warning of ‘xxx.dcm has Bits_Stored=16 and High_Bit=11’? Is this something that I should be worried about? I could not find any other threads that talk about this warning.

Dimon actually assumes alt+z for slice timing unless otherwise
specified. That is a default I often consider changing, except that
it would probably break scripts for a lot of people. It may be quite
reasonable for dcm2niix to not including any slice timing.

Do you know what the timing should be?

For the High Bit warning, that looks good, assuming there is no
4095 problem. If High Bit = 11, the largest number they can
store is 4095. That is okay if the data is not actually reaching
the number. But if it is, there can be truncation artifacts in
the dataset. Just to see, run something like this on the datasets:

3dTto1D -input epi+orig -method 4095_warn

  • rick

Hi Rick and Daniel,

Thank you for your help!

I did a little more googling and I am pretty sure dcm2niix does not read or store the slice timing information. I finally decided to do this:

dcm2niix -f %i_%d_%s -p y ./
3dcopy *.nii xxx+orig
3dTcat xxx+orig -tpattern alt+z -prefix xxx_interleaved+orig

I know the slice timing is even/odd interleaved (0,2,4,6,…,1,3,5,7,…), so alt+z should work fine for me. I also read that Philips scanners do not seem to store slice timing information in DICOM files, so one has to refer to a protocol document to figure out the slice timing. Although I am not sure how true this statement is.

dcm2niix did not complain about the High_Bit, but I still used 3dTto1D -input xxx_interleaved+orig -method 4095_warn. The outputs are:

++ computing 4095_warn, nvox = 196608, nmask = 196608, nt = 140
++ global max = 6302593.000000
++ max of 6.30259e+06 is okay

However, when I did 3dcopy, AFNI warned that it was converting nifti INT16 to FLOAT32. Isn’t the above maximum 6.30259e+06 way beyond the range of INT16?

There can be a similar scaling there too with a scl_slope factor and an intercept, as described below in the NIFTI definitions. You can check the NIFTI header with nifti_tool to be sure. The INT16 format is the unsigned format instead of the signed 16-bit format we use, so just to be safe, we move the data into a floating point format with 32 bits.

/---------------------------------------------------------------------------/
/* DATA SCALING:

If the scl_slope field is nonzero, then each voxel value in the dataset
should be scaled as
y = scl_slope * x + scl_inter
where x = voxel value stored
y = “true” voxel value
Normally, we would expect this scaling to be used to store “true” floating
values in a smaller integer datatype, but that is not required. That is,
it is legal to use scaling even if the datatype is a float type (crazy,
perhaps, but legal).

float scl_slope ; /*!< Data scaling: slope. / / float funused1; /
float scl_inter ; /
!< Data scaling: offset. / / float funused2; */

I see, so NIFTI stored both the INT16 value and the scaling slope and the AFNI datasets contain the scaled data.

I checked through nifti_tool -disp_hdr -infiles xxx.nii and indeed I found scl_slope = 1873.54.

Thank you!