private Traversal(Graph g) { this.g = g; this.visited = new boolean[g.order()]; this.ordering = new int[g.order()]; BitSet dbAtoms = new BitSet(); for (int u = 0; u < g.order(); u++) { if (!visited[u]) dbAtoms.or(visit(u, u)); } Collections.sort(doubleBonds, new Comparator<Edge>() { @Override public int compare(Edge e, Edge f) { int u1 = e.either(); int v1 = e.other(u1); int u2 = f.either(); int v2 = f.other(u2); int min1 = Math.min(ordering[u1], ordering[v1]); int min2 = Math.min(ordering[u2], ordering[v2]); int cmp = min1 - min2; if (cmp != 0) return cmp; int max1 = Math.max(ordering[u1], ordering[v1]); int max2 = Math.max(ordering[u2], ordering[v2]); return max1 - max2; } }); for (Edge e : doubleBonds) { if (acc.containsKey(e)) continue; flip(g, e, dbAtoms); } }
if (v == p) continue; if (e.bond().order() == 2 && hasAdjDirectionalLabels(g, e)) { dbAtoms.or(visit(u, v));
private void flip(Edge first, int u, BitSet dbAtoms) { if (ordering[first.other(u)] < ordering[u]) { if (first.bond(u) == Bond.UP) invertExistingDirectionalLabels(g, u, new BitSet(), u); else markExistingDirectionalLabels(g, u, new BitSet(), invertExistingDirectionalLabels(g, u, new BitSet(), u); else markExistingDirectionalLabels(g, u, new BitSet(),
private void markExistingDirectionalLabels(Graph g, int prev, BitSet visited, Map<Edge, Edge> replacement, BitSet dbAtoms, int u) { visited.set(u); final int d = g.degree(u); for (int j = 0; j < d; ++j) { final Edge e = g.edgeAt(u, j); int v = e.other(u); if (v == prev) continue; Edge f = replacement.get(e); if (f == null) { replacement.put(e, e); if (!visited.get(v)) { if (dbAtoms.get(v)) markExistingDirectionalLabels(g, u, visited, replacement, dbAtoms, v); } } } } }
private void invertExistingDirectionalLabels(Graph g, int prev, BitSet visited, Map<Edge, Edge> replacement, BitSet dbAtoms, int u) { visited.set(u); final int d = g.degree(u); for (int j = 0; j < d; ++j) { final Edge e = g.edgeAt(u, j); int v = e.other(u); if (v == prev) continue; Edge f = replacement.get(e); if (f == null) { replacement.put(e, e.inverse()); if (!visited.get(v)) { if (dbAtoms.get(v)) invertExistingDirectionalLabels(g, u, visited, replacement, dbAtoms, v); } } } }
@Override public Graph apply(Graph g) { Traversal traversal = new Traversal(g); Graph h = new Graph(g.order()); h.addFlags(g.getFlags(0xffffffff)); // copy atom/topology information this is unchanged for (int u = 0; u < g.order(); u++) { h.addAtom(g.atom(u)); h.addTopology(g.topologyOf(u)); } // change edges (only changed added to replacement) for (int u = 0; u < g.order(); u++) { final int d = g.degree(u); for (int j = 0; j < d; ++j) { final Edge e = g.edgeAt(u, j); if (e.other(u) > u) { if (traversal.acc.containsKey(e)) { h.addEdge(traversal.acc.get(e)); } else { h.addEdge(e); } } } } return h.sort(new Graph.CanOrderFirst()); }
private void flip(Graph g, Edge e, BitSet dbAtoms) { int u = e.either(); int v = e.other(u); if (ordering[u] < ordering[v]) { Edge first = firstDirectionalLabel(g, u); if (first != null) { flip(first, u, dbAtoms); } else { first = firstDirectionalLabel(g, v); flip(first, v, dbAtoms); } } else { Edge first = firstDirectionalLabel(g, v); if (first != null) { flip(first, v, dbAtoms); } else { first = firstDirectionalLabel(g, u); flip(first, u, dbAtoms); } } }
private boolean hasAdjDirectionalLabels(Graph g, Edge e) { int u = e.either(); int v = e.other(u); return hasAdjDirectionalLabels(g, u) && hasAdjDirectionalLabels(g, v); }