Notch filter using AFNI

I am interested in implementing a notch filter in AFNI for resting state fMRI data. The documentation for 3dFourier suggests that you can implement a notch filter by combining the lowpass and highpass options (although an example of doing this correctly is not provided). Therefore, I attempted a notch filter as follows (I’m using AFNI_19.1.04 on CentOS 7).

3dFourier -prefix ${subj}_task-${task}.fourier.resid
-retrend -lowpass ${notch_lowpass_hz} -highpass ${notch_highpass_hz} ${subj}_task-${task}.detrend.resid+tlrc

where:
notch_lowpass_hz = 0.06 ## Hz
notch_highpass_hz = 0.14 ## Hz

The resulting call yields a warning:

++ 3dFourier: AFNI version=AFNI_19.1.04 (Apr 21 2019) [64-bit]
** WARNING: lowpass=0.060000 is <= than highpass=0.140000
** -------: results from 3dFourier are suspect!

This leads me to believe that my assumptions about how to implement the notch in AFNI are incorrect. The notch should pass all frequencies below the lowpass and above the highpass (i.e., a bandstop filter eliminating frequencies on the range lowpass-hipass), but the warning suggests that the logical way of combining the lowpass and highpass flags is incorrect. The warning suggests that 3dFourier can only execute a bandpass filter (where lowpass would indeed be higher than the highpass).

Any ideas?

Hi-

Are you wanting to implement this as part of a full processing pipeline? If you are using afni_proc.py, you can do this with “-regress_bandpass …”, providing several pairs of bandpass regions. That would also include your bandpassing as a consistent part of the processing—within the regression step. Regression and bandpassing should not be done separately.

–pt

Yes, this is part of an implementation of a pipeline to complete preprocessing of the (minimally preprocessed) HCP dataset that would handle motion, CompCor, GSR. Band-stop is part of this. I understand the suggestion: will use multiple bandpass ranges to implement bandstop. Makes sense. Working on afni_proc script to generate desired pipeline. Thank you.

I’ve been experimeting with afni_proc.py to create a notch filter. I haven’t yet been successful. I’m using a simple afni_proc call to examine the generated scripts. The following call generates a processing script that seems reasonable (using bandpass filtering).

afni_proc.py
-dsets ./*.nii.gz
-regress_motion_per_run
-regress_censor_motion 0.2
-regress_censor_outliers 0.05
-regress_bandpass 0.01 0.1

When I try to modify this call to implement notch filtering, afni_proc either will not generate a script or ignores one of the requested bandpass ranges

Example 1 (explicitly supply multiple bandpass ranges)

afni_proc.py
-dsets ./*.nii.gz
-regress_motion_per_run
-regress_censor_motion 0.2
-regress_censor_outliers 0.05
-regress_bandpass 0.01 0.06
-regress_bandpass 0.14 0.69

Produces the following bandpass regressor call (which ignores the second range):

create bandpass regressors (instead of using 3dBandpass, say)

1dBport -nodata 1200 0.72 -band 0.01 0.1 -invert -nozero > bandpass_rall.1D

Example 2: (supply multiple ranges to a single call regress_bandpass argument)

afni_proc.py
-dsets ./*.nii.gz
-regress_motion_per_run
-regress_censor_motion 0.2
-regress_censor_outliers 0.05
-regress_bandpass 0.01 0.06 0.14 0.69

Produces a failure

usr/local/AFNI/lib_afni1D.py:1284: SyntaxWarning: ‘str’ object is not callable; perhaps you missed a comma?
print(‘** uncensor from vec: nt = %d, but nocen len = %d’
/usr/local/AFNI/lib_vars_object.py:244: SyntaxWarning: ‘str’ object is not callable; perhaps you missed a comma?
print(‘** SVWD %s.%s, cannot convert value %s to %s’
** error: unknown trailing arguments : [‘0.14’, ‘0.69’]

** failed command (get_user_opts):

afni_proc.py -dsets ./sub-100206_task-restRL_run-1_bold.nii.gz
-regress_motion_per_run -regress_censor_motion 0.2
-regress_censor_outliers 0.05 -regress_bandpass 0.01 0.1 0.14 0.69

What is the syntax for supplying multiple bandpass ranges within afni_proc? I’m not finding documentation or examples of how to implement this (in the end I’d like to notch filter 0.06-0.14). Thank you in advance. Best.

What version of AFNI do you have (-> output of “afni -ver”)? Using:


-regress_bandpass 0.01 0.1 0.14 0.69    \

in my afni_proc.py command worked fine.

Question: do you have very low-TR data?
For a given TR (in units of s), the Nyquist frequency (=maximum freq in Fourier decomposition band around 0) will be: 1/(2TR) Hz.
So, for TR = 2s, the Nyquist freq = 1/(2
2) = 0.25 Hz.

For data to have freqencies up to 0.7 Hz, such as your case above, then that implies you have data with TR > 1/(2*0.7) = 10/14 ~ 0.7 s. That is certainly possible nowadays, I was just wondering.

–pt

AFNI version
Precompiled binary linux_centos_7_64: Apr 21 2019 (Version AFNI_19.1.04 ‘Caligula’)

This is HCP resting state data, so 0.5/0.72s = .69.

Okeydoke. I think you do need to update that AFNI—it is quite old, anyways, so you will get a lot more functionality (like the muuuuch more full APQC HTML doc made):


@update.afni.binaries -d

(That particular change went in on April 25, 2019, interestingly.)

–pt

Updated to latest version of AFNI fixed the problem! Thank you. Best