Topology { static Configuration toExplicit(Graph g, int u, Configuration c) { if (c.type() != Implicit) return c; int deg = g.degree(u); int valence = deg + g.atom(u).hydrogens(); if (valence == 4) { return c == ANTI_CLOCKWISE ? TH1 : TH2; } else if (valence == 3) { if (g.atom(u).element() == Element.Sulfur || g.atom(u).element() == Element.Selenium) { int sb = 0, db = 0; final int d = g.degree(u); for (int j=0; j<d; ++j) { final Edge e = g.edgeAt(u, j); if (e.bond().order() == 1) sb++; else if (e.bond().order() == 2) db++; else return Configuration.UNKNOWN; } int q = g.atom(u).charge(); if ((q == 0 && sb == 2 && db == 1) || (q == 1 && sb == 3)) return c == ANTI_CLOCKWISE ? TH1 : TH2; else return Configuration.UNKNOWN; } if (g.atom(u).element() == Element.Phosphorus || g.atom(u).element() == Element.Nitrogen) { if (g.bondedValence(u) == 3 && g.implHCount(u) == 0 && g.atom(u).charge() == 0) { return c == ANTI_CLOCKWISE ? TH1 : TH2; } } int nDoubleBonds = 0; final int d = g.degree(u); for (int j=0; j<d; ++j) { final Edge e = g.edgeAt(u, j); if (e.bond() == Bond.DOUBLE) nDoubleBonds++; } if (nDoubleBonds == 1) { return c == ANTI_CLOCKWISE ? DB1 : DB2; } else { return Configuration.UNKNOWN; } } else if (deg == 2) { int nDoubleBonds = 0; final int d = g.degree(u); for (int j = 0; j < d; ++j) { final Edge e = g.edgeAt(u, j); if (e.bond() != Bond.DOUBLE) nDoubleBonds++; } if (nDoubleBonds == 1) { return c == ANTI_CLOCKWISE ? DB1 : DB2; } else { return c == ANTI_CLOCKWISE ? AL1 : AL2; } } else if (valence == 5) { return c == ANTI_CLOCKWISE ? TB1 : TB2; } else if (valence == 6) { return c == ANTI_CLOCKWISE ? OH1 : OH2; } return Configuration.UNKNOWN; }    }
@Test public void implicitToExplicit_tetrahedral() { Graph g = new Graph(7); g.addAtom(AtomImpl.AliphaticSubset.Nitrogen); g.addAtom(new AtomImpl.BracketAtom(Element.Carbon, 0, 0)); g.addAtom(AtomImpl.EXPLICIT_HYDROGEN); g.addAtom(AtomImpl.AliphaticSubset.Carbon); g.addAtom(AtomImpl.AliphaticSubset.Carbon); g.addAtom(AtomImpl.AliphaticSubset.Oxygen); g.addAtom(AtomImpl.AliphaticSubset.Oxygen); g.addEdge(new Edge(0, 1, Bond.IMPLICIT)); g.addEdge(new Edge(1, 2, Bond.IMPLICIT)); g.addEdge(new Edge(1, 3, Bond.IMPLICIT)); g.addEdge(new Edge(1, 4, Bond.IMPLICIT)); g.addEdge(new Edge(4, 5, Bond.DOUBLE)); g.addEdge(new Edge(4, 6, Bond.IMPLICIT)); assertThat(Topology.toExplicit(g, 1, ANTI_CLOCKWISE), is(TH1)); assertThat(Topology.toExplicit(g, 1, CLOCKWISE), is(TH2)); }
@Test public void implicitToExplicit_tetrahedralImplicitH() { Graph g = new Graph(7); g.addAtom(AtomImpl.AliphaticSubset.Nitrogen); g.addAtom(new AtomImpl.BracketAtom(Element.Carbon, 1, 0)); g.addAtom(AtomImpl.AliphaticSubset.Carbon); g.addAtom(AtomImpl.AliphaticSubset.Carbon); g.addAtom(AtomImpl.AliphaticSubset.Oxygen); g.addAtom(AtomImpl.AliphaticSubset.Oxygen); g.addEdge(new Edge(0, 1, Bond.IMPLICIT)); g.addEdge(new Edge(1, 2, Bond.IMPLICIT)); g.addEdge(new Edge(1, 3, Bond.IMPLICIT)); g.addEdge(new Edge(3, 4, Bond.DOUBLE)); g.addEdge(new Edge(3, 5, Bond.IMPLICIT)); assertThat(Topology.toExplicit(g, 1, ANTI_CLOCKWISE), is(TH1)); assertThat(Topology.toExplicit(g, 1, CLOCKWISE), is(TH2)); }
@Test public void implicitToExplicit_sulfoxide() { Graph g = new Graph(5); g.addAtom(AtomImpl.AliphaticSubset.Carbon); g.addAtom(new AtomImpl.BracketAtom(Element.Sulfur, 0, 0)); g.addAtom(AtomImpl.AliphaticSubset.Carbon); g.addAtom(AtomImpl.AliphaticSubset.Carbon); g.addAtom(AtomImpl.AliphaticSubset.Oxygen); g.addEdge(new Edge(0, 1, Bond.IMPLICIT)); g.addEdge(new Edge(1, 2, Bond.IMPLICIT)); g.addEdge(new Edge(1, 4, Bond.DOUBLE)); g.addEdge(new Edge(2, 3, Bond.IMPLICIT)); assertThat(Topology.toExplicit(g, 1, ANTI_CLOCKWISE), is(TH1)); assertThat(Topology.toExplicit(g, 1, CLOCKWISE), is(TH2)); }
@Test public void implicitToExplicit_phosphorus() throws Exception { Graph g = new Graph(5); g.addAtom(AtomImpl.AliphaticSubset.Carbon); g.addAtom(new AtomImpl.BracketAtom(Element.Phosphorus, 0, 0)); g.addAtom(AtomImpl.AliphaticSubset.Carbon); g.addAtom(AtomImpl.AliphaticSubset.Carbon); g.addAtom(AtomImpl.AliphaticSubset.Oxygen); g.addEdge(new Edge(0, 1, Bond.IMPLICIT)); g.addEdge(new Edge(1, 2, Bond.IMPLICIT)); g.addEdge(new Edge(1, 4, Bond.IMPLICIT)); g.addEdge(new Edge(2, 3, Bond.IMPLICIT)); assertThat(Topology.toExplicit(g, 1, ANTI_CLOCKWISE), is(TH1)); assertThat(Topology.toExplicit(g, 1, CLOCKWISE), is(TH2)); }
@Test public void implicitToExplicit_allene() { Graph g = new Graph(7); g.addAtom(AtomImpl.AliphaticSubset.Oxygen); g.addAtom(AtomImpl.AliphaticSubset.Carbon); g.addAtom(AtomImpl.AliphaticSubset.Chlorine); g.addAtom(new AtomImpl.BracketAtom(Element.Carbon, 0, 0)); g.addAtom(AtomImpl.AliphaticSubset.Carbon); g.addAtom(AtomImpl.AliphaticSubset.Carbon); g.addAtom(AtomImpl.AliphaticSubset.Fluorine); g.addEdge(new Edge(0, 1, Bond.IMPLICIT)); g.addEdge(new Edge(1, 2, Bond.IMPLICIT)); g.addEdge(new Edge(1, 3, Bond.DOUBLE)); g.addEdge(new Edge(3, 4, Bond.DOUBLE)); g.addEdge(new Edge(4, 5, Bond.IMPLICIT)); g.addEdge(new Edge(5, 6, Bond.IMPLICIT)); assertThat(Topology.toExplicit(g, 3, ANTI_CLOCKWISE), is(AL1)); assertThat(Topology.toExplicit(g, 3, CLOCKWISE), is(AL2)); }
@Test public void implicitToExplicit_trigonalBipyramidal() { Graph g = new Graph(7); g.addAtom(AtomImpl.AliphaticSubset.Oxygen); g.addAtom(AtomImpl.AliphaticSubset.Carbon); g.addAtom(new AtomImpl.BracketAtom(Element.Arsenic, 0, 0)); g.addAtom(AtomImpl.AliphaticSubset.Fluorine); g.addAtom(AtomImpl.AliphaticSubset.Chlorine); g.addAtom(AtomImpl.AliphaticSubset.Bromine); g.addAtom(AtomImpl.AliphaticSubset.Sulfur); g.addEdge(new Edge(0, 1, Bond.DOUBLE)); g.addEdge(new Edge(1, 2, Bond.IMPLICIT)); g.addEdge(new Edge(2, 3, Bond.IMPLICIT)); g.addEdge(new Edge(2, 4, Bond.IMPLICIT)); g.addEdge(new Edge(2, 5, Bond.IMPLICIT)); g.addEdge(new Edge(2, 6, Bond.IMPLICIT)); assertThat(Topology.toExplicit(g, 2, ANTI_CLOCKWISE), is(Configuration.TB1)); assertThat(Topology.toExplicit(g, 2, CLOCKWISE), is(Configuration.TB2)); }
@Test public void implicitToExplicit_octahedral() { Graph g = new Graph(8); g.addAtom(AtomImpl.AliphaticSubset.Sulfur); g.addAtom(new AtomImpl.BracketAtom(Element.Cobalt, 0, 0)); g.addAtom(AtomImpl.AliphaticSubset.Fluorine); g.addAtom(AtomImpl.AliphaticSubset.Chlorine); g.addAtom(AtomImpl.AliphaticSubset.Bromine); g.addAtom(AtomImpl.AliphaticSubset.Iodine); g.addAtom(AtomImpl.AliphaticSubset.Carbon); g.addAtom(AtomImpl.AliphaticSubset.Oxygen); g.addEdge(new Edge(0, 1, Bond.IMPLICIT)); g.addEdge(new Edge(1, 2, Bond.IMPLICIT)); g.addEdge(new Edge(1, 3, Bond.IMPLICIT)); g.addEdge(new Edge(1, 4, Bond.IMPLICIT)); g.addEdge(new Edge(1, 5, Bond.IMPLICIT)); g.addEdge(new Edge(1, 6, Bond.IMPLICIT)); g.addEdge(new Edge(6, 7, Bond.DOUBLE)); assertThat(Topology.toExplicit(g, 1, ANTI_CLOCKWISE), is(Configuration.OH1)); assertThat(Topology.toExplicit(g, 1, CLOCKWISE), is(Configuration.OH2)); }
@Test public void implicitToExplicit_unknown() { assertThat(Topology.toExplicit(new Graph(0), 0, Configuration.UNKNOWN), is(Configuration.UNKNOWN)); }
@Test public void implicitToExplicit_th1_th2() { assertThat(Topology.toExplicit(new Graph(0), 0, Configuration.TH1), is(Configuration.TH1)); assertThat(Topology.toExplicit(new Graph(0), 0, Configuration.TH2), is(Configuration.TH2)); }
@Test public void implicitToExplicit_al1_al2() { assertThat(Topology.toExplicit(new Graph(0), 0, Configuration.AL1), is(Configuration.AL1)); assertThat(Topology.toExplicit(new Graph(0), 0, Configuration.AL2), is(Configuration.AL2)); }