two entire runs of opposite polarity?

AFNI version very recent

hi gurus-

I have a dataset where an entire epi run is collected AP (forward blip) and a second run is collected PA (reverse blip). There is no separate short run that represents a "reverse" dataset; the second entire run is the reverse. Is it possible to use afni_proc to process such data? I love that afni_proc concatenates everything into a single resampling and would love to stick with it (many other reasons too!). However, if I compare resulting warps via the AP data's "pb??volreg" with anat_final it looks great but "run 2" (the PA run) is even worse than its original state and the two certainly don't align.

It seems that I can't specify the forward and reverse blips without also having the required "-dsets" option, but specifying that with a wild card seems to make afni_proc 'think' those are 2 runs of the same polarity. Then in the proc.* those 2 runs are treated identically within a foreach loop, when in reality run2 (PA) needs to have that middle-ground warp estimation applied differently, right? Does this make sense? I can send screenshots and afni_proc commands etc if you need. Thanks!

-Sam

Did you want to use the second run for analysis? If not, then just specify the reverse blip dataset with subbrick selectors for the first few volumes, maybe "dset.nii.gz[0..4]".

Otherwise, you can try analyzing these runs separately - again with just the first few volumes from the alternate run as the reverse blip dset.

If alignment is not working, then there's probably something odd about the datasets, and we would have to investigate further. If alignment works, then you could move all the datasets with a separate tool like UnwarpEPI.py to create new input datasets for afni_proc.py and skip all the alignments.

Thanks for the quick thoughts Daniel!

Yes i have to use the second run for analysis.

Analyzing these runs separately feels suboptimal because i'd have double the *.results folders and QC files to look through (plus, QC-wise it's informative to have concatenated visualizations to comprehend things overall).

This is resting state data which makes this problem a little simpler (just concatenate the errts* at the end before 2nd level stuff?) but i'd have probably have further questions in the future about how to combine such data if it's task-based. The beauty of afni_proc is the way it puts things together :-)

I would say the alignment is working, it's just that the PA dataset gets warped in the wrong direction. So as it is right now i cannot trust any outputs at and past the volreg stages in the two-run sense.

Sigh, so i guess it's not possible with afni_proc? Hasn't this situation come up before?

-Sam

Doing them separately lets you check if alignment works. afni_proc.py doesn't have options for inverting warps on a run-selective basis, so you can either use it separately or modify the generated proc script. That's not something we can typically recommend, but it is an option here. You would have to find the 3dNwarpApply steps. The third choice is to give afni_proc.py the blip distortion corrected datasets and skip it inside afni_proc.py.

i was able to split the foreach loop in the 'blip' block into 2 parts that specified each run sequentially, adding to the PA data's 3dNwarpApply a simple "-iwarp" with blip_warp_For_WARP+orig.. It looks super terrific now overlaid on T1_al_junk+orig. :-) However, I'm much more skittish about splitting the bigger foreach in the 'volreg' block where all warps and transforms converge. I agree with you that these proc file hacks can be risky. So I guess i'll just deal with the double resampling and use unWarpEPI.py to unwarp the data prior to afni_proccing. Thanks again for the feedback.

You wouldn't use iwarp from 3dNwarpApply because that would warp the entire set of warps, not just the blippy part. You could use an INV(thatwarp) inside the -nwarp field, or 3dNwarpCat to invert just that warp, or use an inverted warp straight out of 3dQwarp.
You should get similar results by splitting this up, but you will get some smoothing from interpolation. Still, you should compare and contrast those two basic approaches.

1 Like

for anyone listening in, i went with a super simple approach:

set subj = MOTSF036

afni_proc.py                                                                        \
     -subj_id                   blip_AP_${subj}_ap                                  \
     -blocks                    blip                                                \
     -dsets                     func/sub-${subj}_task-rest_dir-AP_bold.nii.gz    \
     -blip_forward_dset         func/sub-${subj}_task-rest_dir-AP_bold.nii.gz    \
     -blip_reverse_dset         func/sub-${subj}_task-rest_dir-PA_bold.nii.gz'[0..4]'   \
     -blip_opts_qw              -minpatch 11                                        \
     -html_review_style         none

afni_proc.py                                                                        \
     -subj_id                   blip_PA_${subj}_pa                                  \
     -blocks                    blip                                                \
     -dsets                     func/sub-${subj}_task-rest_dir-PA_bold.nii.gz    \
     -blip_forward_dset         func/sub-${subj}_task-rest_dir-PA_bold.nii.gz    \
     -blip_reverse_dset         func/sub-${subj}_task-rest_dir-AP_bold.nii.gz'[0..4]'   \
     -blip_opts_qw              -minpatch 11                                        \
     -html_review_style         none

#change interpolation to least blurry (wish list: an AP 3dNwarpApply _opts)
sed -i '.BAK' 's/quintic/wsinc5/g' proc.blip_AP_${subj}_ap
sed -i '.BAK' 's/quintic/wsinc5/g' proc.blip_PA_${subj}_pa
rm *.BAK

#execute 'em
tcsh -xef proc.blip_AP_${subj}_ap |& tee output.proc.blip_AP_${subj}_ap
tcsh -xef proc.blip_PA_${subj}_pa |& tee output.proc.blip_PA_${subj}_pa

then: cleaned up some extra files and used those pb01* outputs as inputs into the real AP which didn't include any blip parts