I’m converting some data from DICOM into a BIDS format (http://bids.neuroimaging.io/) using Python and AFNI tools, and one remaining snag is determining the phase encoding direction (BIDS term “PhaseEncodingDirection”) of distortion correction scans from the information in their DICOM headers. Has anyone been able to figure this out?
The BIDS specification describes PhaseEncodingDirection as follows:
PhaseEncodingDirection : Possible values: “i”, “j”, “k”, “i-”, “j-”, “k-”. The letters “i”, “j”, “k” correspond to the first, second and third axis of the data in the NIFTI file. The polarity of the phase encoding is assumed to go from zero index to maximum index unless ‘-’ sign is present (then the order is reversed - starting from the highest index instead of zero). PhaseEncodingDirection is defined as the direction along which phase is was modulated which may result in visible distortions. Note that this is not the same as the DICOM term InPlanePhaseEncodingDirection which can have “ROW” or “COL” values. This parameter is required if a corresponding fieldmap data is present or when using multiple runs with different phase encoding directions (which can be later used for field inhomogeneity correction).
I asked a similar question over at Neurostars (https://neurostars.org/t/determining-bids-phaseencodingdirection-from-dicom/612), and the author of dcm2niix (Chris Rorden) weighed in:
If you use Matlab, you can get this easily using dicm2nii - it should provide the same solution as dcm2niix. However, since you mention using Python I think the process will be more involved. You can use the excellent dcmstack to get the DICOM details. DICOM tag 0018,1312 will tell you if the phase encoding is in the Column or Row direction (the NIfTI i and j voxel dimensions; though some FSL tools refer to these as x and y voxel dimensions [which should not be confused with the MNI spatial dimensions of the same name]). Now you need to determine the polarity of the phase encoding. This varies for vendor, but assuming you are using Siemens this will be the tag “PhaseEncodingDirectionPositive” from the private CSA header (Python details at http://nipy.org/nibabel/dicom/siemens_csa.html1). In general, you simply need to detect whether two scans have opposite encoding directions, but note that some tools store rows from top-to-bottom (the way we read lines of text, and the method used by raw DICOM) while others write rows from bottom-to-top (the way we draw a graph, with larger values above lower values on the vertical axis, the default in NIfTI’s forerunner Analyze). Since NIfTI can encode this swap in the S-form, you have to know how your converter copied the rows to solve this. dcm2niix can generate rows in either format depending on the opts.isFlipY flag (which defaults to true, flipping DICOM images to match the Analyze style).
It should be noted that DICOM “COLUMN” and “ROW” do not necessarily correspond with NIfTI dimensions i and j. For example, dcm2nii, dicm2nii and dcm2niix have options to losslessly rotate 3D acquisitions so that they have the closest orthogonal axis to the NIfTI s-form identity matrix (e.g. canonical space). In practice, to my knowledge all converters preserver the Column->i, Row->j for 2D EPI acquisitions. The most popular slice-time correction tools all assume that the images are i*j in plane, and that k refers to different slices.
One bit that I thought the AFNI team might be able to help with is this, and specifically how Dimon (or to3D/Ifile) is reading/writing NIFTI files:
… note that some tools store rows from top-to-bottom (the way we read lines of text, and the method used by raw DICOM) while others write rows from bottom-to-top (the way we draw a graph, with larger values above lower values on the vertical axis, the default in NIfTI’s forerunner Analyze). Since NIfTI can encode this swap in the S-form, you have to know how your converter copied the rows to solve this.
Thanks in advance for any help!