Ejemplo n.º 1
0
def build_masetome(est_path_iterlist, ID):
    """
    Embeds structural-functional graph pairs into a common invariant subspace.

    Parameters
    ----------
    est_path_iterlist : list
        List of list of pairs of file paths (.npy) corresponding to
        structural and functional connectomes matched at a given node
        resolution.
    ID : str
        A subject id or other unique identifier.

    References
    ----------
    .. [1] Rosenthal, G., Váša, F., Griffa, A., Hagmann, P., Amico, E., Goñi, J.,
      Sporns, O. (2018). Mapping higher-order relations between brain structure
      and function with embedded vector representations of connectomes.
      Nature Communications. https://doi.org/10.1038/s41467-018-04614-w

    """
    import numpy as np
    from pynets.core.utils import prune_suffices
    from pynets.stats.embeddings import _mase_embed
    from pynets.core.utils import load_runconfig

    # Available functional and structural connectivity models
    hardcoded_params = load_runconfig()
    try:
        n_components = hardcoded_params["gradients"]["n_components"][0]
    except KeyError:
        import sys
        print("ERROR: available gradient dimensionality presets not "
              "sucessfully extracted from runconfig.yaml")
        sys.exit(1)

    out_paths = []
    for pairs in est_path_iterlist:
        pop_list = []
        for _file in pairs:
            pop_list.append(np.load(_file))
        atlas = prune_suffices(pairs[0].split("/")[-3])
        res = prune_suffices("_".join(pairs[0].split("/")[-1].split("modality")
                                      [1].split("_")[1:]).split("_est")[0])
        if "rsn" in res:
            subgraph = res.split("rsn-")[1].split('_')[0]
        else:
            subgraph = "all_nodes"
        out_path = _mase_embed(pop_list,
                               atlas,
                               pairs[0],
                               ID,
                               subgraph_name=subgraph,
                               n_components=n_components)
        out_paths.append(out_path)

    return out_paths
Ejemplo n.º 2
0
def build_masetome(est_path_iterlist, ID):
    """
    Embeds structural-functional graph pairs into a common invariant subspace.

    Parameters
    ----------
    est_path_iterlist : list
        List of list of pairs of file paths (.npy) corresponding to
        structural and functional connectomes matched at a given node
        resolution.
    ID : str
        A subject id or other unique identifier.

    References
    ----------
    .. [1] Rosenthal, G., Váša, F., Griffa, A., Hagmann, P., Amico, E., Goñi, J.,
      Sporns, O. (2018). Mapping higher-order relations between brain structure
      and function with embedded vector representations of connectomes.
      Nature Communications. https://doi.org/10.1038/s41467-018-04614-w

    """
    import numpy as np
    from pynets.core.utils import prune_suffices
    from pynets.stats.embeddings import _mase_embed

    out_paths = []
    for pairs in est_path_iterlist:
        pop_list = []
        for _file in pairs:
            pop_list.append(np.load(_file))
        atlas = prune_suffices(pairs[0].split("/")[-3])
        res = prune_suffices("_".join(pairs[0].split("/")[-1].split("modality")
                                      [1].split("_")[1:]).split("_est")[0])
        if "rsn" in res:
            subgraph = res.split("rsn-")[1]
        else:
            subgraph = "whole_brain"
        out_path = _mase_embed(pop_list,
                               atlas,
                               pairs[0],
                               ID,
                               subgraph_name=subgraph)
        out_paths.append(out_path)

    return out_paths
Ejemplo n.º 3
0
def build_masetome(est_path_iterlist, ID):
    """
    Embeds structural-functional graph pairs into a common invariant subspace.

    Parameters
    ----------
    est_path_iterlist : list
        List of list of pairs of file paths (.npy) corresponding to
        structural and functional connectomes matched at a given node
        resolution.
    ID : str
        A subject id or other unique identifier.

    References
    ----------
    .. [1] Rosenthal, G., Váša, F., Griffa, A., Hagmann, P., Amico, E., Goñi,
      J., Sporns, O. (2018). Mapping higher-order relations between brain
      structure and function with embedded vector representations of
      connectomes. Nature Communications.
      https://doi.org/10.1038/s41467-018-04614-w

    """
    from pathlib import Path
    import os
    import numpy as np
    from pynets.core.utils import prune_suffices
    from pynets.stats.embeddings import _mase_embed
    from pynets.core.utils import load_runconfig

    # Available functional and structural connectivity models
    hardcoded_params = load_runconfig()
    try:
        n_components = hardcoded_params["gradients"][
            "n_components"][0]
    except KeyError:
        import sys
        print(
            "ERROR: available gradient dimensionality presets not "
            "sucessfully extracted from runconfig.yaml"
        )
        sys.exit(1)

    out_paths = []
    for pairs in est_path_iterlist:
        pop_list = []
        for _file in pairs:
            mat = np.load(_file)
            if np.isfinite(mat).all():
                pop_list.append(mat)
        if len(pop_list) != len(pairs):
            continue
        atlas = prune_suffices(pairs[0].split("/")[-3])
        res = prune_suffices("_".join(pairs[0].split(
            "/")[-1].split("modality")[1].split("_")[1:]).split("_est")[0])
        if "rsn" in res:
            subgraph = res.split("rsn-")[1].split('_')[0]
        else:
            subgraph = "all_nodes"
        out_path = _mase_embed(
            pop_list,
            atlas,
            pairs[0],
            ID,
            subgraph_name=subgraph, n_components=n_components)

        if out_path is not None:
            out_paths.append(out_path)
        else:
            # Add a null tmp file to prevent pool from breaking
            dir_path = str(Path(os.path.dirname(pairs[0])))
            namer_dir = f"{dir_path}/mplx_embeddings"
            if os.path.isdir(namer_dir) is False:
                os.makedirs(namer_dir, exist_ok=True)

            out_path = (
                f"{namer_dir}/gradient-MASE_{atlas}_{subgraph}"
                f"_{os.path.basename(pairs[0])}_NULL"
            )
            if not os.path.exists(out_path):
                os.mknod(out_path)
            out_paths.append(out_path)

    return out_paths
Ejemplo n.º 4
0
def build_embedded_connectome(est_path_iterlist, ID, multimodal, embed):
    """
    Embeds ensemble population of graphs into an embedded ensemble feature vector.

    Parameters
    ----------
    est_path_iterlist : list
        List of file paths to .npy file containing graph with thresholding applied.
    ID : str
        A subject id or other unique identifier.
    multimodal : list
        List of booleans indicating whether multiple modalities of input data have been specified.
    embed : str
        Specifies which type of ensemble embedding will be performed. Options include `omni` and `mase`.
    """
    import yaml
    from pathlib import Path
    from pynets.stats.embeddings import _mase_embed, _omni_embed
    # Available functional and structural connectivity models
    with open("%s%s" % (str(Path(__file__).parent.parent), '/runconfig.yaml'),
              'r') as stream:
        hardcoded_params = yaml.load(stream)
        try:
            func_models = hardcoded_params['available_models']['func_models']
        except KeyError:
            print(
                'ERROR: available functional models not sucessfully extracted from runconfig.yaml'
            )
        try:
            struct_models = hardcoded_params['available_models'][
                'struct_models']
        except KeyError:
            print(
                'ERROR: available structural models not sucessfully extracted from runconfig.yaml'
            )

    if multimodal is True:
        out_path = None
        atlases = list(
            set([x.split('/')[-3].split('/')[0] for x in est_path_iterlist]))
        parcel_dict_func = dict.fromkeys(atlases)
        parcel_dict_dwi = dict.fromkeys(atlases)

        est_path_iterlist_dwi = list(
            set([
                i for i in est_path_iterlist
                if i.split('est-')[1].split('_')[0] in struct_models
            ]))
        est_path_iterlist_func = list(
            set([
                i for i in est_path_iterlist
                if i.split('est-')[1].split('_')[0] in func_models
            ]))

        func_subnets = list(
            set([
                i.split('_est')[0].split('/')[-1]
                for i in est_path_iterlist_func
            ]))

        dwi_subnets = list(
            set([
                i.split('_est')[0].split('/')[-1]
                for i in est_path_iterlist_dwi
            ]))

        for atlas in atlases:
            if len(func_subnets) > 1:
                parcel_dict_func[atlas] = {}
                for sub_net in func_subnets:
                    parcel_dict_func[atlas][sub_net] = []
            else:
                parcel_dict_func[atlas] = []

            if len(dwi_subnets) > 1:
                parcel_dict_dwi[atlas] = {}
                for sub_net in dwi_subnets:
                    parcel_dict_dwi[atlas][sub_net] = []
            else:
                parcel_dict_dwi[atlas] = []

            for graph_path in est_path_iterlist_dwi:
                if atlas in graph_path:
                    if len(dwi_subnets) > 1:
                        for sub_net in dwi_subnets:
                            if sub_net in graph_path:
                                parcel_dict_dwi[atlas][sub_net].append(
                                    graph_path)
                    else:
                        parcel_dict_dwi[atlas].append(graph_path)

            for graph_path in est_path_iterlist_func:
                if atlas in graph_path:
                    if len(func_subnets) > 1:
                        for sub_net in func_subnets:
                            if sub_net in graph_path:
                                parcel_dict_func[atlas][sub_net].append(
                                    graph_path)
                    else:
                        parcel_dict_func[atlas].append(graph_path)

            pop_list = []
            for pop_ref in parcel_dict_func[atlas]:
                # RSN case
                if isinstance(pop_ref, dict):
                    rsns = [i.split('_')[1] for i in list(pop_ref.keys())]
                    i = 0
                    for rsn in rsns:
                        pop_rsn_list = []
                        for graph in pop_ref[rsn]:
                            pop_list.append(np.load(graph))
                        if len(pop_rsn_list) > 1:
                            if len(list(set([i.shape
                                             for i in pop_rsn_list]))) > 1:
                                raise RuntimeWarning(
                                    'ERROR: Inconsistent number of vertices in graph population '
                                    'that precludes embedding')
                            if embed == 'omni':
                                out_path = _omni_embed(pop_list, atlas,
                                                       graph_path, ID, rsns[i])
                            elif embed == 'mase':
                                out_path = _mase_embed(pop_list, atlas,
                                                       graph_path, ID, rsns[i])
                            else:
                                raise ValueError(
                                    'Embedding type not recognized. Presently supported options include: '
                                    'omni or mase')
                        else:
                            print(
                                'WARNING: Only one graph sampled, omnibus embedding not appropriate.'
                            )
                            pass
                        i = i + 1
                else:
                    pop_list.append(np.load(pop_ref))
            if len(pop_list) > 1:
                if len(list(set([i.shape for i in pop_list]))) > 1:
                    raise RuntimeWarning(
                        'ERROR: Inconsistent number of vertices in graph population that '
                        'precludes embedding')
                if embed == 'omni':
                    out_path = _omni_embed(pop_list, atlas, graph_path, ID)
                elif embed == 'mase':
                    out_path = _mase_embed(pop_list, atlas, graph_path, ID)
                else:
                    raise ValueError(
                        'Embedding type not recognized. Presently supported options include: '
                        'omni or mase')
            else:
                print(
                    'WARNING: Only one graph sampled, omnibus embedding not appropriate.'
                )
                pass

            pop_list = []
            for pop_ref in parcel_dict_dwi[atlas]:
                # RSN case
                if isinstance(pop_ref, dict):
                    rsns = [i.split('_')[1] for i in list(pop_ref.keys())]
                    i = 0
                    for rsn in rsns:
                        pop_rsn_list = []
                        for graph in pop_ref[rsn]:
                            pop_list.append(np.load(graph))
                        if len(pop_rsn_list) > 1:
                            if len(list(set([i.shape
                                             for i in pop_rsn_list]))) > 1:
                                raise RuntimeWarning(
                                    'ERROR: Inconsistent number of vertices in graph population '
                                    'that precludes embedding')
                            if embed == 'omni':
                                out_path = _omni_embed(pop_list, atlas,
                                                       graph_path, ID, rsns[i])
                            elif embed == 'mase':
                                out_path = _mase_embed(pop_list, atlas,
                                                       graph_path, ID, rsns[i])
                            else:
                                raise ValueError(
                                    'Embedding type not recognized. Presently supported options include: '
                                    'omni or mase')
                        else:
                            print(
                                'WARNING: Only one graph sampled, omnibus embedding not appropriate.'
                            )
                            pass
                        i = i + 1
                else:
                    pop_list.append(np.load(pop_ref))
            if len(pop_list) > 1:
                if len(list(set([i.shape for i in pop_list]))) > 1:
                    raise RuntimeWarning(
                        'ERROR: Inconsistent number of vertices in graph population that '
                        'precludes embedding')
                if embed == 'omni':
                    out_path = _omni_embed(pop_list, atlas, graph_path, ID)
                elif embed == 'mase':
                    out_path = _mase_embed(pop_list, atlas, graph_path, ID)
                else:
                    raise ValueError(
                        'Embedding type not recognized. Presently supported options include: '
                        'omni or mase')
            else:
                print(
                    'WARNING: Only one graph sampled, omnibus embedding not appropriate.'
                )
                pass

    elif (multimodal is False) and (len(est_path_iterlist) > 1):
        atlases = list(
            set([x.split('/')[-3].split('/')[0] for x in est_path_iterlist]))
        parcel_dict = dict.fromkeys(atlases)
        subnets = list(
            set([
                i.split('_est')[0].split('/')[-1] for i in est_path_iterlist
                if i.split('_est')[0].split('/')[-1] != ID
            ]))
        out_path = None
        for atlas in atlases:
            if len(subnets) > 1:
                parcel_dict[atlas] = {}
                for sub_net in subnets:
                    parcel_dict[atlas][sub_net] = []
            else:
                parcel_dict[atlas] = []

            for graph_path in est_path_iterlist:
                if atlas in graph_path:
                    if len(subnets) > 1:
                        for sub_net in subnets:
                            if sub_net in graph_path:
                                parcel_dict[atlas][sub_net].append(graph_path)
                    else:
                        parcel_dict[atlas].append(graph_path)
            pop_list = []
            for pop_ref in parcel_dict[atlas]:
                # RSN case
                if isinstance(pop_ref, dict):
                    rsns = [i.split('_')[1] for i in list(pop_ref.keys())]
                    i = 0
                    for rsn in rsns:
                        pop_rsn_list = []
                        for graph in pop_ref[rsn]:
                            pop_list.append(np.load(graph))
                        if len(pop_rsn_list) > 1:
                            if len(list(set([i.shape
                                             for i in pop_rsn_list]))) > 1:
                                raise RuntimeWarning(
                                    'ERROR: Inconsistent number of vertices in graph population '
                                    'that precludes embedding')
                            out_path = _omni_embed(pop_rsn_list, rsns[i])
                        else:
                            print(
                                'WARNING: Only one graph sampled, omnibus embedding not appropriate.'
                            )
                            pass
                        i = i + 1
                else:
                    pop_list.append(np.load(pop_ref))
            if len(pop_list) > 1:
                if len(list(set([i.shape for i in pop_list]))) > 1:
                    raise RuntimeWarning(
                        'ERROR: Inconsistent number of vertices in graph population that '
                        'precludes embedding')
                if embed == 'omni':
                    out_path = _omni_embed(pop_list, atlas, graph_path, ID)
                elif embed == 'mase':
                    out_path = _mase_embed(pop_list, atlas, graph_path, ID)
                else:
                    raise ValueError(
                        'Embedding type not recognized. Presently supported options include: '
                        'omni or mase')
            else:
                print(
                    'WARNING: Only one graph sampled, omnibus embedding not appropriate.'
                )
                pass
    else:
        raise RuntimeWarning(
            'ERROR: Only one graph sampled, omnibus embedding not appropriate.'
        )

    return out_path