Question on how to use fieldmap with fmriprep

Please forgive me for the somewhat basic question.

I have a 4D fieldmap for an fMRI-scan that includes both forward and reverse PE directions, which I would
like to use in fmriprep for SDC.

  1. What are the specific BIDS naming conventions I should use? (e.g. sub-01_task-A_dir-both.nii.gz)
  2. Does the “IntendedFor” field need to be manually added to the .json?

Hi @ajschadler,

The BIDS spec contains a section on different fieldmap cases and how to appropriately label in BIDS. Your fieldmap example sounds strange, it almost sounds to me like you have two spin-echo field maps that were combined into a single file? Did you use dcm2niix to convert your DICOMS to nifti/json files?

I don’t believe the BIDS validator is going to like dir-both, you would typically specify the phase encoding direction (e.g. dir-AP, dir-PA, etc) for the direction label.

Yes, for any fieldmap json file, you will need to add the IntendedFor field and add the path(s) of the func-bold (or dwi) file(s) that the fieldmap will perform SDC on. Once that’s done, fmriprep will be able to automatically handle SDC without further user intervention.

Both directions were acquired in a single run. Hmm, after the initial dcm2niix conversion, I could split the file. Incidentally, here is the .json file from the initial dcm2niix conversion. (N.B. some identifiable sections were removed, e.g. “InstitutionName”)

{                                                                                                                                                                                               
    "Modality": "MR",
    "Manufacturer": "GE",
    "AcquisitionNumber": 1,
    "SoftwareVersions": "27_LX_MR_Software_release:DV26.0_R01_1725.a",
    "ScanningSequence": "EP_RM",
    "SequenceVariant": "NONE",
    "BodyPartExamined": "BRAIN",
    "ImageType": ["ORIGINAL", "PRIMARY", "OTHER"],
    "MagneticFieldStrength": 3,
    "FlipAngle": 90, 
    "EchoTime": 0.08,
    "RepetitionTime": 7.8,
    "PhaseEncodingLines": 108,
    "EffectiveEchoSpacing": 0.000608,
    "ConversionSoftware": "dcm2niix",
    "ConversionSoftwareVersion": "v1.0.20170818 GCC4.4.7"
}

It should be noted: no section for “Phase Encoding Direction” was outputted.

You appear to be using an old dcm2niix version. I’d suggest upgrading to the newest release and see if that changes how dcm2niix handles the acquisition.

Here is an updated .json, using the latest dcm2niix:

{
	"Modality": "MR",
	"MagneticFieldStrength": 3,
	"ImagingFrequency": 127.719,
	"Manufacturer": "GE",
	"PulseSequenceName": "epi",
	"InternalPulseSequenceName": "EPI",
	"ManufacturersModelName": "DISCOVERY MR750",
	"BodyPartExamined": "BRAIN",
	"PatientPosition": "HFS",
	"SoftwareVersions": "27\\LX\\MR Software release:DV26.0_R01_1725.a",
	"MRAcquisitionType": "2D",
	"SeriesDescription": "fMRI_Field_Map_VPA",
	"ScanningSequence": "EP\\RM",
	"SequenceVariant": "NONE",
	"ScanOptions": "SAT_GEMS\\EDR_GEMS\\MP_GEMS\\EPI_GEMS\\FS",
	"ImageType": ["ORIGINAL", "PRIMARY", "OTHER"],
	"SeriesNumber": 4,
	"AcquisitionNumber": 1,
	"TriggerDelayTime": 31070,
	"SliceThickness": 2,
	"SpacingBetweenSlices": 2,
	"SAR": 0.265701,
	"EchoTime": 0.08,
	"RepetitionTime": 7.8,
	"FlipAngle": 90,
	"PhaseEncodingPolarityGE": "Flipped",
	"CoilString": "RM:Nova32ch",
	"PercentPhaseFOV": 100,
	"PercentSampling": 100,
	"AcquisitionMatrixPE": 108,
	"ReconMatrixPE": 128,
	"EffectiveEchoSpacing": 0.000512252,
	"TotalReadoutTime": 0.065056,
	"PixelBandwidth": 3906.25,
	"PhaseEncodingDirection": "j",
	"SliceTiming": [
		0,
		3.9,
		0.13,
		4.03,
		0.26,
		4.16,
		0.39,
		4.29,
		0.52,
		4.42,
		0.65,
		4.55,
		0.78,
		4.68,
		0.91,
		4.81,
		1.04,
		4.94,
		1.17,
		5.07,
		1.3,
		5.2,
		1.43,
		5.33,
		1.56,
		5.46,
		1.69,
		5.59,
		1.82,
		5.72,
		1.95,
		5.85,
		2.08,
		5.98,
		2.21,
		6.11,
		2.34,
		6.24,
		2.47,
		6.37,
		2.6,
		6.5,
		2.73,
		6.63,
		2.86,
		6.76,
		2.99,
		6.89,
		3.12,
		7.02,
		3.25,
		7.15,
		3.38,
		7.28,
		3.51,
		7.41,
		3.64,
		7.54,
		3.77,
		7.67	],
	"ImageOrientationPatientDICOM": [
		1,
		-0,
		0,
		-0,
		1,
		0	],
	"InPlanePhaseEncodingDirectionDICOM": "COL",
	"ConversionSoftware": "dcm2niix",
	"ConversionSoftwareVersion": "v1.0.20210317"
}

Just to clarify, there is only 1 nifti/json file pair even after using the updated dcm2niix version? And that this fieldmap is for func-bold data?

Since your data comes from a GE scanner, I’m curious whether this is a case of GE’s direct field mapping? This would assume that there is a fieldmap nifti/json and magnitude nifti/json pairs. It would also be ideal if you could provide the SeriesDescription information from the json as well, if possible.

Another potential option could be to rerun dcm2niix with the -m n option, though I haven’t tried it.

I added the SeriesDescription to the previous post:

{
	"SeriesDescription": "fMRI_Field_Map_VPA",
}

Only 1 nifti/json combo is generated, even with the -m n option. The outputted nifti is 4D with 4 volumes. It is also, indeed, for func-bold data. Would info from 3dinfo -VERB | fslhd | mri_info | dcmdump / dcminfo also be helpful?

I personally haven’t come across much GE data before, so take this with a grain of salt, but it could be that the first two volumes have a specific PED, and the other two volumes contain a 180 degree flipped PED. If so, you could split your single 4D fieldmap nifti file into two, that way each has an opposing PED, and then use the dir- entity label to differentiate the two in BIDS format. You would also need to make a copy of the json file and change "PhaseEncodingDirection": "j-", to "PhaseEncodingDirection": "j",

I’m going to loop in @Chris_Rorden, as he may have a better idea of your issue.

Actually you are absolutely correct! Volumes 2 and 4 have a 180 degree flipped PED. I can try splitting the file, copying the .json, adding the fields and use the BIDS convention you mentioned.

1 Like

I’m with a project that is currently dealing with this same kind of data coming from a GE scanner. It sounds like you’ve got a plan. I’d be curious to know how you plan to flip the data, because it seems tricky to get right.

Our current plan is to use the following commands from fsl. But I’m not completely confident in them

# separate each of the four volumes into separate niftis
fslsplit input.nii.gz

# merge second and fourth volume to make AP fieldmap
fslmerge -t ap.nii.gz vol0001.nii.gz vol0003.nii.gz

# merge first and third volume to make PA fieldmap 
# (these are in reversed orientation)
fslmerge -t pa.nii.gz vol0000.nii.gz vol0002.nii.gz

# reorder the second axis of PA image
# note that fslswapdim updates the qform/sform matrices
# but in such a way that x-axis stops matching the 
# data
fslswapdim pa.nii.gz x -y z pa_swap-y.nii.gz

# copy sform/qform of the correctly oriented AP back to PA image
sform=$(fslorient -getsform ap.nii.gz )
fslorient -setsform ${sform} pa_swap-y.nii.gz
fslorient -copysform2qform pa_swap-y.nii.gz

@ajschadler and @psadil can either of you share a dataset directly with me (e.g. shared via Box to my institution email) so I can take a look at what dcm2niix is doing. It would also be nice to have permission to share a copy with GE engineers (specifically @mr-jaemin).

There are two forms of field map allowed by BIDS:

  • A gradient-echo image that directly measures the field. This would be used by a tool like FSL’s FUGUE. This will only have a single phase encoding polarity.
  • A spin-echo sequence, where one acquires two sets of images where are settings are identical except the phase encoding polarity. This does not directly measure field. This would be used by FSL’s TOPUP, which will assume that the spatial distortions are equal magnitude but opposite direction, so the correct shape is in the middle of the two. This makes the most sense for diffusion weighted images (where the data of interest is spin echo).

Your dataset does look like it belongs to the latter class: the protocol name is fMRI_Field_Map_VPA but the TR = 7800ms and the TE = 80ms, which sounds like DWI parameters.

Hi @Chris_Rorden. Thanks for the offer! At least for the shareable part of the dataset that I’m working on, I think that you may have already seen the participant; they’re referred to as " PulseSequenceName: epi_pepolar " in heudiconv github issue 479. But let me know if you’d like me to send it

I don’t know about the dataset being worked on by @ajschadler

@psadil I suspect your assumption is correct that the issues you and @ajschadler are having are due to a custom ABCD research sequence that does not correctly document the phase encoding polarity in the DICOM header. dcm2niix generally assume that the DICOM image is truthful, and coming up with heuristics to handle incorrectly specified DICOMs is a recipe for unintended consequences. It would be great if the ABCD team to fix this upstream (and also clean up some of the DICOM files they artificially created from GE p-files that have various issues). The ABCD team has created a terrific resource, the sequences are well designed. It would be great if they could aid in the curation of this resource.

Do resend the dataset. I was asked not to keep the one sent to me last December.

@psadil and @ajschadler can you try out the dcm2niix developmental branch (v1.0.202100811). This implements a kludge described here. A minimal build on a Unix machine would look like this:

git clone --branch development https://github.com/rordenlab/dcm2niix.git
cd dcm2niix/console
make

@Chris_Rorden Thanks for update! Confirming that when we used v1.0.20210081 on the dataset that we shared with you, the resulting images were correctly generated. And their json sidecars also seem to be accurate (i.e., identical, but the nifti that was generated from the second and fourth volumes has "PhaseEncodingPolarityGE": "Flipped" and "PhaseEncodingDirection": "j", while the other has "PhaseEncodingPolarityGE": "Unflipped" and "PhaseEncodingDirection": "j-"). But I guess you already knew how the updates performed on this dataset.

I’ll run this in a larger sample soon (within a week or so). If there are issues, I’ll report back here

I wanted to briefly follow up on this discussion.
Since I am doing this using a dcm2bids container, I’m having to use an older version of dcm2niix (~v2020). For now, I’ve made a python script that produces similar output to yours, just wanted to double check if the flipping and PA/AP labeling makes sense to you:

import nibabel as nib

orig_stem = "sub-01_acq-func_run-01_epi"
subdir = "./BIDS/raw/sub-01"

orig = nib.load(f'{subdir}/fmap/{orig_stem}.nii.gz')
header = orig.header
affine = orig.affine

## Load Data matrix
orig_np = orig.get_fdata()

# Extract reverse phase-encoded maps

tth = orig_np.shape[3]
PA = []
AP = []
i=0
while i < tth:
    AP.append(i)
    PA.append(i+1)
    i=i+2

fmapPA = orig_np[...,PA]
fmapAP = orig_np[...,AP]

# Flip y-axis of fmapAP
fmapAP = np.flip(fmapAP, axis = 1)

# Create new nifti images

fmapPA_nif = nib.Nifti1Image(
        fmapPA,
        affine = affine,
        header = header)
fmapAP_nif = nib.Nifti1Image(
        fmapAP,
        affine = affine,
        header = header)

A couple questions regarding flipping data and correctly labeling PE:

  1. Am I flipping the correct fieldmap? (i.e. fmapAP)
  2. Should 'PhaseEncodingDirection': 'j' be “AP” or “PA”, for direction label?

@ajschadler,

I’d recommend checking out fmriprep’s get_world_pedir function. You’ll need two inputs: orientation (can determine this with something like AFNI’s 3dinfo -orient command), and the pe_direction (from the dcm2niix metatdata). The output will tell you the direction to use for the BIDS dir- entity label.

1 Like

Thank you for the tip.

Still somewhat confused at the convention.
If the image is either RPI or LPI, then the positive j, y-axis, moves from posterior to anterior, right?
Negative direction would be moving from anterior to posterior, right?
If so, wouldn’t positive be PA (from posterior to anterior) and negative be AP (from anterior to posterior)?

Or am I misunderstanding the convention? If so, clarification is much appreciated!

Yes you right: If the image is RPI or LPI, this means that for the second dimension, when the cursor increases, it is going toward the Posterior.
But “j” is for P>A encoding direction, “j-” is A>P direction.

I agree this is confusing: I encourage you to look at this documentation page from MRTRIX:
https://mrtrix.readthedocs.io/en/latest/concepts/pe_scheme.html#fixed-phase-encoding

especially this note:

The phase encoding direction is defined specifically with respect to image axes . It is therefore not affected by the image strides , which only affect how the data for these axes are arranged when they are stored as a one-dimensional list of values within a file.

As this is said, there are two different things: the images axis which are defined at the scanner console, and the image “strides” , or data storage, which can be modified afterwards but does not change the image axis. So “j” or “j-” stay the same even if you change you image data storage from , say, “LPS” to “RAS”.