Ejemplo n.º 1
0
def test_parcel_naming():
    """
    Test parcel_namiing functionality
    """
    coords = [[0, 0, 0], [-5, -5, -5], [5, 5, 5], [-10, -10, -10],
              [10, 10, 10]]
    labels = nodemaker.parcel_naming(coords, vox_size='2mm')
    assert len(coords) == len(labels)
Ejemplo n.º 2
0
def test_parcel_naming():
    """
    Test parcel_namiing functionality
    """
    coords = [(0, 0, 0), (-5, -5, -5), (5, 5, 5), (-10, -10, -10),
              (10, 10, 10)]
    labels = nodemaker.parcel_naming(coords, vox_size="2mm")
    assert len(coords) == len(labels)
Ejemplo n.º 3
0
def make_node_dict_from_parcellation(parcellation, dir_path, vox_size='2mm'):
    from pynets.core.nodemaker import get_names_and_coords_of_parcels, \
        parcel_naming
    from pynets.core.utils import save_coords_and_labels_to_json
    coords, _, _, label_intensities = \
        get_names_and_coords_of_parcels(parcellation)
    labels = parcel_naming(coords, vox_size)
    node_file = save_coords_and_labels_to_json(coords, labels,
                                               dir_path, network='regen',
                                               indices=label_intensities)
    return node_file
Ejemplo n.º 4
0
    def _run_interface(self, runtime):
        from pynets.core import utils, nodemaker
        from nipype.utils.filemanip import fname_presuffix, copyfile
        from nilearn.image import concat_imgs
        import pandas as pd
        import time
        import textwrap
        from pathlib import Path
        import os.path as op
        import glob

        base_path = utils.get_file()
        # Test if atlas is a nilearn atlas. If so, fetch coords, labels, and/or
        # networks.
        nilearn_parc_atlases = [
            "atlas_harvard_oxford",
            "atlas_aal",
            "atlas_destrieux_2009",
            "atlas_talairach_gyrus",
            "atlas_talairach_ba",
            "atlas_talairach_lobe",
        ]
        nilearn_coords_atlases = ["coords_power_2011", "coords_dosenbach_2010"]
        nilearn_prob_atlases = ["atlas_msdl", "atlas_pauli_2017"]
        local_atlases = [
            op.basename(i).split(".nii")[0]
            for i in glob.glob(f"{str(Path(base_path).parent.parent)}"
                               f"/templates/atlases/*.nii.gz")
            if "_4d" not in i
        ]

        if self.inputs.parcellation is None and self.inputs.atlas in \
                nilearn_parc_atlases:
            [labels, networks_list, parcellation
             ] = nodemaker.nilearn_atlas_helper(self.inputs.atlas,
                                                self.inputs.parc)
            if parcellation:
                if not isinstance(parcellation, str):
                    nib.save(
                        parcellation, f"{runtime.cwd}"
                        f"{self.inputs.atlas}{'.nii.gz'}")
                    parcellation = f"{runtime.cwd}" \
                                   f"{self.inputs.atlas}{'.nii.gz'}"
                if self.inputs.clustering is False:
                    [parcellation,
                     labels] = \
                        nodemaker.enforce_hem_distinct_consecutive_labels(
                        parcellation, label_names=labels)
                [coords, atlas, par_max, label_intensities] = \
                    nodemaker.get_names_and_coords_of_parcels(parcellation)
                if self.inputs.parc is True:
                    parcels_4d_img = nodemaker.three_to_four_parcellation(
                        parcellation)
                else:
                    parcels_4d_img = None
            else:
                raise FileNotFoundError(
                    f"\nAtlas file for {self.inputs.atlas} not found!")

            atlas = self.inputs.atlas
        elif (self.inputs.parcellation is None and self.inputs.parc is False
              and self.inputs.atlas in nilearn_coords_atlases):
            print("Fetching coords and labels from nilearn coordinate-based"
                  " atlas library...")
            # Fetch nilearn atlas coords
            [coords, _, networks_list,
             labels] = nodemaker.fetch_nilearn_atlas_coords(self.inputs.atlas)
            parcels_4d = None
            par_max = None
            atlas = self.inputs.atlas
            parcellation = None
            label_intensities = None
        elif (self.inputs.parcellation is None and self.inputs.parc is False
              and self.inputs.atlas in nilearn_prob_atlases):
            import matplotlib
            matplotlib.use("agg")
            from nilearn.plotting import find_probabilistic_atlas_cut_coords

            print("Fetching coords and labels from nilearn probabilistic atlas"
                  " library...")
            # Fetch nilearn atlas coords
            [labels, networks_list, parcellation
             ] = nodemaker.nilearn_atlas_helper(self.inputs.atlas,
                                                self.inputs.parc)
            coords = find_probabilistic_atlas_cut_coords(maps_img=parcellation)
            if parcellation:
                if not isinstance(parcellation, str):
                    nib.save(
                        parcellation, f"{runtime.cwd}"
                        f"{self.inputs.atlas}{'.nii.gz'}")
                    parcellation = f"{runtime.cwd}" \
                                   f"{self.inputs.atlas}{'.nii.gz'}"
                if self.inputs.clustering is False:
                    [parcellation,
                     labels] = \
                        nodemaker.enforce_hem_distinct_consecutive_labels(
                        parcellation, label_names=labels)
                if self.inputs.parc is True:
                    parcels_4d_img = nodemaker.three_to_four_parcellation(
                        parcellation)
                else:
                    parcels_4d_img = None
            else:
                raise FileNotFoundError(
                    f"\nAtlas file for {self.inputs.atlas} not found!")

            par_max = None
            atlas = self.inputs.atlas
            label_intensities = None
        elif self.inputs.parcellation is None and self.inputs.atlas in \
            local_atlases:
            parcellation_pre = (
                f"{str(Path(base_path).parent.parent)}/templates/atlases/"
                f"{self.inputs.atlas}.nii.gz")
            parcellation = fname_presuffix(parcellation_pre,
                                           newpath=runtime.cwd)
            copyfile(parcellation_pre,
                     parcellation,
                     copy=True,
                     use_hardlink=False)
            try:
                par_img = nib.load(parcellation)
            except indexed_gzip.ZranError as e:
                print(
                    e, "\nCannot load subnetwork reference image. "
                    "Do you have git-lfs installed?")
            try:
                if self.inputs.clustering is False:
                    [parcellation, _] = \
                        nodemaker.enforce_hem_distinct_consecutive_labels(
                            parcellation)

                # Fetch user-specified atlas coords
                [coords, _, par_max, label_intensities] = \
                    nodemaker.get_names_and_coords_of_parcels(parcellation)
                if self.inputs.parc is True:
                    parcels_4d_img = nodemaker.three_to_four_parcellation(
                        parcellation)
                else:
                    parcels_4d_img = None
                # Describe user atlas coords
                print(f"\n{self.inputs.atlas} comes with {par_max} parcels\n")
            except ValueError as e:
                print(
                    e, "Either you have specified the name of an atlas that "
                    "does not exist in the nilearn or local repository or "
                    "you have not supplied a 3d atlas parcellation image!")
            labels = None
            networks_list = None
            atlas = self.inputs.atlas
        elif self.inputs.parcellation:
            if self.inputs.clustering is True:
                while True:
                    if op.isfile(self.inputs.parcellation):
                        break
                    else:
                        print("Waiting for atlas file...")
                        time.sleep(5)

            try:
                parcellation_tmp_path = fname_presuffix(
                    self.inputs.parcellation, newpath=runtime.cwd)
                copyfile(self.inputs.parcellation,
                         parcellation_tmp_path,
                         copy=True,
                         use_hardlink=False)
                # Fetch user-specified atlas coords
                if self.inputs.clustering is False:
                    [parcellation,
                     _] = nodemaker.enforce_hem_distinct_consecutive_labels(
                         parcellation_tmp_path)
                else:
                    parcellation = parcellation_tmp_path
                [coords, atlas, par_max, label_intensities] = \
                    nodemaker.get_names_and_coords_of_parcels(parcellation)
                if self.inputs.parc is True:
                    parcels_4d_img = nodemaker.three_to_four_parcellation(
                        parcellation)
                else:
                    parcels_4d_img = None

                atlas = utils.prune_suffices(atlas)

                # Describe user atlas coords
                print(f"\n{atlas} comes with {par_max} parcels\n")
            except ValueError as e:
                print(
                    e, "Either you have specified the name of an atlas that "
                    "does not exist in the nilearn or local repository or "
                    "you have not supplied a 3d atlas parcellation image!")
            labels = None
            networks_list = None
        else:
            raise ValueError(
                "Either you have specified the name of an atlas that does"
                " not exist in the nilearn or local repository or you have"
                " not supplied a 3d atlas parcellation image!")

        # Labels prep
        if atlas and not labels:
            if (self.inputs.ref_txt is not None) and (op.exists(
                    self.inputs.ref_txt)):
                labels = pd.read_csv(self.inputs.ref_txt,
                                     sep=" ",
                                     header=None,
                                     names=["Index",
                                            "Region"])["Region"].tolist()
            else:
                if atlas in local_atlases:
                    ref_txt = (
                        f"{str(Path(base_path).parent.parent)}/templates/"
                        f"labels/"
                        f"{atlas}.txt")
                else:
                    ref_txt = self.inputs.ref_txt
                if ref_txt is not None:
                    try:
                        labels = pd.read_csv(ref_txt,
                                             sep=" ",
                                             header=None,
                                             names=["Index", "Region"
                                                    ])["Region"].tolist()
                    except BaseException:
                        if self.inputs.use_parcel_naming is True:
                            try:
                                labels = nodemaker.parcel_naming(
                                    coords, self.inputs.vox_size)
                            except BaseException:
                                print("AAL reference labeling failed!")
                                labels = np.arange(len(coords) + 1)[
                                    np.arange(len(coords) + 1) != 0].tolist()
                        else:
                            print("Using generic index labels...")
                            labels = np.arange(len(coords) +
                                               1)[np.arange(len(coords) +
                                                            1) != 0].tolist()
                else:
                    if self.inputs.use_parcel_naming is True:
                        try:
                            labels = nodemaker.parcel_naming(
                                coords, self.inputs.vox_size)
                        except BaseException:
                            print("AAL reference labeling failed!")
                            labels = np.arange(len(coords) +
                                               1)[np.arange(len(coords) +
                                                            1) != 0].tolist()
                    else:
                        print("Using generic index labels...")
                        labels = np.arange(len(coords) +
                                           1)[np.arange(len(coords) +
                                                        1) != 0].tolist()

        dir_path = utils.do_dir_path(atlas, self.inputs.outdir)

        if len(coords) != len(labels):
            labels = [
                i for i in labels if (i != 'Unknown' and i != 'Background')
            ]
            if len(coords) != len(labels):
                print("Length of coordinates is not equal to length of "
                      "label names...")
                if self.inputs.use_parcel_naming is True:
                    try:
                        print("Attempting consensus parcel naming instead...")
                        labels = nodemaker.parcel_naming(
                            coords, self.inputs.vox_size)
                    except BaseException:
                        print("Reverting to integer labels instead...")
                        labels = np.arange(len(coords) +
                                           1)[np.arange(len(coords) +
                                                        1) != 0].tolist()
                else:
                    print("Reverting to integer labels instead...")
                    labels = np.arange(len(coords) +
                                       1)[np.arange(len(coords) +
                                                    1) != 0].tolist()

        print(f"Coordinates:\n{coords}")
        print(f"Labels:\n"
              f"{textwrap.shorten(str(labels), width=1000, placeholder='...')}"
              f"")

        assert len(coords) == len(labels)

        if label_intensities is not None:
            self._results["labels"] = list(zip(labels, label_intensities))
        else:
            self._results["labels"] = labels
        self._results["coords"] = coords
        self._results["atlas"] = atlas
        self._results["networks_list"] = networks_list
        # TODO: Optimize this with 4d array concatenation and .npyz

        out_path = f"{runtime.cwd}/parcels_4d.nii.gz"
        nib.save(parcels_4d_img, out_path)
        self._results["parcels_4d"] = out_path
        self._results["par_max"] = par_max
        self._results["parcellation"] = parcellation
        self._results["dir_path"] = dir_path

        return runtime