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