@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; } });
private int[] findExtendedTetrahedralEnds(Graph g, int focus) { List<Edge> es = g.edges(focus); int prevEnd1 = focus; int prevEnd2 = focus; int end1 = es.get(0).other(prevEnd2); int end2 = es.get(1).other(prevEnd2); int tmp; while (end1 >= 0 && end2 >= 0) { tmp = getOtherDb(g, end1, prevEnd1); prevEnd1 = end1; end1 = tmp; tmp = getOtherDb(g, end2, prevEnd2); prevEnd2 = end2; end2 = tmp; } return new int[]{prevEnd1, prevEnd2}; }
private void visit(int u) { visited[u] = i++; for (Edge e : g.edges(u)) { int v = e.other(u); if (visited[v] < 0) { visit(v); } } } }
private List<Edge> doubleBondLabelledEdges(Graph g) { List<Edge> es = new ArrayList<Edge>(); for (int u = 0; u < g.order(); u++) { for (Edge e : g.edges(u)) { if (e.other(u) > u && e.bond() == Bond.DOUBLE) { es.add(e); } } } return es; }
private int getOtherDb(Graph g, int u, int v) { for (Edge e : g.edges(u)) { if (e.bond() != Bond.DOUBLE) continue; int nbr = e.other(u); if (nbr == v) continue; return nbr; } return -1; }
Edge firstDirectionalLabel(Graph g, int u) { Edge first = null; final int d = g.degree(u); for (int j = 0; j < d; ++j) { final Edge f = g.edgeAt(u, j); if (f.bond() == Bond.UP || f.bond() == Bond.DOWN) { if (first == null || ordering[f.other(u)] < ordering[first.other(u)]) first = f; } } return first; }
private void invertExistingDirectionalLabels(BitSet visited, int u) { visited.set(u); if (g.topologyOf(u) == null) return; for (Edge e : g.edges(u)) { int v = e.other(u); if (!visited.get(v)) { Edge f = replacement.get(e); if (f != null) { replacement.put(e, f.inverse()); } invertExistingDirectionalLabels(visited, v); } } }
private boolean hasAdjDirectionalLabels(Graph g, Edge e) { int u = e.either(); int v = e.other(u); return hasAdjDirectionalLabels(g, u) && hasAdjDirectionalLabels(g, v); }
/** * Given a double bond edge traverse the neighbors of both endpoints and * accumulate any explicit replacements in the 'acc' accumulator. * * @param g the chemical graph * @param e a edge in the graph ('double bond type') * @param acc accumulator for new edges * @throws uk.ac.ebi.beam.InvalidSmilesException * thrown if the edge could not be converted */ private void removeRedundant(Graph g, Edge e, int[] ordering, Map<Edge, Edge> acc) throws InvalidSmilesException { int u = e.either(), v = e.other(u); replaceImplWithExpl(g, e, u, ordering, acc); replaceImplWithExpl(g, e, v, ordering, acc); }
/** * Given a double bond edge traverse the neighbors of both endpoints and accumulate any explicit * replacements in the 'acc' accumulator. * * @param g the chemical graph * @param e a edge in the graph ('double bond type') * @param acc accumulator for new edges * @throws InvalidSmilesException thrown if the edge could not be converted */ private Status replaceImplWithExpl(Graph g, Edge e, Map<Edge, Edge> acc) throws InvalidSmilesException { int u = e.either(), v = e.other(u); Status ustat = replaceImplWithExpl(g, e, u, acc); Status vstat = replaceImplWithExpl(g, e, v, acc); if (ustat == vstat) return ustat; else if (ustat == Status.INVALID && vstat != Status.WAITING) return Status.INVALID; else if (vstat == Status.INVALID && ustat != Status.WAITING) return Status.INVALID; else return Status.WAITING; }
private void invertExistingDirectionalLabels(Graph g, BitSet visited, Map<Edge, Edge> replacement, int u) { visited.set(u); if (g.topologyOf(u) == null) return; for (Edge e : g.edges(u)) { int v = e.other(u); if (!visited.get(v)) { Edge f = replacement.get(e); if (f != null && f.bond().directional()) { replacement.put(e, f.inverse()); } else if (e.bond().directional()) { replacement.put(e, e.inverse()); } invertExistingDirectionalLabels(g, visited, replacement, v); } } }
private IStereoElement newExtendedTetrahedral(int u, Graph g, IAtom[] atoms) { int[] terminals = findExtendedTetrahedralEnds(g, u); int[] xs = new int[]{-1, terminals[0], -1, terminals[1]}; int n = 0; for (Edge e : g.edges(terminals[0])) { if (e.bond().order() == 1) xs[n++] = e.other(terminals[0]); } n = 2; for (Edge e : g.edges(terminals[1])) { if (e.bond().order() == 1) xs[n++] = e.other(terminals[1]); } Arrays.sort(xs); Stereo stereo = g.configurationOf(u).shorthand() == Configuration.CLOCKWISE ? Stereo.CLOCKWISE : Stereo.ANTI_CLOCKWISE; return new org.openscience.cdk.stereo.ExtendedTetrahedral(atoms[u], new IAtom[]{atoms[xs[0]], atoms[xs[1]], atoms[xs[2]], atoms[xs[3]]}, stereo); }
/** * Given a chemical graph and an edge in that graph, return the explicit * form of that edge. Neither the graph or the edge is modified, if the edge * is already explicit then 'e' is returned. * * @param g chemical graph * @param e an edge of g * @return the edge with specified explicit bond type */ static Edge toExplicitEdge(final Graph g, final Edge e) { final int u = e.either(), v = e.other(u); if (e.bond() == Bond.IMPLICIT) { return new Edge(u, v, type(g.atom(u), g.atom(v))); } return e; }
boolean safeToClean(Graph g, int v, Map<Edge,Edge> replacements) { final int d = g.degree(v); for (int j = 0; j < d; ++j) { final Edge e = g.edgeAt(v, j); if (e.bond().order() == 2) { int w = e.other(v); final int d2 = g.degree(w); for (int j2 = 0; j2 < d2; ++j2) { final Edge f = g.edgeAt(w, j2); if (isDirectional(f, replacements)) return false; } } } return true; }
/** * Given a chemical graph and an edge in that graph, return the implicit * form of that edge. Neither the graph or the edge is modified, if the edge * is already explicit then 'e' is returned. * * @param g chemical graph * @param e an edge of g * @return the edge with specified explicit bond type */ static Edge toImplicitEdge(final Graph g, final Edge e) { final int u = e.either(), v = e.other(u); if (e.bond() == Bond.SINGLE || e.bond() == Bond.AROMATIC) { return new Edge(u, v, type(g.atom(u), g.atom(v), e.bond())); } return e; }
private static void traverse(State s, int idx) { s.visit[idx] = true; int mapIdx = s.g.atom(idx).atomClass(); if (mapIdx != 0) { if (s.map[mapIdx] == 0) s.map[mapIdx] = ++s.nMaps; mapIdx = s.map[mapIdx]; s.g.setAtom(idx, AtomBuilder.fromExisting(s.g.atom(idx)).atomClass(mapIdx).build()); } for (Edge e : s.g.edges(idx)) { int nbr = e.other(idx); if (!s.visit[nbr]) traverse(s, nbr); } }
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); } } }
/** * Transform all explicit to implicit bonds. The original graph is * unmodified. * * @param g a chemical graph * @return new chemical graph but with all explicit bonds */ public Graph apply(final Graph g) { Graph h = new Graph(g.order()); // atom/topology information doesn't change for (int u = 0; u < g.order(); u++) { h.addAtom(g.atom(u)); h.addTopology(g.topologyOf(u)); } // transform edges for (int u = 0; u < g.order(); u++) { for (final Edge e : g.edges(u)) { if (e.other(u) > u) h.addEdge(toImplicitEdge(g, e)); } } return h; }
/** * Transform all implicit to explicit bonds. The original graph is * unmodified * * @param g a chemical graph * @return new chemical graph but with all explicit bonds */ public Graph apply(final Graph g) { Graph h = new Graph(g.order()); // copy atom/topology information for (int u = 0; u < g.order(); u++) { h.addAtom(g.atom(u)); h.addTopology(g.topologyOf(u)); } // apply edges for (int u = 0; u < g.order(); u++) { for (final Edge e : g.edges(u)) { if (e.other(u) > u) h.addEdge(toExplicitEdge(g, e)); } } return h; }