How to find Region using coordinate?

I’ve performed a searchlight analysis with Python using machine learning techniques, and I’ve obtained the coordinates of specific voxels based on a threshold. Is there a way to obtain the labels of the corresponding brain regions for these coordinates?(e.g. Right Cerebral Cortex…)

array([[20, 12, 25],
       [20, 13, 21],
       [20, 13, 24],
       ...,
       [20, 66, 26],
       [20, 66, 29],
       [20, 67, 23]], dtype=int64)

First, I performed with GPT then GPT gave me the code, but not work.

from nilearn import datasets, image

# Harvard-Oxford Atlas
atlas = datasets.fetch_atlas_harvard_oxford('cort-maxprob-thr25-2mm')

# Create an empty list to store the region names for the coordinates
mapped_regions = []

# Load the Harvard-Oxford Atlas image
atlas_img = atlas.maps

# Define the reference image, which should have the same resolution as your bold data

# Resample the atlas image to the resolution of the reference image
atlas_img_resampled = image.resample_to_img(atlas_img, bold)

# Iterate through the coordinates
for coord in above_threshold_coords:
    x, y, z = coord  # Coordinates directly from above_threshold_coords
    
    # Extract the region value from the resampled atlas image
    region_value = atlas_img_resampled.get_fdata()[x, y, z]
    
    # Get the region name from the atlas labels
    region_name = atlas.labels[int(region_value)]
    
    # Append the region name to the list
    mapped_regions.append(region_name)

# The mapped_regions list now contains the names of brain regions corresponding to the coordinates.
print(mapped_regions)


IndexError Traceback (most recent call last)
Cell In[78], line 25
22 region_value = atlas_img_resampled.get_fdata()[x, y, z]
24 # Get the region name from the atlas labels
—> 25 region_name = atlas.labels[int(region_value)]
27 # Append the region name to the list
28 mapped_regions.append(region_name)

IndexError: list index out of range

Hi @novicedata and welcome to neurostars!

When you get that error, what is the value of region_value, and what is the size of atlas.labels.

Best,
Steven

I guess It is why the code is not working… the region_value is something wrong.

print(region_value)
>> 52.0

and the atlas.labels is in below

['Background',
 'Frontal Pole',
 'Insular Cortex',
 'Superior Frontal Gyrus',
 'Middle Frontal Gyrus',
 'Inferior Frontal Gyrus, pars triangularis',
 'Inferior Frontal Gyrus, pars opercularis',
 'Precentral Gyrus',
 'Temporal Pole',
 'Superior Temporal Gyrus, anterior division',
 'Superior Temporal Gyrus, posterior division',
 'Middle Temporal Gyrus, anterior division',
 'Middle Temporal Gyrus, posterior division',
 'Middle Temporal Gyrus, temporooccipital part',
 'Inferior Temporal Gyrus, anterior division',
 'Inferior Temporal Gyrus, posterior division',
 'Inferior Temporal Gyrus, temporooccipital part',
 'Postcentral Gyrus',
 'Superior Parietal Lobule',
 'Supramarginal Gyrus, anterior division',
 'Supramarginal Gyrus, posterior division',
 'Angular Gyrus',
 'Lateral Occipital Cortex, superior division',
 'Lateral Occipital Cortex, inferior division',
 'Intracalcarine Cortex',
 'Frontal Medial Cortex',
 'Juxtapositional Lobule Cortex (formerly Supplementary Motor Cortex)',
 'Subcallosal Cortex',
 'Paracingulate Gyrus',
 'Cingulate Gyrus, anterior division',
 'Cingulate Gyrus, posterior division',
 'Precuneous Cortex',
 'Cuneal Cortex',
 'Frontal Orbital Cortex',
 'Parahippocampal Gyrus, anterior division',
 'Parahippocampal Gyrus, posterior division',
 'Lingual Gyrus',
 'Temporal Fusiform Cortex, anterior division',
 'Temporal Fusiform Cortex, posterior division',
 'Temporal Occipital Fusiform Cortex',
 'Occipital Fusiform Gyrus',
 'Frontal Operculum Cortex',
 'Central Opercular Cortex',
 'Parietal Operculum Cortex',
 'Planum Polare',
 "Heschl's Gyrus (includes H1 and H2)",
 'Planum Temporale',
 'Supracalcarine Cortex',
 'Occipital Pole']

It could just be that the values of the atlas aren’t valued nicely from 0 → n (where n is the number of regions in the atlas). If you were to take np.unique of the data in the atlas, is it a nice array from 0 → n or is it something else?

Adding on here, whereami in AFNI provides exactly this functionality.

whereami [-atlas ...] [-LPI] x y z

From python, you would use a shell subprocess to run the command and capture the output. By default, whereami searches across multiple atlases and a radius around the coordinate. You can select individual atlases and set a radius with the -max_search_radius option or the AFNI environment variable AFNI_WHEREAMI_MAX_SEARCH_RAD. A list of coordinates from a file input can be provided instead with -coord_file XYZfile.1D.

When using the np.unique to the data in the atlas, the result is not in the format of 0 to n, but it displays the names of labels instead.

array([{'filename': 'C:\\Users\\atlsw/nilearn_data\\fsl\\data\\atlases\\HarvardOxford\\HarvardOxford-cort-maxprob-thr25-2mm.nii.gz', 'maps': <nibabel.nifti1.Nifti1Image object at 0x0000021C60079D90>, 'labels': ['Background', 'Frontal Pole', 'Insular Cortex', 'Superior Frontal Gyrus', 'Middle Frontal Gyrus', 'Inferior Frontal Gyrus, pars triangularis', 'Inferior Frontal Gyrus, pars opercularis', 'Precentral Gyrus', 'Temporal Pole', 'Superior Temporal Gyrus, anterior division', 'Superior Temporal Gyrus, posterior division', 'Middle Temporal Gyrus, anterior division', 'Middle Temporal Gyrus, posterior division', 'Middle Temporal Gyrus, temporooccipital part', 'Inferior Temporal Gyrus, anterior division', 'Inferior Temporal Gyrus, posterior division', 'Inferior Temporal Gyrus, temporooccipital part', 'Postcentral Gyrus', 'Superior Parietal Lobule', 'Supramarginal Gyrus, anterior division', 'Supramarginal Gyrus, posterior division', 'Angular Gyrus', 'Lateral Occipital Cortex, superior division', 'Lateral Occipital Cortex, inferior division', 'Intracalcarine Cortex', 'Frontal Medial Cortex', 'Juxtapositional Lobule Cortex (formerly Supplementary Motor Cortex)', 'Subcallosal Cortex', 'Paracingulate Gyrus', 'Cingulate Gyrus, anterior division', 'Cingulate Gyrus, posterior division', 'Precuneous Cortex', 'Cuneal Cortex', 'Frontal Orbital Cortex', 'Parahippocampal Gyrus, anterior division', 'Parahippocampal Gyrus, posterior division', 'Lingual Gyrus', 'Temporal Fusiform Cortex, anterior division', 'Temporal Fusiform Cortex, posterior division', 'Temporal Occipital Fusiform Cortex', 'Occipital Fusiform Gyrus', 'Frontal Operculum Cortex', 'Central Opercular Cortex', 'Parietal Operculum Cortex', 'Planum Polare', "Heschl's Gyrus (includes H1 and H2)", 'Planum Temporale', 'Supracalcarine Cortex', 'Occipital Pole']}],
      dtype=object)

I don’t know about the AFNI… I just used to Python. Can AFNI used in Python?

Hi @novicedata,

I was referring to the values of the atlas (that is, what you got from the get_fdata()), not the labels.

AFNI is primarily a command line interface tool or GUI.

Best,
Steven

OK. I understand. I tried np.unique on the data obtained with .get_fdata() .

np.unique(atlas_img_resampled.get_fdata())

array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12.,
13., 14., 15., 16., 17., 18., 19., 20., 21., 22., 23., 24., 25.,
26., 27., 28., 29., 30., 31., 32., 33., 34., 35., 36., 37., 38.,
39., 40., 41., 42., 43., 44., 45., 46., 47., 48., 49., 50., 51.,
52., 53., 54., 55., 56., 57., 58., 59., 60., 61.])

Hi @novicedata,

I think the problem is that you are using continuous interpolation instead of nearest neighbor interpolation (which is what is supposed to be used for mask/atlas interpolation). Indeed, the original atlas image has 48 unique values, matching the atlas labels, but your interpolated image does not.

Please add interpolation='nearest' to your resample_to_img command.

Best,
Steven

1 Like

AFNI has its own python library with many of its pipeline tools (afni_proc.py, @animal_warper, align_epi_anat.py,…) written in python, so there are ways to use AFNI-standard functions. Alternatively, you can use various standard python methods for calling system commands. Each of these have options for capturing stdout text or for redirecting to a text file.

>>> from afnipy.afni_base import *
>>> com = shell_com( "whereami -LPI 10 20 5 > testwami2.txt","")
>>> com.run()
0
>>>
% cat testwami2.txt

Python functions like os.system or subprocess.run can be used like this:

>>> import subprocess
>>> returned_output = subprocess.run("whereami -LPI 10 20 5", shell=True, stdout=subprocess.PIPE)
>>> returned_output
CompletedProcess(args='whereami -LPI 10 20 5', returncode=0, stdout=b'++ Input coordinates orientation set by user to LPI\n+++++++ nearby Atlas structures +++++++\n\nOriginal input data coordinates in TLRC space\n\nFocus point (LPI)=\n     10 mm [R],   20 mm [A],    5 mm [S] {TLRC}\n     10 mm [R],   20 mm [A],    7 mm [S] {MNI}\n\nAtlas FS.afni.MNI2009c_asym: Freesurfer MNI2009c DK parcellation\n   Focus point:  Right-Caudate\n\n ... * Please use results with caution! ********\n******** Brain anatomy is quite variable! ********\n******** The database may contain errors! ********\n\n')

See this thread for a variety of pythonic methods to call system commands:

1 Like

I apologize for the delay. Your response was helpful. Thank you.