alignment in afni_proc.py during neurofeedback

Note: ptaylor split this message off from this thread:

… into this new one, because it starts a new/different topic (albeit related to alignment).


Thank you so much, we are running with the new prepp data and with and without -align_unifize_epi local .
I’ll update you when it’s done.

I have another question that is probably related.

I have made my own neuro-feedback engine (based on AFNI). And yes, I know AFNI has it’s own :D. But I’m trying to make this work.

I have run into one issue. I implemented your prepp-steps in this process as well which helps but I have one epi 2 epi alignment that does not work. I’ll try to be super breif:

Step1: Collect T1
Step2: Run localizer task: Goal is to find subject specific region to give feedback from
Step3: Run the prepp-steps on epi + aligment of epi and anat (default is that anat is moved to epi space, right):


afni_proc.py -subj_id $sub_id \
    -dsets EPI_do.nii \
    -copy_anat T1_do_zp.nii \
    -align_opts_aea -cost lpc+ZZ -giant_move \
    -blocks despike align volreg blur regress \
    -tcat_remove_first_trs 0 \
    -volreg_align_to MIN_OUTLIER \
    -regress_censor_motion 0.3 \
    -regress_censor_outliers 0.1 \
    -regress_apply_mot_types demean deriv \
	-regress_basis 'BLOCK(8,1)' \
    -regress_stim_times $stim/stimfile.1D \
    -regress_stim_labels localizer_task \
    -regress_local_times \
        -regress_opts_3dD \
	-jobs $cpu_num \
	-html_review_style none \
	-execute

Step4: In this localizer epi space we make the mask, (threshold the stats file, top 10% voxels) within a salience network mask that I warped to the anat.final file.
Looking at vr_min_outlier as underlay and the mask as overlay looks good! (attached)

Step5: We start the live run.
These EPIs are collected one by one. Let’s focus on the first TR that arrives into the system.
I want this EPI to overlap with the vr_minimum outlier map from the localizer (since there the mask matches the anatomy we want to give feedback from).
The arriving TR1.nii file is in it’s own native space (but close to vr_min_outlier since the subject is still in the scanner and hopefully don’t move A LOT).
On each arriving TR I would do:


cp $nii_dir/TR1.nii.gz .
3drefit -oblique_recenter TR1.nii.gz
3drefit -deoblique TR1.nii.gz
###
3dvolreg -zpad 1 -base vr_minimum_outlier+orig. \
          -1Dfile dfile_TR1 -prefix TR1.volreg \
          -cubic TR1.nii.gz

My idea was just to volume register to vr_minimum outlier but it seems like this does not actually move the EPI (TR1) to the space of the localizer (vr_min_outlier). But 3dvolreg does not seem to do it (attached).

So, how to I best (and fastest) move a single EPI TR image onto another (in space close) EPI (vr_min_outlier) from the previous scan?

I tried this:
@Align_Centers
-cm
-base vr_base_min_outlier+orig
-dset 11+orig

And 11_shft+orig (the output) does look much much better but I don’t think they are “aligned”.

Heeelp and thanks again!

vr_origspace_mask.png

Hi, Robin-

A couple of quick comments/questions:

A) You might want to add the following options to your AP command, to be explicit about the values used (there are defaults, but I prefer to state them):


-blur_size   SOMETHING
-anat_has_skull  YES_OR_NO

B) Are you sure you want this line in there, even though processing task-based data:


-regress_apply_mot_types demean deriv \

I am used to seeing that just in resting state processing, rather than when task-based events timing for stimuli is available. (Specifically, having the extra regressors for the derivatives of motion included.)

C) In your current code, I think you might actually specifically be better of with 3dcopy to a BRIK/HEAD file to start, rather than the shell’s cp. This is because of how the header information will propagate in preparation for refitting.

–pt

Hi!

A)
I’ll change


-blur_size   SOMETHING
-anat_has_skull  YES_OR_NO

To be explicit

B)
I’ll remove


-regress_apply_mot_types demean deriv \

C)
Yes, I have realized that is a good idea. I’ll change the first steps accordingly:


# Once the TR is registered
cd $afni_dir/all_TRs
name=TR$last_brik
mkdir $name
cd $name
#changing this
cp $nii_dir/${last_brik}.nii.gz .
#to
3dcopy $nii_dir/${last_brik}.nii.gz ${last_brik}
#and changing this
3drefit -oblique_recenter ${last_brik}.nii.gz
3drefit -deoblique ${last_brik}.nii.gz
#to this
3drefit -oblique_recenter ${last_brik}+orig.
3drefit -deoblique ${last_brik}+orig.

But that won’t help with my problem, or do you think it will?

Hi Robin,

So the EPI localizer datasets are all in original, vr_base_min_outlier space.

Is this volume oblique, and is it the same obliquity as with the subsequent EPI runs? I would expect so. And if so, I do not see why the subsequent data would have the obliquity altered or removed, or was the same thing done to the localizer EPI? I would think no obliquity adjustment would be needed for this, just leave it oblique.

Otherwise, what you are doing looks okay.

If 3dvolreg is not succeeding, the volumes are starting too far apart. If that is because of altering the obliquity of the later EPI, maybe omit that step. I would expect that there is no reason to alter the obliquity of any of the EPI data. Either way, such datasets should be handled identically.

If they are far apart because the subject might have moved a lot between the runs (or did they even leave the scanner?), then it might be good to add the -twopass option to the 3dvolreg command.

Note that an external volume (like the localizer vr_base_min_outlier) can be given to afni’s realtime plugin to be used for volume registration in real-time. Then any ROI averages other real-time afni output would be with respect to that registered data.

  • rick

Thanks Rick. How scared should I be of warnings in the viewer and from 3dvolreg like:


*+ WARNING:   If you are performing spatial transformations on an oblique dset,
  such as ./vr_base_min_outlier+orig.BRIK,
  or viewing/combining it with volumes of differing obliquity,
  you should consider running: 
     3dWarp -deoblique 
  on this and  other oblique datasets in the same session.

If we start with the salience mask that we are using (we threshold within this mask, on the localizer task). Took your advice and I don’t to any extra deobliqing:

LOCALIZER
T1 nii file in a T1 dir, epi nii data in an epi dir:

Nothing strange here


echo "8 24 40 56 72 88 104 120 136 152 168 184 200 216 232 248 264 280" >> stimfile.1D
sub_id=ref
T1_data=../../data/localizer/T1_nii/T1.nii
fmri_data=../../data/localizer/epi_nii/epi.nii
3dcopy $T1_data T1
3dcopy $fmri_data epi

I run the basic AP where we align T1 to epi


afni_proc.py -subj_id $sub_id \
    -dsets epi+orig \
    -copy_anat T1+orig \
    -anat_has_skull  yes \
    -align_opts_aea -cost lpc+ZZ -giant_move \
    -blocks despike align volreg blur regress \
    -tcat_remove_first_trs 0 \
    -blur_size 4.0 \
    -volreg_align_to MIN_OUTLIER \
    -regress_censor_motion 0.3 \
    -regress_censor_outliers 0.1 \
	-regress_basis 'BLOCK(8,1)' \
    -regress_stim_times stimfile.1D \
    -regress_stim_labels localizer_task \
    -regress_local_times \
        -regress_opts_3dD \
	-jobs $cpu_num \
	-execute

Looking at this, the pb03.volreg / vr_base_min_outlier+orig overlap very well with the anat_final.ref and but we get de-oblique varnings in viewer:
vr_base_min_outlier+orig overlap and anat_final.ref have a diff of 12.86 degrees. Is this a problem?

Now I want to transfer our MNI salience mask to this localizer space.

Just getting the masks


template=/usr/local/abin/MNI152_2009_template_SSW.nii.gz 
mask_MNI=/home/rtfMRI/rtfMRI_engine/scripts/afni/SN_MNI.nii
3dcopy $mask_MNI mask_mni
3dcopy $template MNI_template_in_mni_space

Skipping all de-obliqe steps here too. Just running:


3dcopy ref.results/anat_final.ref+orig anat_final.ref_warp_input
@auto_tlrc -base MNI_template_in_mni_space+tlrc -input anat_final.ref_warp_input+orig -no_ss -prefix rm.anat_final_mni

Now we have the warp-matrix of how to take the localizer anat to MNI. My idea was to use the inverse of this transformation to transfer the MNI mask to localizer space. I found some code on Andrews blog:


cat_matvec rm.anat_final_mni+tlrc.::WARP_DATA > warp.anat.Xat.1D

Then I apply these warps to the mask


3dAllineate -base anat_final.ref_warp_input+orig.                       \
          -input mask_mni+tlrc                        \
          -1Dmatrix_apply warp.anat.Xat.1D         \
          -mast_dxyz 3 -final NN -quiet                   \
          -prefix mask_original_space

This output:
mask_original_space+orig
overlaps well with the
vr_base_min_outlier+orig file (IN THE VIEWER)

But it does warn, in the viewer about de-obliqeness!


The data (pair vr_base_min_outlier/mask_orginal_space+orig )have an oblique angle difference of 12.86.. degrees. Conciser 3dwarp -deoblieqe

Exactly the same warning as after AP: vr_base_min_outlier vs anat_final.ref.

Before I procede, I must know that this process of moving the MNI space mask to my localizer (orig space) is correct.
Thanks!

Assuming the oblique warning above is fine (since it’s there, and the same, already for anat_final vs vr_min_outlier, I assume it’s fine)…

Then the goal is to get the live nii file to overlap well with the vr_base_min_outlier (or I guess anat_final is also fine).

Now I have done nothing to obliquess in any dataset.
I only do this:


3dcopy ../../data/nii_1/1.nii 1

Generating 1+orig.

If I only do:


3dvolreg -zpad 1 -base  ../localizer_results/ref.results/vr_base_min_outlier+orig. \
          -1Dfile dfile.1D -prefix 1.volreg \
          -cubic 1+orig

The 1.volreg+orig file is shifted compared to vr_min_outlier (attached image)

If I add -two-pass:


3dvolreg -zpad 1 -base  ../localizer_results/ref.results/vr_base_min_outlier+orig. -twopass \
          -1Dfile dfile.1D -prefix 1.volreg_twopass \
          -cubic 1+orig.

There is absolutely no difference. Values are identical.

I can make it better by first running:


@Align_Centers \
:
mkdir TR$i
cp ../../../data/live_DICOMS/$name TR$i/
dcm2niix TR$i/
cd TR$i
mv *.nii TR$i.nii
3dcopy TR$i.nii TR$i

@Align_Centers \
   -cm \
   -base /home/rtfMRI/rtfMRI_engine/final_eval/basic/localizer_results/ref.results/vr_base_min_outlier+orig.  \
   -dset TR$i+orig. \


3dvolreg -zpad 1 -base  /home/rtfMRI/rtfMRI_engine/final_eval/basic/localizer_results/ref.results/vr_base_min_outlier+orig. -twopass \
          -1Dfile dfile.1D -prefix TR$i.volreg \
          -cubic TR${i}_shft+orig.

mni_mask=/home/rtfMRI/rtfMRI_engine/final_eval/basic/localizer_results/mask_original_space+orig.
cd ..
3dmaskave -q -mask $mni_mask TR$i/TR$i.volreg+orig >> tc_ACC.1D

Then the overlap is pretty good: attached.

This signal looks good. But it takes longer to process it when adding @Align centers. I really should not need to do it.
But it is possible that the the live EPI’s are further away from the localizer EPI. Some time passes between them (FLAIR + resting state).

I think the issue for 3dvolreg is that the volumes have different obliquities. The volumes probably get registered well, but the output might not have the correct obliquity anymore.

For kicks, try this:

3dcalc -a …/localizer_results/ref.results/vr_base_min_outlier+orig -b 1.volreg_twopass
-expr b -prefix 2.vr.twopass.grid

So 2.vr would have the data from 1.volreg, but should have the grid from the localizer.
Does that overlap well with the localizer?

  • rick