[go: up one dir, main page]

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lateralized parcellation #4473

Open
whsu2s opened this issue Jun 27, 2024 · 9 comments
Open

Lateralized parcellation #4473

whsu2s opened this issue Jun 27, 2024 · 9 comments
Labels
Documentation for documentation related questions or requests

Comments

@whsu2s
Copy link
whsu2s commented Jun 27, 2024

Hi, I have some questions about the Yeo parcellation. It may be related to #1602, as I've been trying to plot the brain connectivity using the Yeo atlas.

When calculating the coordinates of ROIs using "nilearn.plotting.find_parcellation_cut_coords", we need to specify "label_hemisphere." I understand that it makes sense to analyze the left and right hemisphere separately, but it seems the BOLD signals are extracted from both hemispheres when using the "nilearn.maskers.NiftiLabelsMasker", as some ROIs are on both sides and the extracted signals are the average within each ROI. Did I understand correctly? If yes, then the calculated connectivity is not accurate. If no, then are there ways to choose the side of signals to extract, or to consider both hemispheres?

@Remi-Gau
Copy link
Collaborator

Can you provide a code snippet (preferably one that only uses nilearn data) to show us what you mean?

maybe by adapting this example
https://github.com/nilearn/nilearn/blob/main/examples/03_connectivity/plot_atlas_comparison.py

@whsu2s
Copy link
Author
whsu2s commented Jun 27, 2024

Hi Remi, thanks for your reply! Sure, here is an example:

The Yeo atlas parcellates the whole brain, as shown here

from nilearn.connectome import ConnectivityMeasure
from nilearn.maskers import MultiNiftiLabelsMasker

plotting.plot_roi(yeo.thick_7, title='Yeo atlas', colorbar=True)

yeo

yeo = datasets.fetch_atlas_yeo_2011()
data = datasets.fetch_development_fmri(n_subjects=3)

connectome_measure = ConnectivityMeasure(
    kind="correlation",
    standardize="zscore_sample",
)

masker = MultiNiftiLabelsMasker(
    labels_img=yeo["thick_17"],
    standardize="zscore_sample",
    standardize_confounds="zscore_sample",
    memory="nilearn_cache",
    n_jobs=2,
)

time_series = masker.fit_transform(data.func, confounds=data.confounds)
correlation_matrices = connectome_measure.fit_transform(time_series)
mean_correlation_matrix = connectome_measure.mean_

coordinates = plotting.find_parcellation_cut_coords(labels_img=yeo["thick_17"], label_hemisphere='left')

plotting.plot_connectome(
    mean_correlation_matrix,
    coordinates,
    edge_threshold="80%",
    title="Yeo Atlas 17 thick (func)",
)

By changing the argument label_hemisphere='left' to label_hemisphere='right' in the function plotting.find_parcellation_cut_coords(), you can get the plots as shown below:

left
right

The connectome only shows either the left or right hemisphere using Yeo parcellation, but the correlation matrix is actually calculated by taking the signals from both the right and left hemispheres. That's why the left and the right connectomes look symmetric as shown above while they should be asymmetric in reality.

My questions are:

  1. Does nilearn use the averaged signals from both hemispheres to plot the connectome in one hemisphere? Or I missed something in the calculation using nilearn?
  2. Are there any ways to plot the holistic connectome on the whole brain using the Yeo parcellation?

Sorry for my poor explanation. Hope that you understand what I'm trying to explain.

@Remi-Gau
Copy link
Collaborator

Thanks for the example. Helps make sure we are on the same page.

Does nilearn use the averaged signals from both hemispheres to plot the connectome in one hemisphere?

The label maskers will give you one timeseries per label in your label image. If one of the label contains voxels from both hemisphere, then data from both hemipshere will be used to compute the timeseries.

are there ways to choose the side of signals to extract,

My hunch would be that it'd be better to let users tweak the label image to only have ROI in one hemisphere rather than to have something at the nilearn masker level to just extract one hemisphere: it may seem simple to just say keep right or left but I can imagine many reasons where this would break.

@Remi-Gau
Copy link
Collaborator

for the case you presented I would do this

import nibabel as nb
import numpy as np

from nilearn import datasets, plotting
from nilearn.connectome import ConnectivityMeasure
from nilearn.image import get_data
from nilearn.image.resampling import coord_transform
from nilearn.maskers import MultiNiftiLabelsMasker

yeo = datasets.fetch_atlas_yeo_2011()

connectome_measure = ConnectivityMeasure(
    kind="correlation",
    standardize="zscore_sample",
)

label_image = nb.load((yeo["thick_17"]))

labels_data = get_data(label_image)
labels_affine = label_image.affine

# Grab hemispheres separately
x, y, z = coord_transform(0, 0, 0, np.linalg.inv(labels_affine))

left_hemi = get_data(label_image).copy()
left_hemi[: int(x)] = 0
label_image_left = nb.Nifti1Image(left_hemi, labels_affine)

right_hemi = get_data(label_image).copy()
right_hemi[int(x) :] = 0
label_image_right = nb.Nifti1Image(right_hemi, labels_affine)

for hemi, img in zip(["right", "left"], [label_image_right, label_image_left]):

    masker = MultiNiftiLabelsMasker(
        labels_img=img,
        standardize="zscore_sample",
        standardize_confounds="zscore_sample",
    )

    data = datasets.fetch_development_fmri(n_subjects=3)
    time_series = masker.fit_transform(data.func, confounds=data.confounds)

    report = masker.generate_report()
    report.open_in_browser()

    correlation_matrices = connectome_measure.fit_transform(time_series)
    mean_correlation_matrix = connectome_measure.mean_

    coordinates = plotting.find_parcellation_cut_coords(
        labels_img=img, label_hemisphere=hemi
    )

    plotting.plot_connectome(
        mean_correlation_matrix,
        coordinates,
        edge_threshold="80%",
        title=f"Yeo Atlas 17 thick (func) - {hemi}",
    )

plotting.show()

The results are now slightly different between hemispheres.

right

left

@Remi-Gau
Copy link
Collaborator

Please double check my code before using this in your analysis. I coded that a tad quickly.

@whsu2s
Copy link
Author
whsu2s commented Jun 28, 2024

Thanks a lot! Now I can plot the connectome on both hemispheres using the Yeo parcellation by specifying the argument figure of plotting.plot_connectome() to the same figure in the loop you showed.

Still I would suggest an update for the Yeo parcellation, as the documentation does not explicitly mention that the user needs to tweak the label image.

@Remi-Gau
Copy link
Collaborator

Glad it helped.
I think at best we can update the documentation about the yeo parcellation and the example we worked on in this issue to show how to do it, but I would not "change" the parcellation.

@Remi-Gau Remi-Gau added the Documentation for documentation related questions or requests label Jun 28, 2024
@Remi-Gau
Copy link
Collaborator
Remi-Gau commented Jul 5, 2024

@bthirion
do you think it would make sense to update this example:
https://github.com/nilearn/nilearn/blob/main/examples/03_connectivity/plot_atlas_comparison.py

to show how to use Nilearn to keep only one hemisphere of the yeo parcelation?

@bthirion
Copy link
Member
bthirion commented Jul 7, 2024

I think that this is a good idea. Since it makes the example longer, it should be clear in the sectioning that this is another functionality independent from the others.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Documentation for documentation related questions or requests
Projects
None yet
Development

No branches or pull requests

3 participants