コード例 #1
0
def test_get_clusters_table_not_modifying_stat_image():
    shape = (9, 10, 11)
    data = np.zeros(shape)
    data[2:4, 5:7, 6:8] = 5.
    data[0:3, 0:3, 0:3] = 6.

    stat_img = nib.Nifti1Image(data, np.eye(4))
    data_orig = get_data(stat_img).copy()

    # test one cluster should be removed
    clusters_table = get_clusters_table(stat_img, 4, cluster_threshold=10)
    assert np.allclose(data_orig, get_data(stat_img))
    assert len(clusters_table) == 1

    # test no clusters should be removed
    stat_img = nib.Nifti1Image(data, np.eye(4))
    clusters_table = get_clusters_table(stat_img, 4, cluster_threshold=7)
    assert np.allclose(data_orig, get_data(stat_img))
    assert len(clusters_table) == 2

    # test cluster threshold is None
    stat_img = nib.Nifti1Image(data, np.eye(4))
    clusters_table = get_clusters_table(stat_img, 4, cluster_threshold=None)
    assert np.allclose(data_orig, get_data(stat_img))
    assert len(clusters_table) == 2
コード例 #2
0
def test_get_clusters_table(tmp_path):
    shape = (9, 10, 11)
    data = np.zeros(shape)
    data[2:4, 5:7, 6:8] = 5.
    stat_img = nib.Nifti1Image(data, np.eye(4))

    # test one cluster extracted
    cluster_table = get_clusters_table(stat_img, 4, 0)
    assert len(cluster_table) == 1

    # test empty table on high stat threshold
    cluster_table = get_clusters_table(stat_img, 6, 0)
    assert len(cluster_table) == 0

    # test empty table on high cluster threshold
    cluster_table = get_clusters_table(stat_img, 4, 9)
    assert len(cluster_table) == 0

    # test with filename
    fname = str(tmp_path / "stat_img.nii.gz")
    stat_img.to_filename(fname)
    cluster_table = get_clusters_table(fname, 4, 0)
    assert len(cluster_table) == 1

    # test with extra dimension
    data_extra_dim = data[..., np.newaxis]
    stat_img_extra_dim = nib.Nifti1Image(data_extra_dim, np.eye(4))
    cluster_table = get_clusters_table(stat_img_extra_dim, 4, 0)
    assert len(cluster_table) == 1
コード例 #3
0
def test_get_clusters_table():
    shape = (9, 10, 11)
    data = np.zeros(shape)
    data[2:4, 5:7, 6:8] = 5.
    stat_img = nib.Nifti1Image(data, np.eye(4))

    # test one cluster extracted
    cluster_table = get_clusters_table(stat_img, 4, 0)
    assert len(cluster_table) == 1

    # test empty table on high stat threshold
    cluster_table = get_clusters_table(stat_img, 6, 0)
    assert len(cluster_table) == 0

    # test empty table on high cluster threshold
    cluster_table = get_clusters_table(stat_img, 4, 9)
    assert len(cluster_table) == 0
コード例 #4
0
ファイル: test_reporting.py プロジェクト: rob-luke/nilearn
def test_get_clusters_table(tmp_path):
    shape = (9, 10, 11)
    data = np.zeros(shape)
    data[2:4, 5:7, 6:8] = 5.
    data[4:6, 7:9, 8:10] = -5.
    stat_img = nib.Nifti1Image(data, np.eye(4))

    # test one cluster extracted
    cluster_table = get_clusters_table(stat_img, 4, 0, two_sided=False)
    assert len(cluster_table) == 1

    # test empty table on high stat threshold
    cluster_table = get_clusters_table(stat_img, 6, 0, two_sided=False)
    assert len(cluster_table) == 0

    # test empty table on high cluster threshold
    cluster_table = get_clusters_table(stat_img, 4, 9, two_sided=False)
    assert len(cluster_table) == 0

    # test two clusters with different signs extracted
    cluster_table = get_clusters_table(stat_img, 4, 0, two_sided=True)
    assert len(cluster_table) == 2

    # test empty table on high stat threshold
    cluster_table = get_clusters_table(stat_img, 6, 0, two_sided=True)
    assert len(cluster_table) == 0

    # test empty table on high cluster threshold
    cluster_table = get_clusters_table(stat_img, 4, 9, two_sided=True)
    assert len(cluster_table) == 0

    # test with filename
    fname = str(tmp_path / "stat_img.nii.gz")
    stat_img.to_filename(fname)
    cluster_table = get_clusters_table(fname, 4, 0, two_sided=True)
    assert len(cluster_table) == 2

    # test with extra dimension
    data_extra_dim = data[..., np.newaxis]
    stat_img_extra_dim = nib.Nifti1Image(data_extra_dim, np.eye(4))
    cluster_table = get_clusters_table(stat_img_extra_dim,
                                       4,
                                       0,
                                       two_sided=True)
    assert len(cluster_table) == 2

    # Test that nans are handled correctly (No numpy axis errors are raised)
    data[data == 0] = np.nan
    stat_img_nans = nib.Nifti1Image(data, affine=np.eye(4))
    cluster_table = get_clusters_table(stat_img_nans, 1e-2, 0, two_sided=False)
    assert len(cluster_table) == 1
コード例 #5
0
from nilearn.reporting import plot_contrast_matrix

plot_contrast_matrix('StopSuccess - Go', design_matrix)
plotting.plot_glass_brain(z_map,
                          colorbar=True,
                          threshold=norm.isf(0.001),
                          plot_abs=False,
                          display_mode='z',
                          figure=plt.figure(figsize=(4, 4)))
plt.show()

###############################################################################
# We can get a latex table from a Pandas Dataframe for display and publication purposes
from nilearn.reporting import get_clusters_table

print(get_clusters_table(z_map, norm.isf(0.001), 10).to_latex())

#########################################################################
# Generating a report
# -------------------
# Using the computed FirstLevelModel and contrast information,
# we can quickly create a summary report.

from nilearn.reporting import make_glm_report

report = make_glm_report(
    model=model,
    contrasts='StopSuccess - Go',
)

#########################################################################
コード例 #6
0
def _make_stat_maps_contrast_clusters(stat_img, contrasts_plots, threshold,
                                      alpha, cluster_threshold, height_control,
                                      min_distance, bg_img, display_mode,
                                      plot_type):
    """ Populates a smaller HTML sub-template with the proper values,
     make a list containing one or more of such components
     & returns the list to be inserted into the HTML Report Template.
    Each component contains the HTML code for
    a contrast & its corresponding statistical maps & cluster table;

    Parameters
    ----------
    stat_img : Niimg-like object or None
       statistical image (presumably in z scale)
       whenever height_control is 'fpr' or None,
       stat_img=None is acceptable.
       If it is 'fdr' or 'bonferroni',
       an error is raised if stat_img is None.

    contrasts_plots: Dict[str, str]
        Contains contrast names & HTML code of the contrast's SVG plot.

    threshold: float
       desired threshold in z-scale.
       This is used only if height_control is None

    alpha: float
        number controlling the thresholding (either a p-value or q-value).
        Its actual meaning depends on the height_control parameter.
        This function translates alpha to a z-scale threshold.

    cluster_threshold : float
        cluster size threshold. In the returned thresholded map,
        sets of connected voxels (`clusters`) with size smaller
        than this number will be removed.

    height_control: string
        false positive control meaning of cluster forming
        threshold: 'fpr' or 'fdr' or 'bonferroni' or None

    min_distance: `float`
        For display purposes only.
        Minimum distance between subpeaks in mm. Default is 8 mm.

    bg_img : Niimg-like object
        Only used when plot_type is 'slice'.
        See http://nilearn.github.io/manipulating_images/input_output.html
        The background image for stat maps to be plotted on upon.
        If nothing is specified, the MNI152 template will be used.
        To turn off background image, just pass "bg_img=False".

    display_mode: string
        Choose the direction of the cuts:
        'x' - sagittal, 'y' - coronal, 'z' - axial,
        'l' - sagittal left hemisphere only,
        'r' - sagittal right hemisphere only,
        'ortho' - three cuts are performed in orthogonal directions.

        Possible values are:
        'ortho', 'x', 'y', 'z', 'xz', 'yx', 'yz',
        'l', 'r', 'lr', 'lzr', 'lyr', 'lzry', 'lyrz'.

    plot_type: string
        ['slice', 'glass']
        The type of plot to be drawn.

    Returns
    -------
    all_components: List[String]
        Each element is a set of HTML code for
        contrast name, contrast plot, statistical map, cluster table.
    """
    all_components = []
    components_template_path = os.path.join(
        HTML_TEMPLATE_ROOT_PATH, 'stat_maps_contrast_clusters_template.html')
    with open(components_template_path) as html_template_obj:
        components_template_text = html_template_obj.read()
    for contrast_name, stat_map_img in stat_img.items():
        component_text_ = string.Template(components_template_text)
        thresholded_stat_map, threshold = threshold_stats_img(
            stat_img=stat_map_img,
            threshold=threshold,
            alpha=alpha,
            cluster_threshold=cluster_threshold,
            height_control=height_control,
        )
        table_details = _clustering_params_to_dataframe(
            threshold,
            cluster_threshold,
            min_distance,
            height_control,
            alpha,
        )
        stat_map_svg = _stat_map_to_svg(
            stat_img=thresholded_stat_map,
            bg_img=bg_img,
            display_mode=display_mode,
            plot_type=plot_type,
            table_details=table_details,
        )
        cluster_table = get_clusters_table(
            stat_map_img,
            stat_threshold=threshold,
            cluster_threshold=cluster_threshold,
            min_distance=min_distance,
        )

        cluster_table_html = _dataframe_to_html(
            cluster_table,
            precision=2,
            index=False,
            classes='cluster-table',
        )
        table_details_html = _dataframe_to_html(
            table_details,
            precision=2,
            header=False,
            classes='cluster-details-table',
        )
        components_values = {
            'contrast_name': escape(contrast_name),
            'contrast_plot': contrasts_plots[contrast_name],
            'stat_map_img': stat_map_svg,
            'cluster_table_details': table_details_html,
            'cluster_table': cluster_table_html,
        }
        component_text_ = component_text_.safe_substitute(**components_values)
        all_components.append(component_text_)
    return all_components
コード例 #7
0
              display_mode='z', cut_coords=3, black_bg=True,
              title='Active minus Rest (fdr=0.05), clusters > 10 voxels')
plt.show()



###############################################################################
# We can save the effect and zscore maps to the disk.
z_map.to_filename(join(outdir, 'active_vs_rest_z_map.nii.gz'))
eff_map.to_filename(join(outdir, 'active_vs_rest_eff_map.nii.gz'))

###############################################################################
# We can furthermore extract and report the found positions in a table.

from nilearn.reporting import get_clusters_table
table = get_clusters_table(z_map, stat_threshold=threshold,
                           cluster_threshold=20)
print(table)

###############################################################################
# This table can be saved for future use.

table.to_csv(join(outdir, 'table.csv'))

###############################################################################
# Performing an F-test.
#
# "active vs rest" is a typical t test: condition versus
# baseline. Another popular type of test is an F test in which one
# seeks whether a certain combination of conditions (possibly two-,
# three- or higher-dimensional) explains a significant proportion of
# the signal.  Here one might for instance test which voxels are well
コード例 #8
0
# Calculate and plot contrast
# ---------------------------
from nilearn import plotting

z_map = fmri_glm.compute_contrast('active - rest')

plotting.plot_stat_map(z_map, bg_img=mean_img, threshold=3.1)

#########################################################################
# Extract the largest clusters
# ----------------------------
from nilearn.reporting import get_clusters_table
from nilearn.maskers import NiftiSpheresMasker

table = get_clusters_table(z_map, stat_threshold=3.1,
                           cluster_threshold=20).set_index('Cluster ID',
                                                           drop=True)
table.head()

# get the 6 largest clusters' max x, y, and z coordinates
coords = table.loc[range(1, 7), ['X', 'Y', 'Z']].values

# extract time series from each coordinate
masker = NiftiSpheresMasker(coords)
real_timeseries = masker.fit_transform(fmri_img)
predicted_timeseries = masker.fit_transform(fmri_glm.predicted[0])

#########################################################################
# Plot predicted and actual time series for 6 most significant clusters
# ---------------------------------------------------------------------
import matplotlib.pyplot as plt
コード例 #9
0
ファイル: transforms.py プロジェクト: NBCLab/NiMARE
    def transform(self, dataset):
        """Create coordinate peaks from statistical images.

        Parameters
        ----------
        dataset : :obj:`nimare.dataset.Dataset`
            Dataset with z maps and/or p maps
            that can be converted to coordinates.

        Returns
        -------
        dataset : :obj:`nimare.dataset.Dataset`
            Dataset with coordinates generated from
            images and metadata indicating origin
            of coordinates ('original' or 'nimare').
        """
        # relevant variables from dataset
        space = dataset.space
        masker = dataset.masker
        images_df = dataset.images
        metadata = dataset.metadata.copy()

        # conform space specification
        if "mni" in space.lower() or "ale" in space.lower():
            coordinate_space = "MNI"
        elif "tal" in space.lower():
            coordinate_space = "TAL"
        else:
            coordinate_space = None

        coordinates_dict = {}
        for _, row in images_df.iterrows():

            if row["id"] in list(dataset.coordinates["id"]) and self.merge_strategy == "fill":
                continue

            if row.get("z"):
                clusters = get_clusters_table(
                    nib.funcs.squeeze_image(nib.load(row.get("z"))),
                    self.z_threshold,
                    self.cluster_threshold,
                    self.two_sided,
                    self.min_distance,
                )
            elif row.get("p"):
                LGR.info(
                    f"No Z map for {row['id']}, using p map "
                    "(p-values will be treated as positive z-values)"
                )
                if self.two_sided:
                    LGR.warning(f"Cannot use two_sided threshold using a p map for {row['id']}")

                p_threshold = 1 - z_to_p(self.z_threshold)
                nimg = nib.funcs.squeeze_image(nib.load(row.get("p")))
                inv_nimg = nib.Nifti1Image(1 - nimg.get_fdata(), nimg.affine, nimg.header)
                clusters = get_clusters_table(
                    inv_nimg,
                    p_threshold,
                    self.cluster_threshold,
                    self.min_distance,
                )
                # Peak stat p-values are reported as 1 - p in get_clusters_table
                clusters["Peak Stat"] = p_to_z(1 - clusters["Peak Stat"])
            else:
                LGR.warning(f"No Z or p map for {row['id']}, skipping...")
                continue

            # skip entry if no clusters are found
            if clusters.empty:
                LGR.warning(
                    f"No clusters were found for {row['id']} at a threshold of {self.z_threshold}"
                )
                continue

            if self.remove_subpeaks:
                # subpeaks are identified as 1a, 1b, etc
                # while peaks are kept as 1, 2, 3, etc,
                # so removing all non-int rows will
                # keep main peaks while removing subpeaks
                clusters = clusters[clusters["Cluster ID"].apply(lambda x: isinstance(x, int))]

            coordinates_dict[row["study_id"]] = {
                "contrasts": {
                    row["contrast_id"]: {
                        "coords": {
                            "space": coordinate_space,
                            "x": list(clusters["X"]),
                            "y": list(clusters["Y"]),
                            "z": list(clusters["Z"]),
                            "z_stat": list(clusters["Peak Stat"]),
                        },
                        "metadata": {"coordinate_source": "nimare"},
                    }
                }
            }

        # only the generated coordinates ('demolish')
        coordinates_df = dict_to_coordinates(coordinates_dict, masker, space)
        meta_df = dict_to_df(
            pd.DataFrame(dataset._ids),
            coordinates_dict,
            "metadata",
        )

        if "coordinate_source" in meta_df.columns:
            metadata["coordinate_source"] = meta_df["coordinate_source"]
        else:
            # nimare did not overwrite any coordinates
            metadata["coordinate_source"] = ["original"] * metadata.shape[0]

        if self.merge_strategy != "demolish":
            original_idxs = ~dataset.coordinates["id"].isin(coordinates_df["id"])
            old_coordinates_df = dataset.coordinates[original_idxs]
            coordinates_df = coordinates_df.append(old_coordinates_df, ignore_index=True)

            # specify original coordinates
            original_ids = set(old_coordinates_df["id"])
            metadata.loc[metadata["id"].isin(original_ids), "coordinate_source"] = "original"

        # ensure z_stat is treated as float
        if "z_stat" in coordinates_df.columns:
            coordinates_df["z_stat"] = coordinates_df["z_stat"].astype(float)

        new_dataset = copy.deepcopy(dataset)
        new_dataset.coordinates = coordinates_df
        new_dataset.metadata = metadata

        return new_dataset