which ROI belongs to which network

Hi everybody,

I have a question: I'm using the Craddock atlas with 748 ROIs and I would like to have the center of mass of each of this ROI associated to one of the network of the Yeo 7-network atlas.

So far I used this command to generate the list of coordinates
3dCM -all_rois dset Craddock748.nii > Craddock748_Coordinates.1D

and I was hoping I could use whereami and feed the coordinates and use the Yeo-7-network atlas; but as it does not exist in the list of atlas; do you know how I could do that?

Thank you very much in advance

PS, is there a way to get the coordinates in LPI format from the 3dCM command?

Thanks

The Schaefer-Yeo atlases from our site already come with a CustomAtlases.niml file that can be used to define atlas names and files. You should be able to set "AFNI_SUPP_ATLAS_DIR = pathofatlases/afni_sy_atlas" where the "pathofatlases" is where the atlases are installed on your system and the location of that CustomAtlases.niml file.

RAI and LPI only differ by the sign in the x and y. whereami takes RAI as input by default, but the -lpi option changes the input order to LPI. If you want to change the order, you can do that with this short script that works on list of coordinates in RAI order :

cat testRAI.1D
1 2 3
4 5 6
-5 -7 -10
1deval -a testRAI.1D'[0]' -expr '-a' > testLPIx.1D
1deval -a testRAI.1D'[1]' -expr '-a' > testLPIy.1D
1dcat testLPIx.1D testLPIy.1D testRAI.1D'[2]' > testLPI.1D
cat testLPI.1D
-1 -2 3
-4 -5 6
5 7 -10

Also, note that 3dCM finds the center of mass for each region. That will probably be okay for these regions, but for some shapes, the center of mass may actually lie outside the region. Consider the -Icent option for 3dCM to guarantee an internal center - a voxel center within the region that is closest to the center of mass. This poster on centers provides some alternatives:
https://afni.nimh.nih.gov/pub/dist/HBM2020/GlenEtal_FindingYourCenter_OHBM2020.pdf

Oh nice, thank you for the DICOM -> LPI conversion !
and the advicw wiht the -lcent that will definitely help

However I don't think I have any CustomAtlases.niml file, I just downloaded the 7 network atlas and only have a .nii file with it

The various atlases and the CustomAtlases.niml file can be found here:

https://afni.nimh.nih.gov/pub/dist/atlases/SchaeferYeo/afni_sydist_atlas_v1.0.tgz

if it's okay i'd like to jump on this thread whose title totally matches my question, but the above moved into RAI/LPI considerations.

@dglen i have your version of the SchaeferYeo atlas downloaded (and have reviewed the OHBM poster) and am actually just trying to combine regions back into the 7 or 17 basic Yeo networks, but with the improved MNI152_2009 alignment, modal smoothing etc

to do so would i simply, for example:

3dinfo -labeltable Schaefer_7N_200.nii.gz | grep Default > dmn_regions.txt

and manually edit that output to contain the integer column and with added commas then place that into a 3dcalc command:

3dcalc -a Schaefer_7N_200.nii.gz -prefix dmn.nii.gz -expr 'step(a * amongst(a, 10, 11, 12, etc etc))'

so my just-curious question is: is there a better afni way to do it?

thanks!

-Sam

You could make the list a range selector list instead of the 3dcalc amongst expression as in atlasdset'<5,6,25,21,200>'. That will extract just those values from the atlas.

You don't have to manually edit the list to change the values to be separated by columns instead of carriage return/line feeds. There are multiple Unix commands that can do this "sed, awk, tr", but you can also do it with an AFNI command:

 1d_tool.py -infile test.1D  -write stdout -write_sep \, -transpose
4,8,6

This takes the column inputs and transposes those into rows with comma separation.

ah you're right, could be done many other ways. if i keep my first line the 1d_tool.py command doesn't work, but this gets me closer:

cat dmn_regions.txt | cut -d '"' -f 2 | sort -V

and then i have a little vim macro to add commas and transpose to a single line.
much better, thanks!

Hi, Sam-

To do that all in one command (no need for vim!!!), broken into separate lines, could be

3dinfo -labeltable Schaefer_7N_200.nii.gz \
    | grep Default \
    | tr '"' ' ' \
    | awk '{print $1}' \
    | sort -V \
    | tr '\n' ',' \
    | sed 's/.$//'

.. where, line by line:

  • dump label table
  • get each line that has "Default" as a string
  • remove double quotes
  • get only the first column
  • sort numerically (NB: I didn't know about the -V option before you used it above, thanks for that!)
  • replace newlines with commas (so, convert column to row, while putting in desired syntax)
  • remove last dangling comma.

That could be saved to a variable and put into 3dcalc:

set my_sel = `3dinfo -labeltable Schaefer_7N_200.nii.gz \
    | grep Default \
    | tr '"' ' ' \
    | awk '{print $1}' \
    | sort -V \
    | tr '\n' ',' \
    | sed 's/.$//'`

3dcalc -a DSET"<${my_sel}>" -expr 'a' -prefix DSET_Default.nii.gz

--pt

... and, as an update, you can convert the list to a condensed (or "encoded") one, like this:

afni_python_wrapper.py  -listfunc -float -print encode_1D_ints \
    `3dinfo -labeltable Schaefer_7N_200.nii.gz \
      | grep Default \
      | tr '"' ' ' \
      | sort -V \
      | awk '{print $1}' \
      | tr '\n' ' '`

... which in this case outputs:

74..100,182..200

You could save that to a variable and use that, which might need more steps:

#!/bin/tcsh

set my_sel = `3dinfo -labeltable Schaefer_7N_200.nii.gz \
      | grep Default \
      | tr '"' ' ' \
      | sort -V \
      | awk '{print $1}' \
      | tr '\n' ' '`
set my_sel_enc = `afni_python_wrapper.py  -listfunc -float -print encode_1D_ints ${my_sel}`

# use
3dcalc -a DSET"<${my_sel_enc}>" -expr 'a' -prefix DSET_Default.nii.gz

Should be same result, but condensed/encoded thing might be nicer.

--pt

I didn't know about afni_python_wrapper.py way. Interesting.

For the sorting, sort -n seems good to sort the integer values of the indices, rather than the -V option used for version numbering. In any case, that's just a nicety for us humans.

Here's another way (at this point, just for fun) to use the 1d_tool.py to do some of the work with only one other unix command. The trick here is to use the quotes as the delimiter and get the second field for the index instead of the first.

3dinfo -labeltable Schaefer_7N_200.nii.gz | grep Default| \
   awk -F\" '{print $2}'| \
   1d_tool.py -infile stdin -write stdout -write_sep \, -transpose
76,97,187,77,98,188,78,99,189,79,190,80,191,81,192,82,193,83,194,84,195,85,196,86,197,87,198,88,199,89,200,90,91,92,182,93,183,94,100,184,74,95,185,75,96,186

And a couple other possibly useful variations on getting indices from atlases (leaving out the comma conversions). The atlas_points_list for this atlas is already sorted, so the order should be right.

3dinfo -atlas_points Schaefer_7N_200.nii.gz| \
   grep -A 1 Default|grep VAL|awk -F\" '{print $2}'
whereami -show_atlas_code -atlas Schaefer_Yeo_7N_200 |  \
   grep Default|awk -F\: '{print $3}'

this unix party thread has answered my question and then some! thanks so much guys!!! i agree now sort -n is better. i'll use one of these solutions for the fastest possible network extraction the world has ever seen! :-) i'm sure the thread will be useful to others too.

2 Likes