def extract_per_subject( input_dir, base_feature, roi_labels, centroids, weight_method_list, atlas, smoothing_param, node_size, num_bins, edge_range, out_dir, return_results, pretty_print_options, subject=None ): # purposefully leaving it last to enable partial function creation """ Extracts give set of weights for one subject. Parameters ---------- subject input_dir base_feature roi_labels weight_method_list atlas smoothing_param node_size num_bins edge_range out_dir return_results pretty_print_options Returns ------- """ if subject is None: return try: features = import_features(input_dir, [ subject, ], base_feature, fwhm=smoothing_param, atlas=atlas) except: traceback.print_exc() warnings.warn( 'Unable to read {} features' ' for {}\n Skipping it.'.format(base_feature, subject), UserWarning) return data, rois = mask_background_roi(features[subject], roi_labels, cfg.null_roi_name) max_id_width, nd_id, num_weights, max_wtname_width, nd_wm = pretty_print_options if return_results: edge_weights_all = dict() else: edge_weights_all = None for ww, weight_method in enumerate(weight_method_list): # unique stamp for each subject and weight expt_id = stamp_expt_weight(base_feature, atlas, smoothing_param, node_size, weight_method) sys.stdout.write( '\nProcessing id {:{id_width}} -- weight {:{wtname_width}} ({:{nd_wm}}/{:{nd_wm}})' ' :'.format(subject, weight_method, ww + 1, num_weights, nd_id=nd_id, nd_wm=nd_wm, id_width=max_id_width, wtname_width=max_wtname_width)) # actual computation of pair-wise features try: graph = hiwenet.extract(data, rois, weight_method=weight_method, num_bins=num_bins, edge_range=edge_range, return_networkx_graph=True) # retrieving edge weights weight_vec = np.array( list(nx.get_edge_attributes(graph, 'weight').values())) warn_nan(weight_vec) # weight_vec = get_triu_handle_inf_nan(edge_weights) # adding position info to nodes (for visualization later) for roi in centroids: graph.node[roi]['x'] = float(centroids[roi][0]) graph.node[roi]['y'] = float(centroids[roi][1]) graph.node[roi]['z'] = float(centroids[roi][2]) if return_results: edge_weights_all[(weight_method, subject)] = weight_vec # saving to disk try: save(weight_vec, out_dir, subject, expt_id) save_graph(graph, out_dir, subject, expt_id) except: raise IOError( 'Unable to save the network/vectorized weights to:\n{}'. format(out_dir)) except (RuntimeError, RuntimeWarning) as runexc: print(runexc) except KeyboardInterrupt: print('Exiting on keyborad interrupt! \n' 'Abandoning the remaining processing for {} weights:\n' '{}.'.format(num_weights - ww, weight_method_list[ww:])) sys.exit(1) except: print('Unable to extract {} features for {}'.format( weight_method, subject)) traceback.print_exc() sys.stdout.write('Done.') return edge_weights_all
def per_subject_multi_edge( input_dir, base_feature_list, roi_labels, centroids, weight_method_list, summary_stats, summary_stat_names, atlas, smoothing_param, node_size, num_bins, edge_range_dict, out_dir, return_results, overwrite_results, pretty_print_options, subject=None ): # purposefully leaving it last to enable partial function creation """ Extracts give set of weights for one subject. """ if subject is None: return if return_results: edge_weights_all = dict() else: edge_weights_all = None max_id_width, nd_id, num_weights, max_wtname_width, nd_wm = pretty_print_options for ww, weight_method in enumerate(weight_method_list): expt_id_multi = stamp_expt_multiedge(base_feature_list, atlas, smoothing_param, node_size, weight_method) out_path_multigraph = make_output_path_graph( out_dir, subject, [expt_id_multi, 'multigraph']) # skipping the computation if the file exists already if not overwrite_results and isfile( out_path_multigraph) and getsize(out_path_multigraph) > 0: print( '\nMultigraph exists already at\n\t{}\n skipping its computation!' .format(out_path_multigraph)) multigraph = None # signal to re-read else: multigraph = nx.MultiGraph() for base_feature in base_feature_list: # # TODO refactor # unigraph, weight_vec = compute_unigraph(input_dir, subject, base_feature, weight_method, roi_labels, # atlas, smoothing_param, node_size, centroids, # num_bins, edge_range_dict, # out_dir, overwrite_results, pretty_print_options) # if return_results: # edge_weights_all[(weight_method, base_feature, subject)] = weight_vec try: features = single_edge.import_features( input_dir, [ subject, ], base_feature, fwhm=smoothing_param, atlas=atlas) except: traceback.print_exc() warnings.warn( 'Unable to read {} features' ' for {}\n Skipping it.'.format(base_feature, subject), UserWarning) return data, rois = mask_background_roi(features[subject], roi_labels, cfg.null_roi_name) # unique stamp for each subject and weight expt_id_single = stamp_expt_weight(base_feature, atlas, smoothing_param, node_size, weight_method) sys.stdout.write( '\nProcessing id {:{id_width}} --' ' weight {:{wtname_width}} ({:{nd_wm}}/{:{nd_wm}})' ' :'.format(subject, weight_method, ww + 1, num_weights, nd_id=nd_id, nd_wm=nd_wm, id_width=max_id_width, wtname_width=max_wtname_width)) # actual computation of pair-wise features try: unigraph = hiwenet.extract( data, rois, weight_method=weight_method, num_bins=num_bins, edge_range=edge_range_dict[base_feature], return_networkx_graph=True) # retrieving edge weights weight_vec = np.array( list( nx.get_edge_attributes(unigraph, 'weight').values())) warn_nan(weight_vec) if return_results: edge_weights_all[(weight_method, base_feature, subject)] = weight_vec except (RuntimeError, RuntimeWarning) as runexc: print(runexc) except KeyboardInterrupt: print('Exiting on keyborad interrupt! \n' 'Abandoning the remaining processing ') sys.exit(1) except: print('Unable to extract {} weights for {} for {}'.format( weight_method, base_feature, subject)) traceback.print_exc() print('Done.') # TODO consider extracting some network features upon user request. add_nodal_positions(unigraph, centroids) single_edge.save_graph(unigraph, out_dir, subject, expt_id_single) # adding edges/weights from each feature to a multigraph # this also encodes the sources for u, v in unigraph.edges(): multigraph.add_edge(u, v, weight=unigraph[u][v]['weight'], base_feature=base_feature) # adding position info to nodes (for visualization later) add_nodal_positions(multigraph, centroids) save_graph(multigraph, out_path_multigraph, 'multi-edge') for stat_func, stat_name in zip(summary_stats, summary_stat_names): # creating single graph with a summary edge weight (like median) out_path_summary = make_output_path_graph( out_dir, subject, [expt_id_multi, stat_name, 'multigraph']) if not overwrite_results and isfile( out_path_summary) and getsize(out_path_summary) > 0: print( 'Summary {} of multigraph exists already at\n\t{}\n skipping its computation!' .format(stat_name, out_path_summary)) else: if multigraph is None: multigraph = nx.read_graphml(out_path_multigraph) try: summary_multigraph = summarize_multigraph( multigraph, stat_func) add_nodal_positions(summary_multigraph, centroids) save_graph(summary_multigraph, out_path_summary, '{} summary'.format(stat_name)) except: print( 'Summary {} could not be computed - skipping!'.format( stat_name)) traceback.print_exc() return edge_weights_all
'features.txt') feature_vector = np.loadtxt(features_path) return feature_vector def upper_tri_vec(matrix): "Returns the vectorized values of upper triangular part of a matrix" triu_idx = np.triu_indices_from(matrix, 1) return matrix[triu_idx] num_links = num_ROIs * (num_ROIs - 1) / 2.0 edge_weights_vec = np.zeros(len(subject_list), num_links) for ss, subject in enumerate(subject_list): features = get_features(subject) edge_weight_matrix = hiwenet.extract(features, groups, weight_method='kullback_leibler') edge_weights_vec[ss, :] = upper_tri_vec(edge_weight_matrix) out_file = os.path.join(out_folder, 'hiwenet_{}.txt'.format(subject)) np.save(out_file, edge_weight_matrix) # proceed to analysis # very rough example for training/evaluating a classifier rf = RandomForestClassifier(oob_score=True) scores = cross_val_score(rf, edge_weights_vec, subject_labels)