creat mask in afni

Hello,
I want to create the state transition diagram. I will need the original fmri file that was used to calculate melodic. for each component, I should create a spatial mask by thresholding the component map with these indices: dmn_indices = [33, 30,62, 36, 19, 42] . I should use z-score thresholding (z>1.5) on all voxels. once I have the mask, use it to isolate the time series from the original fmri that is unique to each component mask and average the time series across all voxels in the mask.
the original fmri data are subs=['pb06.sub-04710.r01.scale.nii', ' pb06.sub-12599.r01.scale.nii ', ' pb06.sub-16053.r01.scale.nii', ' pb06.sub-19284.r01.scale.nii' , ' pb06.sub-19979.r01.scale.nii ', ' pb06.sub-20094.r01.scale.nii'].

Hi-

OK, that sounds doable. Let's call the original FMRI file "DSET_FMRI" and the file output by melodic "DSET_MEL" (whose voxels contain Z-score values, which can be either positive or negative). Both DSET_FMRI and DSET_MEL are what we could call 4D (four dimensional) datasets, in that they each have 3 dimensions of space and a time axis, as well. In AFNI, you can use sub-brick selectors to select out volumes along the time axis with zero-based indexing.

Sub-brick selection
You can add a sub-brick selection list after the end of the dataset name. This allows only a subset of the sub-bricks to be read in (by default, all of a dataset's sub-bricks are input). A sub-brick selection list looks like one of the following forms (and works the same if you have a NIFTI dataset like fred.nii or fred.nii.gz):

fred+orig"[5]"                       ==> use only sub-brick #5
fred+orig"[5,9,17]"                  ==> use #5, #9, and #17
fred+orig"[5..8]"     or "[5-8]"     ==> use #5, #6, #7, and #8
fred+orig"[5..13(2)]" or "[5-13(2)]" ==> use #5, #7, #9, #11, and #13

Note that in general you will want to use the double quotes, to guard against the shell interpreting any of the square brackets as special shell characters, as above.

OK, so now, let's say you want to take the [33]rd volume of DSET_MEL and make a mask where |z|>1.5. This can be accomplished with:

3dcalc                                     \
    -a       DSET_MEL"[33]"                \
    -expr    "ispositive(abs(a)-1.5)"      \
    -prefix  mask_33.nii.gz

The output dataset mask_33.nii.gz has values of 1 where the dset voxels were magnitude>1.5, and 0 elsewhere.

To use that mask to calculate the average time series from DSET_FMRI within it, you can use 3dmaskave to dump out the values to the terminal, and redirect them to a text file, called "fmri_ave_33.txt":

3dmaskave -quiet -mask mask_33.nii.gz DSET_FMRI > fmri_ave_33.txt

You can loop over this set of two commands for each sub-brick value you want to select out of DSET_MEL, and for each time series. In tcsh script syntax, this could look like:

#!/bin/tcsh

# list of all FMRI dsetes
set all_fmri = ( pb06.sub-04710.r01.scale.nii pb06.sub-12599.r01.scale.nii  \
                 pb06.sub-16053.r01.scale.nii pb06.sub-19284.r01.scale.nii \
                 pb06.sub-19979.r01.scale.nii pb06.sub-20094.r01.scale.nii  )

# list of all sub-brick selectors *must be zero-based*
set all_ss = ( 33 30 62 36 19 42 )

# need to know name of melodic dset
set dset_mel = something.nii.gz

# loop over all sub-brick indices
foreach ss ( ${all_ss} ) 
    # make mask
    3dcalc                                     \
        -a       ${dset_mel}"[${ss}]"          \
        -expr    "ispositive(abs(a)-1.5)"      \
        -prefix  mask_${ss}.nii.gz

    # loop over all FMRI dsets
    foreach dset_fmri ( ${all_fmri} )
        # get prefix of dset_fmri for output naming
        set name_fmri = `3dinfo -prefix_noext "${dset_fmri}"`

        # apply mask
        3dmaskave -quiet                        \
            -mask mask_${ss}.nii.gz             \
            ${dset_fmri}                        \
            > "fmri_ave_${name_fmri}_${ss}.txt"
    end
end

--pt

Hello Paul,

I tried to run the code several times but gave me the error. My Ubuntu terminal is bash I think you write for tcsh. I changed the code according to tcsh but it gave an error again. Can you change it for bash?

Best regards,

Masy

name of melodic is dset_mels=("melodic4710_IC.nii.gz" "melodic12599_IC.nii.gz"
"melodic16053_IC.nii.gz" "melodic19284_IC.nii.gz"
"melodic19979_IC.nii.gz" "melodic20094_IC.nii.gz")
and it is the code for bash but give the errors:

#!/bin/bash

# List of all FMRI datasets
all_fmri=("pb06.sub-04710.r01.scale.nii" "pb06.sub-12599.r01.scale.nii" \
          "pb06.sub-16053.r01.scale.nii" "pb06.sub-19284.r01.scale.nii" \
          "pb06.sub-19979.r01.scale.nii" "pb06.sub-20094.r01.scale.nii")

# List of all sub-brick selectors (must be zero-based)
all_ss=(33 30 62 36 19 42)

# Need to know the name of melodic dataset
dset_mels=("melodic4710_IC.nii.gz" "melodic12599_IC.nii.gz" \
          "melodic16053_IC.nii.gz" "melodic19284_IC.nii.gz" \
          "melodic19979_IC.nii.gz" "melodic20094_IC.nii.gz")

# Loop over all sub-brick indices
for ((i=0; i<${#all_ss[@]}; i++)); do
    dset_mel=${dset_mels[i]}
    ss=${all_ss[i]}
    # Make mask
    ~/abin/3dcalc -a "${dset_mel[$ss]}" -expr "ispositive(abs(a)-1.5)" -prefix "mask_${ss}.nii.gz"

    # Loop over all FMRI datasets
    for dset_fmri in "${all_fmri[@]}"; do
        # Get prefix of dset_fmri for output naming
        name_fmri=$(~/abin/3dinfo -prefix_noext "${dset_fmri}")

        # Apply mask
        ~/abin/3dmaskave -quiet -mask "mask_${ss}.nii.gz" "${dset_fmri}" > "fmri_ave_${name_fmri}_${ss}.txt"
    done
done

and it is another code:

#!/bin/bash

# List of all FMRI datasets
all_fmri=("pb06.sub-04710.r01.scale.nii" "pb06.sub-12599.r01.scale.nii" \
          "pb06.sub-16053.r01.scale.nii" "pb06.sub-19284.r01.scale.nii" \
          "pb06.sub-19979.r01.scale.nii" "pb06.sub-20094.r01.scale.nii")

# List of all sub-brick selectors (must be zero-based)
all_ss=(33 30 62 36 19 42)

# Need to know the name of melodic dataset
dset_mel=("melodic4710_IC.nii.gz" "melodic12599_IC.nii.gz" \
          "melodic16053_IC.nii.gz" "melodic19284_IC.nii.gz" \
          "melodic19979_IC.nii.gz" "melodic20094_IC.nii.gz")

# Loop over all sub-brick indices
for ss in "${all_ss[@]}"; do
    # Make mask
    3dcalc -a "${dset_mel[$ss]}" -expr "ispositive(abs(a)-1.5)" -prefix "mask_${ss}.nii.gz"

    # Loop over all FMRI datasets
    for dset_fmri in "${all_fmri[@]}"; do
        # Get prefix of dset_fmri for output naming
        name_fmri=$(3dinfo -prefix_noext "${dset_fmri}")

        # Apply mask
        3dmaskave -quiet -mask "mask_${ss}.nii.gz" "${dset_fmri}" > "fmri_ave_${name_fmri}_${ss}.txt"
    done
done

Hi, Masy-

My bash scripting is not very good---bash scripts are very sensitive to spacing, and I guess I'm just not a sensitive enough person to understand everywhere it is necessary. It is possible that you need to put spaces between the parentheses and the quotes in your arrays, like changing:

all_fmri=("pb06.sub-04710.r01.scale.nii"

to:

all_fmri=( "pb06.sub-04710.r01.scale.nii"

and likewise at the closing parenthesis.

Note that you can run a tcsh script from a bash command line without any trouble. You can just write:

tcsh SCRIPT.tcsh

... and it will execute as a tcsh script, regardless of your terminal shell type.

So, you could adapt the tcsh script that I had initially posted, just putting in your desired file names. I had tested that script on my computer, and it appeared to work, so that might be the simplest thing if translating it to bash is causing difficulties.

--pt