Orientation of input image files to proc.py

Hello experts,

I am using AFNI to preprocess resting state data from the ADNI database. Prior to running the pipeline, I checked the orientation of each of my files that would be input to the proc.py script for each subject using the “3dinfo -oreint” command. I found that the T1 data was in LPI, resting state in RPI, and WM/vent masks generated in freesurfer were in RSP. Prior to running the proc.py scripts, I resampled the resting state data and the freesurfer data to be in LPI to match each other and the structural images. I proceeded to run the processing script in two ways:

  1. Using the original data, in its original, non-resampled orientation
  2. Using the LPI resampled data

Interestingly, when I ran the pipeline using the data that was not resampled, only a few subjects were flagged during the CHECK_FLIP portion of the script. This flip error went away when I used the LPI images as input.

However, an additional problem came up. When I ran the processing pipeline with the LPI resampled images, the script errored out for 10% of my sample with the following error:
3dpc -mask follow_ROI_FSvent+tlrc -pcsave 3 -prefix rm.ROIPC.FSvent.r01 rm.det_pcin_r01+tlrc
++ 3dpc: AFNI version=AFNI_19.2.01 (Jul 3 2019) [64-bit]
** FATAL ERROR: mask is all zeros!

It seems that when the LPI FSvent mask is eroded, no voxels survive but this does not occur with the RSP (non-resampled freesurfer images). Do you know why this would be? Additionally, would you recommend that I resample the images to be in LPI prior to running proc.py or to keep the resting state images and freeesurfer masks in their original orientation?

I really appreciate your help!

Hi, Jenna-

Interesting. What command(s) did you use to resample the data initially?


Hi Paul,

Thanks for your reply. I previously had been using the resting state file as the master when I was resampling. But I was able to fix this issue by eroding the mask first and then resampling to lpi:
3dmask_tool -input fs_ap_latvent.nii -dilate_input -1 -prefix fs_ap_latvent_erode.nii.gz
3dresample -orient lpi -prefix fs_ap_latvent_erode_lpi.nii.gz -input fs_ap_latvent_erode.nii.gz

I did notice another problem though when I was checking the overlay of the masks. It appears that some of my original T1 images are oblique, which results in the masks not overlaying in the proper anatomical position.

There are a few potential issues with my data and it would be great to hear your opinion on whether the following steps I took to solve those issues are necessary. For context, my processing pipeline consists of dcm2niix, SSwarper, reconall/@SUMA_Make_Spec_FS to create WM/CSF masks, and proc.py (very similar to example 11b).

Potential issues/solutions:

  1. The anatomical data (LPI), EPI data (RPI), freesurfer masks (RSP), and atlas (LPI) which I’ll be using for time course extraction are in different orientations. Prior to preprocessing I reoriented the EPI and freesurfer masks to be in LPI space. I did this because in the end I will be extracting time courses from an atlas which is in LPI orientation and I wanted to be sure that when I was extracting the time course form the left PFC, for example, that it truly was the left PFC and not the right. Is it necessary to change the orientation of the EPI/freesurfer files prior to submission to proc.py? Or is the orientation difference taken care of during the align block, since the -master flag is used in many of the commands and the master anat is in LPI orientation?

  2. Some of my T1 images are oblique. Should I cardinalize these images using 3dWarp -deoblique and resubmit the deoblique images to SSWarper, reconall, and @SUMA_Make_Spec_FS steps? The major problem here is that when the original data are used, in oblique format, the resulting Ventricle/WM masks are not aligned to the anatomy and thus signal is being regressed from the wrong portion of the image during preprocessing.

Thank you for your help!

Hi, Jenna-

I think that it is not the differing orientations, but the initial data being oblique, that explains the differences here when you process in different ways.

Running 3dresample purges the obliquity information from the dset—because there are resampling processes that would be inconsistent with the obliquity. So, then you might have an anatomical with obliquity info and a ventricle map that doesn’t have that, and things end up in different places/spaces relatively. I would wager that is what is happening with the PC error message as well: there is no overlap because things are in a different spot.

Re. processing pipeline:

  1. I run that set of programs often, and I don’t worry about dset orientations. However, making sure that obliquity doesn’t cause problems is a larger consideration.

  2. I think the issue is that early dsets (raw anatomical) have obliquity and the derived ones after FreeSurfer (tissue maps) or resampling don’t—that is why things don’t overlap.
    I generally prefer to remove obliquity information from my EPI and anatomical. There are some options how to do this:
    A) “3drefit -deoblique …” will purge the obliquity info, so the input dset is not regridded, and it just has the coordinates as seen in the GUI—the down side is the shopping of the coordinate matrix can leave the current coordinates far from centering the brain around (x,y,z)=(0,0,0); and since the EPI and anatomical are on different grids, they might not end up well aligned anymore even though they started out that way.
    B) “3dWarp -deoblique …” will apply the obliquity info, so the dset is output in scanner coordinates (which were hopefully well-centered to start). But the output dset will have been regridded-- for EPI data, this kind of extra smoothing-by-regridding is something to avoid.
    C) A third option is to remove the obliquity information without regridding BUT preserving the location (x,y,z)=(0,0,0) in the dset; so, if your coordinates are well-centered to start, they wil remain so. And relative obliquity differences (e.g., between a subject EPI and anat) are reduced to hopefully just a minor rotation (to be overcome with the alignment step that will be done, anyways). To do this to create new NIFTI, one could do the following:

3dcopy ${dset}  tmp       # yes, copy to BRIK/HEAD
set sp = `3dinfo -av_space "${dset}"`
3drefit  -oblique_recenter  tmp${sp}
3drefit  -deoblique tmp${sp}
3dcopy tmp${sp} OUTPUT.nii

The attached image shows a comparison of these. In each case, option “B” is underlaid, because that is where the dset is in “scanner coordinates” (the downside of getting it from 3dWarp like this is a slight blurring). The crosshairs are centered at (x,y,z)=(0,0,0). In the top row, the 3drefit-style deobliquing in A is overlayed—notice how the brain is in a non-centered spot; it could certainly be further off, depending on the obliquity information. In the bottom row, the case C is shown—notice how it is still well-centered, looking mainly rotated around the coordinate origin a bit.

If useful, here is a slightly fancier script version of Case C, that I put in a script “do_deoblique_keep_000.tcsh”, which takes 2 arguments-- an input and output dset (and cleans up a temporary file):


# This script will purge obliquity with NO regridding, AND preserve
# where (x,y,z)=(0,0,0), so coords stay well-behaved IF they started
# well-behaved

# --------------------------------- setup --------------------------------

set narg_good = 2
set dset_in   = $1
set dset_out  = $2

set narg = ${#argv}
if ( ${narg} != ${narg_good} ) then
    echo "** ERROR: Should have ${narg_good} args input:"
    echo ""
    echo "       tcsh do_deoblique_keep_000.tcsh DSET_IN DSET_OUT"
    echo ""
    echo "   ... but only this many args have been used: ${narg}"
    exit 1

set avsp     = `3dinfo -av_space "${dset_in}"`
set tpref    = tmp_1234
set dset_tmp = ${tpref}${avsp}

# ------------------------------- the work --------------------------------

3dcopy   "${dset_in}"       ${tpref}              # yes, copy to BRIK/HEAD

3drefit  -oblique_recenter  ${dset_tmp}
3drefit  -deoblique         ${dset_tmp}

3dcopy   ${dset_tmp}        "${dset_out}"

# --------------------------------- finish -------------------------------

if ( $status ) then
    echo "** ERROR: failed to copy output dset:  ${dset_out}"
    exit 1

# cleanup
\rm  "${dset_tmp}".HEAD "${dset_tmp}".BRIK*

echo "++ Have deobliqued (whilst retaining coordinate origin)."
echo "   ${dset_out}"

exit 0