示例#1
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
示例#2
0
def build_omnetome(est_path_iterlist, ID):
    """
    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.
    ID : str
        A subject id or other unique identifier.

    References
    ----------
    .. [1] Liu, Y., He, L., Cao, B., Yu, P. S., Ragin, A. B., & Leow, A. D.
      (2018). Multi-view multi-graph embedding for brain network clustering
      analysis. 32nd AAAI Conference on Artificial Intelligence, AAAI 2018.
    .. [2] Levin, K., Athreya, A., Tang, M., Lyzinski, V., & Priebe, C. E.
      (2017, November). A central limit theorem for an omnibus embedding of
      multiple random dot product graphs. In Data Mining Workshops (ICDMW),
      2017 IEEE International Conference on (pp. 964-967). IEEE.

    """
    from pathlib import Path
    import sys
    import numpy as np
    from pynets.core.utils import flatten
    from pynets.stats.embeddings import _omni_embed
    from pynets.core.utils import load_runconfig

    # Available functional and structural connectivity models
    hardcoded_params = load_runconfig()

    try:
        func_models = hardcoded_params["available_models"]["func_models"]
    except KeyError:
        print(
            "ERROR: available functional models not sucessfully extracted"
            " from runconfig.yaml"
        )
        sys.exit(1)
    try:
        struct_models = hardcoded_params["available_models"][
            "struct_models"]
    except KeyError:
        print(
            "ERROR: available structural models not sucessfully extracted"
            " from runconfig.yaml"
        )
        sys.exit(1)
    try:
        n_components = hardcoded_params["gradients"][
            "n_components"][0]
    except KeyError:
        print(
            "ERROR: available gradient dimensionality presets not "
            "sucessfully extracted from runconfig.yaml"
        )
        sys.exit(1)

    if isinstance(est_path_iterlist, list):
        est_path_iterlist = list(flatten(est_path_iterlist))
    else:
        est_path_iterlist = [est_path_iterlist]

    if len(est_path_iterlist) > 1:
        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("model-")[1].split("_")[0] in struct_models
                ]
            )
        )
        est_path_iterlist_func = list(
            set(
                [
                    i
                    for i in est_path_iterlist
                    if i.split("model-")[1].split("_")[0] in func_models
                ]
            )
        )

        if "_rsn" in ";".join(est_path_iterlist_func):
            func_subnets = list(
                set([i.split("_rsn-")[1].split("_")[0] for i in
                     est_path_iterlist_func])
            )
        else:
            func_subnets = []
        if "_rsn" in ";".join(est_path_iterlist_dwi):
            dwi_subnets = list(
                set([i.split("_rsn-")[1].split("_")[0] for i in
                     est_path_iterlist_dwi])
            )
        else:
            dwi_subnets = []

        out_paths_func = []
        out_paths_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)
            if len(parcel_dict_func[atlas]) > 0:
                if isinstance(parcel_dict_func[atlas], dict):
                    # RSN case
                    for rsn in parcel_dict_func[atlas]:
                        pop_rsn_list = []
                        graph_path_list = []
                        for graph in parcel_dict_func[atlas][rsn]:
                            pop_rsn_list.append(np.load(graph))
                            graph_path_list.append(graph)
                        if len(pop_rsn_list) > 1:
                            if len(
                                    list(set([i.shape for i in
                                              pop_rsn_list]))) > 1:
                                raise RuntimeWarning(
                                    "Inconsistent number of"
                                    " vertices in graph population "
                                    "that precludes embedding...")
                            out_path = _omni_embed(
                                pop_rsn_list, atlas, graph_path_list, ID, rsn,
                                n_components
                            )
                            out_paths_func.append(out_path)
                        else:
                            print(
                                "WARNING: Only one graph sampled, omnibus"
                                " embedding not appropriate."
                            )
                            pass
                else:
                    pop_list = []
                    graph_path_list = []
                    for pop_ref in parcel_dict_func[atlas]:
                        pop_list.append(np.load(pop_ref))
                        graph_path_list.append(pop_ref)
                    if len(pop_list) > 1:
                        if len(list(set([i.shape for i in pop_list]))) > 1:
                            raise RuntimeWarning(
                                "Inconsistent number of vertices in "
                                "graph population that precludes embedding")
                        out_path = _omni_embed(pop_list, atlas,
                                               graph_path_list, ID,
                                               n_components=n_components)
                        out_paths_func.append(out_path)
                    else:
                        print(
                            "WARNING: Only one graph sampled, omnibus "
                            "embedding not appropriate."
                        )
                        pass

            if len(parcel_dict_dwi[atlas]) > 0:
                if isinstance(parcel_dict_dwi[atlas], dict):
                    # RSN case
                    graph_path_list = []
                    for rsn in parcel_dict_dwi[atlas]:
                        pop_rsn_list = []
                        for graph in parcel_dict_dwi[atlas][rsn]:
                            pop_rsn_list.append(np.load(graph))
                            graph_path_list.append(graph)
                        if len(pop_rsn_list) > 1:
                            if len(
                                    list(set([i.shape for i in
                                              pop_rsn_list]))) > 1:
                                raise RuntimeWarning(
                                    "Inconsistent number of"
                                    " vertices in graph population "
                                    "that precludes embedding")
                            out_path = _omni_embed(
                                pop_rsn_list, atlas, graph_path_list, ID,
                                rsn, n_components
                            )
                            out_paths_dwi.append(out_path)
                        else:
                            print(
                                "WARNING: Only one graph sampled, omnibus"
                                " embedding not appropriate."
                            )
                            pass
                else:
                    pop_list = []
                    graph_path_list = []
                    for pop_ref in parcel_dict_dwi[atlas]:
                        pop_list.append(np.load(pop_ref))
                        graph_path_list.append(pop_ref)
                    if len(pop_list) > 1:
                        if len(list(set([i.shape for i in pop_list]))) > 1:
                            raise RuntimeWarning(
                                "Inconsistent number of vertices in graph"
                                " population that precludes embedding")
                        out_path = _omni_embed(pop_list, atlas,
                                               graph_path_list,
                                               ID, n_components=n_components)
                        out_paths_dwi.append(out_path)
                    else:
                        print(
                            "WARNING: Only one graph sampled, omnibus "
                            "embedding not appropriate."
                        )
                        pass
    else:
        print("At least two graphs required to build an omnetome...")
        out_paths_func = []
        out_paths_dwi = []
        pass

    return out_paths_dwi, out_paths_func
示例#3
0
def build_omnetome(est_path_iterlist, ID):
    """
    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.
    ID : str
        A subject id or other unique identifier.

    References
    ----------
    .. [1] Liu, Y., He, L., Cao, B., Yu, P. S., Ragin, A. B., & Leow, A. D. (2018).
      Multi-view multi-graph embedding for brain network clustering analysis.
      32nd AAAI Conference on Artificial Intelligence, AAAI 2018.
    .. [2] Levin, K., Athreya, A., Tang, M., Lyzinski, V., & Priebe, C. E. (2017,
      November). A central limit theorem for an omnibus embedding of multiple random
      dot product graphs. In Data Mining Workshops (ICDMW), 2017 IEEE International
      Conference on (pp. 964-967). IEEE.

    """
    import yaml
    import pkg_resources
    from pynets.stats.embeddings import _omni_embed

    # Available functional and structural connectivity models
    with open(pkg_resources.resource_filename("pynets", "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'
            )
    stream.close()

    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]))

    out_paths_func = []
    out_paths_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')
                        out_path = _omni_embed(pop_list, atlas, graph_path, ID,
                                               rsns[i])
                        out_paths_func.append(out_path)
                    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')
            out_path = _omni_embed(pop_list, atlas, graph_path, ID)
            out_paths_func.append(out_path)
        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')
                        out_path = _omni_embed(pop_list, atlas, graph_path, ID,
                                               rsns[i])
                        out_paths_dwi.append(out_path)
                    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')
            out_path = _omni_embed(pop_list, atlas, graph_path, ID)
            out_paths_dwi.append(out_path)
        else:
            print(
                'WARNING: Only one graph sampled, omnibus embedding not appropriate.'
            )
            pass

    return out_paths_dwi, out_paths_func