def test_isolate_node(): g = remove_filters(Graph(directed=True)) g.add_vertex(4) g.add_edge_list([(0, 1), (1, 0), (0, 2,), (2, 0), (0, 3), (3, 0)]) isolate_node(g, 1) assert set(label_components(g, directed=False)[0].a) == {0, 1} isolate_node(g, 0) assert set(label_components(g, directed=False)[0].a) == {0, 1, 2, 3}
def is_very_fast(protocol, valuation, disabled): graph, vertices, edges = transformation_graph(protocol, valuation, disabled) components, _, is_bottom = label_components(graph, attractors=True) U = {q for q in vertices if not is_bottom[components[vertices[q]]]} formula = Formula(valuation, disabled) for t in protocol.transitions: p, q = tuple(t.pre) p_, q_ = tuple(t.post) if (p in vertices and q in vertices and p_ in vertices and q_ in vertices and len({p, q, p_, q_} & U) > 0): if ((components[vertices[p]] != components[vertices[p_]]) and (components[vertices[p]] != components[vertices[q_]]) and (components[vertices[q]] != components[vertices[p_]]) and (components[vertices[q]] != components[vertices[q_]])): continue elif formula.implies_all_absent_tautology_check({t.pre}): continue else: return False return True
def connected_components(edges, num_nodes): """ Run connected components on the graph encoded by 'edges' and num_nodes. The graph vertex IDs must be CONSECUTIVE. edges: ndarray, shape=(N,2), dtype=np.uint32 num_nodes: Integer, max_node+1. (Allows for graphs which contain nodes that are not referenced in 'edges'.) Returns: ndarray of shape (num_nodes,), labeled by component index from 0..C Note: Uses graph-tool if it's installed; otherwise uses networkx (slower). """ if _graph_tool_available: from graph_tool.topology import label_components g = gt.Graph(directed=False) g.add_vertex(num_nodes) g.add_edge_list(edges) cc_pmap, _hist = label_components(g) return cc_pmap.get_array() else: import networkx as nx g = nx.Graph() g.add_edges_from(edges) cc_labels = np.zeros((num_nodes, ), np.uint32) for i, component_set in enumerate(nx.connected_components(g)): cc_labels[np.array(list(component_set))] = i return cc_labels
def _mapping_from_edges_gt(edges): """ Helper function for mapping_from_edges() Compute the connected components of the graph defined by 'edges', and return the mapping of segment ID -> body ID as an UNSORTED pandas.Series (where segment is the index). Note: This version uses graph-tool to compute the connected components, which is very fast. However, graph-tool is not installed by default due to licensing restrictions. """ from graph_tool.topology import label_components g = gt.Graph(directed=False) sv_pmap = g.add_edge_list( edges, hashed=True ) cc_pmap, _hist = label_components(g) df = pd.DataFrame({'sv': sv_pmap.get_array(), 'cc_index': cc_pmap.get_array()}) # Convert component labels to body IDs (min segment ID in the component) cc_body_ids = df.groupby('cc_index').min() cc_body_ids.columns = ['body'] mapped_cc_df = df.merge( cc_body_ids, how='inner', left_on='cc_index', right_index=True, copy=False ) mapping = pd.Series(index=mapped_cc_df['sv'].values.astype(edges.dtype), data=mapped_cc_df['body'].values.astype(edges.dtype)) mapping.name = 'body' mapping.index.name = 'sv' return mapping
def split_gt(): g = GTGraph() g.add_edge_list(adjacency) component_labels = label_components(g, directed=False)[0].a components = group(component_labels) result = mesh.submesh(components, only_watertight=only_watertight) return result
def is_fast(protocol, valuation, disabled): graph, vertices, edges = transformation_graph(protocol, valuation, disabled) components, _, is_bottom = label_components(graph, attractors=True) U = {q for q in vertices if not is_bottom[components[vertices[q]]]} R = {q: set() for q in vertices} expV = set() for (p, q) in edges: if components[vertices[p]] != components[vertices[q]]: for t in edges[p, q]: expV.add(t.pre) if t.pre not in disabled: for r in (set(t.pre) & U): R[r].add(t.pre) for q in U: formula = Formula(valuation, disabled) formula.assert_some_pair_present(expV) formula.assert_some_states_present({q}) if not formula.implies_some_present_tautology_check(R[q]): return False return True
def compute_I(protocol, valuation, disabled): graph, vertices, _ = transformation_graph(protocol, valuation, disabled, stable=True) components, _, is_bottom = label_components(graph, attractors=True) return {q for q in vertices if not is_bottom[components[vertices[q]]]}
def components_graphtool(): g = GTGraph() # make sure all the nodes are in the graph if min_len <= 1: g.add_vertex(node_count) g.add_edge_list(edges) component_labels = label_components(g, directed=False)[0].a components = grouping.group(component_labels, min_len=min_len) return components
def run(filename, output, header_bool, sub, obj, pred, props, undirected, strong): # import modules locally import csv import sys from graph_tool import load_graph_from_csv from graph_tool.util import find_edge from graph_tool.topology import label_components from kgtk.exceptions import KGTKException from kgtk.cli_argparse import KGTKArgumentParser def find_pred_position(sub, pred, obj): if pred < sub and pred < obj: return pred elif (pred > sub and pred < obj) or (pred < sub and pred > obj): return pred - 1 else: return pred - 2 try: header = ['node1', 'label', 'node2'] label = 'c' + str(find_pred_position(sub, pred, obj)) g = load_graph_from_csv(filename, not (undirected), skip_first=not (header_bool), hashed=True, csv_options={'delimiter': '\t'}, ecols=(sub, obj)) es = [] if props: properties = props.split(',') for e in properties: es += (find_edge(g, g.edge_properties[label], e)) g.clear_edges() g.add_edge_list(list(set(es))) comp, hist = label_components(g, directed=strong) if output: f = open(output, 'w') wr = csv.writer(f, quoting=csv.QUOTE_NONE, delimiter="\t", escapechar="\n", quotechar='') wr.writerow(header) for v, c in enumerate(comp): wr.writerow( [g.vertex_properties['name'][v], 'connected_component', c]) f.close() else: sys.stdout.write('%s\t%s\t%s\n' % ('node1', 'label', 'node2')) for v, c in enumerate(comp): sys.stdout.write('%s\t%s\t%s\n' % (g.vertex_properties['name'][v], 'connected_component', str(c))) except: raise KGTKException
def get_comps(G): labels, _ = topology.label_components(G) labels = labels.a nc = np.max(labels) + 1 comps = [[] for _ in range(nc)] [comps[labels[i]].append(i) for i in range(len(labels))] return comps
def split_gt(): g = GTGraph() if not only_watertight: # same as above, for single triangles with no adjacency g.add_vertex(len(mesh.faces)) g.add_edge_list(adjacency) component_labels = label_components(g, directed=False)[0].a components = group(component_labels) result = mesh.submesh(components, only_watertight=only_watertight) return result
def get_incompatible_segments(g, seg_index, out_edges): incomp_graph = Graph(directed=False) num_segs = np.max(seg_index.a)+1 incomp_graph.add_vertex(num_segs) for v in g.get_vertices(): for vs in group_adjacent(sorted(g.get_out_neighbors(v))): edges = out_edges[v][np.where(np.isin(out_edges[v][:,1], vs))][:,2] segments = list(np.unique(seg_index.a[edges])) [incomp_graph.add_edge(s,t) for i,s in enumerate(segments) for t in segments[i+1:]] return label_components(incomp_graph)[0].a
def _connected_components(weighted_projection): if isinstance(weighted_projection, nx.DiGraph): return nx.number_weakly_connected_components(weighted_projection) else: from graph_tool.topology import label_components G = weighted_projection G.set_directed(False) _, comps = label_components(G) G.set_directed(True) return len(comps)
def exp(protocol, valuation, disabled): graph, vertices, edges = transformation_graph(protocol, valuation, disabled) components, _ = label_components(graph) expF = set() for (p, q) in edges: if components[vertices[p]] != components[vertices[q]]: for t in edges[p, q]: expF.add(t.pre) return expF
def is_tree(tree): # is tree? l, _ = label_components(GraphView(tree, directed=False)) if not np.all(np.array(l.a) == 0): print('not connected') print(np.array(l.a)) return False if tree.num_edges() != (tree.num_vertices() - 1): print('n. edges != n. nodes - 1') return False return True
def graph_from_adjacency_matrix( adjacency_matrix: Union[np.ndarray, List[List[int]]], aprops: Optional[Union[np.ndarray, List[Any]]] = None, ): """ Graph from adjacency matrix. Parameters ---------- adjacency_matrix: Union[np.ndarray, List[List[int]]] Adjacency matrix aprops: Union[np.ndarray, List[Any]], optional Atomic properties Returns ------- Graph Molecular graph Notes ----- It the atomic numbers are passed, they are used as node attributes. """ # Get upper triangular adjacency matrix adj = np.triu(adjacency_matrix) assert adj.shape[0] == adj.shape[1] num_vertices = adj.shape[0] G = gt.Graph(directed=False) G.add_vertex(n=num_vertices) G.add_edge_list(np.transpose(adj.nonzero())) # Check if graph is connected, for warning cc, _ = topology.label_components(G) if set(cc.a) != {0}: warnings.warn(warn_disconnected_graph) if aprops is not None: if not isinstance(aprops, np.ndarray): aprops = np.array(aprops) assert aprops.shape[0] == num_vertices ptype: str = _c_type(aprops.dtype) # Get C type vprop = G.new_vertex_property(ptype, vals=aprops) # Create property map G.vertex_properties["aprops"] = vprop # Set property map return G
def calculate_cutoff_components(graph, n_split_threshold=10): """Apply thresholding to a graph gradually and return the component labels for each cutoff.""" working_graph = gt.Graph(graph) weights = graph.edge_properties['weights'].get_array() max_weight = weights.max() results = [] for th in np.linspace(0, max_weight, num=n_split_threshold): cutoff(working_graph, th, inplace=True) results.append(tp.label_components(working_graph)) return results
def append_lattices(g, nLatte=20, latticeSize=[5, 5]): def isCorner(gLatte, node): if gLatte.vertex(node).out_degree() == 2: return True else: return False gLatte = add_in_graph(None, nLatte, generation.lattice, latticeSize) gLatte.vp["late"] = gLatte.new_vertex_property("short") gLatte.vp["late"].a = np.ones(gLatte.num_vertices()) gFinal = generation.graph_union(g, gLatte, internal_props=True) comp, hist = topology.label_components(gFinal) numOfCC = max(comp.a) assert (numOfCC == nLatte) bbNodes = set(np.where(gFinal.vp["bb"].a == 1)[0]) attached = set(np.where(gFinal.vp["attachments"].a == 1)[0]) freeBBnodes = bbNodes - attached if freeBBnodes < nLatte: warnings.warn( "Not enough free nodes in the erdos graph to attach all the lattices." ) return None freeBBnodes = list(freeBBnodes) np.random.shuffle(freeBBnodes) k = 0 for cc in range(1, numOfCC + 1): atNode = np.where(comp.a == cc)[0][0] assert (isCorner(gFinal, atNode) ) # The first node of a generation.lattice graph is a corner. gFinal.add_edge(atNode, freeBBnodes[k]) k += 1 gFinal.vp["attachments"].a[atNode] = 1 gFinal.vp["attachments"].a[freeBBnodes[k]] = 1 assert (topology.label_components(gFinal)[1][0] == gFinal.num_vertices() ) # gFinal must be Fully Connected. return gFinal
def process(self): input_kr: KgtkReader = KgtkReader.open( self.input_file_path, error_file=self.error_file, who="input", options=self.input_reader_options, value_options=self.value_options, verbose=self.verbose, very_verbose=self.very_verbose, ) input_key_columns: typing.List[int] = self.get_key_columns( input_kr, "input") label_col_idx = input_key_columns[1] label = '{}{}'.format('c', label_col_idx) g = load_graph_from_csv(str(input_kr.file_path), not (self.undirected), skip_first=not (self.no_header), hashed=True, csv_options={'delimiter': '\t'}, ecols=(input_key_columns[0], input_key_columns[2])) es = [] header = ['node1', 'label', 'node2'] if self.properties: properties = self.properties.split(',') for e in properties: es += (find_edge(g, g.edge_properties[label], e)) g.clear_edges() g.add_edge_list(list(set(es))) comp, hist = label_components(g, directed=self.strong) ew: KgtkWriter = KgtkWriter.open(header, self.output_file_path, mode=input_kr.mode, require_all_columns=False, prohibit_extra_columns=True, fill_missing_columns=True, gzip_in_parallel=False, verbose=self.verbose, very_verbose=self.very_verbose) for v, c in enumerate(comp): ew.write([ g.vertex_properties['name'][v], 'connected_component', str(c) ])
def connected_components(edges, num_nodes, _lib=None): """ Run connected components on the graph encoded by 'edges' and num_nodes. The graph vertex IDs must be CONSECUTIVE. Args: edges: ndarray, shape=(E,2), dtype=np.uint32 num_nodes: Integer, max_node+1. (Allows for graphs which contain nodes that are not referenced in 'edges'.) _lib: Do not use. (Used for testing.) Returns: ndarray of shape (num_nodes,), labeled by component index from 0..C Note: Uses graph-tool if it's installed; otherwise uses networkx (slower). """ if len(edges) == 0: # Corner case: No edges -- every node is a component. # Avoid errors in graph_tool with an empty edge list. return np.arange(num_nodes, dtype=np.uint32) if (graph_tool_available() or _lib == 'gt') and _lib != 'nx': import graph_tool as gt from graph_tool.topology import label_components g = gt.Graph(directed=False) g.add_vertex(num_nodes) g.add_edge_list(edges) cc_pmap, _hist = label_components(g) return cc_pmap.get_array() else: edges = np.asarray(edges, dtype=np.int64) g = nx.Graph() g.add_nodes_from(range(num_nodes)) g.add_edges_from(edges) cc_labels = np.zeros((num_nodes, ), np.uint32) for i, component_set in enumerate(nx.connected_components(g)): cc_labels[np.array(list(component_set))] = i return cc_labels
def facets_gt(mesh): ''' Returns lists of facets of a mesh. Facets are defined as groups of faces which are both adjacent and parallel facets returned reference indices in mesh.faces If return_area is True, both the list of facets and their area are returned. ''' face_idx = mesh.face_adjacency() normal_pairs = mesh.face_normals[[face_idx]] parallel = np.abs(np.sum(normal_pairs[:,0,:] * normal_pairs[:,1,:], axis=1) - 1) < TOL_PLANAR graph_parallel = GTGraph() graph_parallel.add_edge_list(face_idx[parallel]) connected = label_components(graph_parallel, directed=False)[0].a facets_idx = group(connected, min_length=2) return facets_idx
def clear_unconnected(g: gt.Graph, key_node) -> gt.Graph: # Get rid of any component that doesn't contain the key node. label_map, hist = gt_top.label_components(g, directed=False) zero_id = vp_map(g, 'zero_id', 'int') key_comps = set() for v in g.vertices(): if zero_id[v] == key_node: key_comps.add(label_map[v]) leave_prop = g.new_vertex_property('bool') for v in g.vertices(): leave_prop[v] = label_map[v] in key_comps sub = gt.GraphView(g, leave_prop) new_g = create_q_graph(sub, add_back_reference=False) return new_g
def is_connected(self, mode="strong"): ''' Return whether the graph is connected. Parameters ---------- mode : str, optional (default: "strong") Whether to test connectedness with directed ("strong") or undirected ("weak") connections. ''' from graph_tool.topology import label_components directed = True if mode == "strong" else False directed *= self._graph.is_directed() _, hist = label_components(self._graph, directed=directed) return len(hist) == 1
def split_gt(mesh, check_watertight=True, only_count=False): g = GTGraph() g.add_edge_list(mesh.face_adjacency()) component_labels = label_components(g, directed=False)[0].a if check_watertight: degree = g.degree_property_map('total').a meshes = deque() components = group(component_labels) if only_count: return len(components) for i, current in enumerate(components): fill_holes = False if check_watertight: degree_3 = degree[current] == 3 degree_2 = degree[current] == 2 if not degree_3.all(): if np.logical_or(degree_3, degree_2).all(): fill_holes = True else: continue # these faces have the original vertex indices faces_original = mesh.faces[current] face_normals = mesh.face_normals[current] # we find the unique vertex indices, so we can reindex from zero unique_vert = np.unique(faces_original) vertices = mesh.vertices[unique_vert] replacement = np.zeros(unique_vert.max()+1, dtype=np.int) replacement[unique_vert] = np.arange(len(unique_vert)) faces = replacement[faces_original] new_mesh = mesh.__class__(faces = faces, face_normals = face_normals, vertices = vertices) new_meta = deepcopy(mesh.metadata) if 'name' in new_meta: new_meta['name'] = new_meta['name'] + '_' + str(i) new_mesh.metadata.update(new_meta) if fill_holes: try: new_mesh.fill_holes(raise_watertight=True) except MeshError: continue meshes.append(new_mesh) return list(meshes)
def get_nuclearity_from_atoms(atoms, structure, actives): #Get surface nuclearity from given Atoms object slab_atoms = atoms.copy() #pick surface atoms bulk_atoms = AseAtomsAdaptor.get_atoms(structure) bulk_cn = find_bulk_cn_dict(bulk_atoms) surface_indices = find_surface_atoms_indices(bulk_cn, slab_atoms) #Generate connectivity matrix cutOff = natural_cutoffs(slab_atoms) neighborList = neighborlist.NeighborList(cutOff, self_interaction=False, bothways=True) neighborList.update(slab_atoms) connectivity_matrix = neighborList.get_connectivity_matrix() #Ignore connectivity with atoms which are not active or on the surface active_connectivity_matrix = connectivity_matrix.copy() active_list = [ atom.symbol in actives and atom.index in surface_indices for atom in slab_atoms ] if sum(active_list) == 0: # No active surface atoms! return {'max_nuclearity': 0, 'nuclearities': []} else: active_connectivity_matrix = active_connectivity_matrix[active_list, :] active_connectivity_matrix = active_connectivity_matrix[:, active_list] # Make a graph-tool graph from the adjacency matrix graph = gt.Graph(directed=False) for i in range(active_connectivity_matrix.shape[0]): graph.add_vertex() graph.add_edge_list(np.transpose(active_connectivity_matrix.nonzero())) labels, hist = topology.label_components(graph, directed=False) return {'max_nuclearity': np.max(hist), 'nuclearities': hist}
def is_arborescence(tree): # is tree? l, _ = label_components(GraphView(tree, directed=False)) if not np.all(np.array(l.a) == 0): print('not connected') print(np.array(l.a)) return False in_degs = np.array([v.in_degree() for v in tree.vertices()]) if in_degs.max() > 1: print('in_degree.max() > 1') return False if np.sum(in_degs == 1) != (tree.num_vertices() - 1): print('should be: only root has no parent') return False roots = get_roots(tree) assert len(roots) == 1, '>1 roots' return True
def connected_components(graph): """ Computes connected components of graph_tool graph :param graph: graph_tool.Graph :return: np.array of len == number of nodes """ assert isinstance(graph, graph_tool.Graph) cc_labels = topology.label_components(graph)[0].a if len(cc_labels) == 0: return [] idx_sort = np.argsort(cc_labels) vals, idx_start, count = np.unique(cc_labels[idx_sort], return_counts=True, return_index=True) res = np.split(idx_sort, idx_start[1:]) return res
def find_connected_component_label(index_filename, dependency_filename, output_file="dep_tree_cc_label"): graph = Graph() # Index start with 1 blueprint_index = read_blueprint_index(index_filename) # All dependency file should be like filename_*.xml filename_pattern = dependency_filename+"_*.xml" #filename_pattern = "blueprints.xml" filenames = glob.glob(filename_pattern) print filenames print len(blueprint_index) key, value = max(blueprint_index.iteritems(), key=lambda x:x[1]) print value graph.add_vertex(len(blueprint_index)+1) for filename in filenames: read_dependency(filename, blueprint_index, graph) cc_label = ['cc_label'] cc_hist = ['cc_hist'] comp, hist = topology.label_components(graph, directed=False) for i in range(1, len(blueprint_index)+1): cc_label.append(comp.a[i]) cc_hist.append(hist[comp.a[i]]) output_file += ".csv" with open(output_file, 'wb') as fp: writer = csv.writer(fp) for i in range(0, len(blueprint_index)+1): writer.writerow([cc_label[i], cc_hist[i]]) fp.close()
def _mapping_from_edges_gt(edges): """ Helper function for mapping_from_edges() Compute the connected components of the graph defined by 'edges', and return the mapping of segment ID -> body ID as an UNSORTED pandas.Series (where segment is the index). Note: This version uses graph-tool to compute the connected components, which is very fast. However, graph-tool is not installed by default due to licensing restrictions. """ from graph_tool.topology import label_components g = gt.Graph(directed=False) sv_pmap = g.add_edge_list(edges, hashed=True) cc_pmap, _hist = label_components(g) df = pd.DataFrame({ 'sv': sv_pmap.get_array(), 'cc_index': cc_pmap.get_array() }) # Convert component labels to body IDs (min segment ID in the component) cc_body_ids = df.groupby('cc_index').min() cc_body_ids.columns = ['body'] mapped_cc_df = df.merge(cc_body_ids, how='inner', left_on='cc_index', right_index=True, copy=False) mapping = pd.Series(index=mapped_cc_df['sv'].values.astype(edges.dtype), data=mapped_cc_df['body'].values.astype(edges.dtype)) mapping.name = 'body' mapping.index.name = 'sv' return mapping
def incremental_simulation(g, c, p, num_nodes, return_new_edges=False): """incrementally add edges to given cascade num_nodes is passed bacause vfilt might be passed """ # print('incremental_simulation -> g', g) gv = sample_graph_by_p(g, p) new_infected_nodes = set(infected_nodes(c)) comp = label_components(gv)[0] covered_cids = set() for v in infected_nodes(c): cid = comp[v] if cid not in covered_cids: new_infected_nodes |= set((comp.a == cid).nonzero()[0]) covered_cids.add(cid) new_c = np.ones(g.num_vertices()) * (-1) new_c[list(new_infected_nodes)] = 1 if return_new_edges: raise Exception("`return_new_edges` not supported anymore") else: return new_c
def components_graphtool(): """ Find connected components using graphtool """ g = GTGraph() # make sure all the nodes are in the graph g.add_vertex(node_count) # add the edge list g.add_edge_list(edges) labels = np.array(label_components(g, directed=False)[0].a, dtype=np.int64)[:node_count] # we have to remove results that contain nodes outside # of the specified node set and reindex contained = np.zeros(node_count, dtype=np.bool) contained[nodes] = True index = np.arange(node_count, dtype=np.int64)[contained] components = grouping.group(labels[contained], min_len=min_len) components = np.array([index[c] for c in components]) return components
def hide_disconnected_components(g, pivots): """ given a graph (might be disconnected) and some nodes (pivots) in it. hide the components in `g` in which no pivot is in **with side effect** """ prop = label_components(g)[0] v2c = {v: prop[v] for v in g.vertices()} c2vs = defaultdict(set) for v, c in v2c.items(): c2vs[c].add(v) vs_to_show = set() for v in pivots: vs_to_show |= c2vs[v2c[v]] vfilt = g.get_vertex_filter()[0] vfilt.set_value(False) for v in vs_to_show: vfilt[v] = True g.set_vertex_filter(vfilt)
def find_reservoirs(self) -> list[set[Cell]]: """Uses a graph approach to find how many wells are needed, making the assumption that only one well is needed per contiguous field locations: Set containing all locations with oil """ raise NotImplementedError import graph_tool as gt import graph_tool.topology as topology locations = {location: idx for idx, location in enumerate(self.cells)} locations_graph = gt.Graph() locations_graph.set_directed(False) locations_graph.add_vertex(len(locations)) locations_prop = locations_graph.new_vertex_property( "object", locations) edge_list = [] for location in locations: neighbor_coords = self.get_neighbors(location) edge_list.extend([(locations[location], locations[neighbor]) for neighbor in neighbor_coords]) locations_graph.add_edge_list(edge_list) components, _ = topology.label_components(locations_graph, directed=False) wells = dict() for vertex, label in enumerate(components.a): if label not in wells: wells[label] = [] wells[label].append(locations_prop[vertex]) return [set(well) for well in wells.values()]
def satisfy(self): """ Solves the 2-SAT instance using an implication graph. https://en.wikipedia.org/wiki/Implication_graph """ # for each clause in the form (u OR v), # add the edges (~u -> v) and (~v -> u) to G # 1 constraint => (x_1 or ~x_2)(~x_1 or x_2)(x_1 or x_2) for clause in self.clauses: u_t, u_f, v_t, v_f = self.clause_mapping[clause] self.g.add_edge(u_f, v_t) self.g.add_edge(v_f, u_t) self.g.add_edge(u_t, ) # find the reverse topological order reverse_topological_order = topo.topological_sort(self.g)[::-1] # find the strongly connected components # components[vertex] -> scc id components = topo.label_components(self.g)[0] # each component is marked either TRUE, or FALSE marked_components = {} for vertex in reverse_topological_order: scc = components[vertex] if scc not in marked_components: # if a variable and it's complement are members of the same scc, then # there is no satisfying assignment if components[self.vertex_complement[vertex]] is scc: return False # otherwise, mark the current scc as true marked_components[scc] = True # mark the scc containing the complement of the current variable as false marked_components[components[self.vertex_complement[vertex]]] = False self.vertex_assignment = {vertex: marked_components[components[vertex]] for vertex in self.g.vertices()} return True
count += 1 if count % 1000 == 0: print(count) print('Finished building graph') print('Total vertices: ' + str(citenet.num_vertices())) print('Total edges: ' + str(citenet.num_edges())) # Step 3: Drop the weakly connected components that don't include core set items print('Extracting core connected components') # `label_components` returns a property map: # `component_pmap[vertex]` returns the ID for the component containing vertex component_pmap = topo.label_components(citenet, directed = False)[0] # Extract a list with the distinct component IDs component_list = set(component_pmap[vertex] for vertex in list(citenet.vertices())) print(str(len(component_list)) + ' weakly connected components found') # Find the vertices from the core set core_vertices = [vertex for vertex in list(citenet.vertices()) if core[vertex]] print(str(len(core_vertices)) + ' core set members found') # Extract a list of the component IDs from the core set members core_components = {component_pmap[vertex] for vertex in core_vertices} print(str(len(core_components)) + ' components with core set members') print(core_components) # Construct a list of graphs, one for each core component citenets = [] for component in core_components:
def facets_gt(): graph_parallel = GTGraph() graph_parallel.add_edge_list(face_idx[parallel]) connected = label_components(graph_parallel, directed=False)[0].a facets_idx = group(connected, min_len=2) return facets_idx
# print(cutoff) # For autnets cutoff = 0 cutoff_pmap = core.copy() for i in range(cutoff): gt.infect_vertex_property(net, cutoff_pmap, vals = [True]) net.set_vertex_filter(cutoff_pmap) core_vertices = [vertex for vertex in net.vertices() if core[vertex]] print('cutoff v: ' + str(net.num_vertices())) print('cutoff core: ' + str(len(core_vertices))) print('Extracting core connected components') # `label_components` returns a property map: # `component_pmap[vertex]` returns the ID for the component containing vertex component_pmap = gtopo.label_components(net, directed = False)[0] # Extract a list with the distinct component IDs component_list = {component_pmap[vertex] for vertex in net.vertices()} print(str(len(component_list)) + ' weakly connected components found') # Extract a list of the component IDs from the core set members core_components = {component_pmap[vertex] for vertex in core_vertices} print(str(len(core_components)) + ' components with core set members') # Construct a list of graphs, one for each core component citenets = [] for component in core_components: net.set_vertex_filter(None) net.set_vertex_filter(cutoff_pmap) # Define a new pmap for component membership core_comp_pmap = net.new_vertex_property('bool', vals = [component_pmap[vertex] == component for vertex in net.vertices()]) # Use this to filter down to the component
def main(*args): helpText = ''' Read a given raw connectivity matrix file from a tractography and find the minimum spanning tree (MST). Save the MST to a numpy array with the given output name. Repeat the process a number of times on versions of the original connectivity matrix with noise added. Accumulate the scores for each edge, i.e. the number of times it is in the MST over all repetitions. Default number of repetitions = 100. Default noise value added drawn uniformly from zero to 5th percentile of distribution of differences between edge-weights. Intended for use with UNC AAL based regions in the tractography. ''' parser = argparse.ArgumentParser(description=helpText) # ,formatter_class=argparse.RawTextHelpFormatter) helpText = 'Connectivity matrix file, .raw or .npy format' parser.add_argument("filename", type=str, help=helpText) helpText = 'Output numpy array for MST' parser.add_argument('output', type=str, help=helpText) helpText = 'Repetitions on adding noise' parser.add_argument('-reps', type=int, help=helpText, default=100) helpText = 'noise level: (default) -1 -> estimate from data, 0 or higher, use given value' parser.add_argument('-noise', type=float, help=helpText, default=-1) helpText = 'Number of components: How many of the components of the graph to keep, starting with largest' parser.add_argument('-comps', type=int, help=helpText, default=1) args = parser.parse_args() filename = args.filename outputName = args.output nReps = args.reps width = args.noise compsRequired = args.comps if filename[-4:] == '.raw': # Raw format data = readRawData(filename, symmetric=True) elif filename[-4:] == '.npy': # Numpy array data = np.load(filename) G = matrixToGraph(data) # Expect 90 nodes, 8 of which are subcortical, these and other ones # may be disconnected. By default select the largest connected # component but may select further ones if we want to work with a # multi-component graph. comp, hist = label_components(G) vprop = G.new_vertex_property('bool') proparr = np.zeros((G.num_vertices(),), dtype='bool') print 'Selecting', compsRequired, 'components' compOrder = np.argsort(hist) for i in range(compsRequired): j = compOrder[-1-i] proparr[comp.a == j] = True vprop.a = proparr G.set_vertex_filter(vprop) nVertices = G.num_vertices() nEdges = G.num_edges() print '(nodes, edges) in selected component(s) : (' , nVertices, ', ', nEdges , ')' if width < 0: temp = np.tri(data.shape[0]) temp = temp * data temp = temp[temp > 0] nVals = temp.size # How many comparisons? Max 1 million. nComps = np.min([1000000, nVals * (nVals-1) / 2]) diffs = np.zeros(nComps) n = 0 i = 0 while (n < nComps) and (i < nVals-1): j = i + 1 while (n < nComps) and (j < nVals): diffs[n] = np.fabs( temp[i] - temp[j] ) n += 1 j += 1 i += 1 width = np.percentile(diffs, 5) print 'adding noise with width ', width print 'repeating ', nReps, ' times' # Invert the connection strengths so that smaller is better. I.e. a # MST has strong edges. propW = G.edge_properties['weight'] w = np.asarray(propW.a, dtype=np.float64) print 'Average (STD) of edge weights [nVertices-1 x average weight = expected tree weight] ', meanW = np.mean(w) stdW = np.std(w) eTreeWeight = meanW * float(nVertices - 1) print '{:0.3f} ({:0.3f}) [{:0.3f}]'.format(meanW, stdW, eTreeWeight) wMax = np.max(w) w2 = (0.1 * wMax) + (wMax - w) w2prop = G.new_edge_property('double') w2prop.a = w2 w2propNoise = G.new_edge_property('double') mstMat = np.zeros(data.shape) allWeights = np.zeros(nReps) for i in range(nReps): noiseVals = 2.0 * width * (np.random.rand(nEdges) - 0.5 ) w2propNoise.a = w2 + noiseVals mst = min_spanning_tree(G, weights=w2propNoise) treeW = 0.0 for e in G.edges(): if mst[e]: s,t = e.source(), e.target() treeW += propW[e] mstMat[s,t] += 1 allWeights[i] = treeW print 'Average (STD) of weights for MSTs = ', print '{:0.3f} ({:0.3f})'.format(np.mean(allWeights), np.std(allWeights)) np.save(outputName, mstMat)