public void TestAccept_NoSubstituents() { var m_atom = new Mock <IAtom>(); var atom = m_atom.Object; var m_a = new Mock <IBond>(); var a = m_a.Object; var bonds = new[] { a }; m_atom.SetupGet(n => n.Hybridization).Returns(Hybridization.SP2); m_a.SetupGet(n => n.Order).Returns(BondOrder.Double); Assert.IsFalse(GeometricDoubleBondEncoderFactory.Accept(atom, bonds)); }
public void TestAccept_CumulatedDoubleBond() { var m_atom = new Mock <IAtom>(); var atom = m_atom.Object; var m_a = new Mock <IBond>(); var a = m_a.Object; var m_b = new Mock <IBond>(); var b = m_b.Object; var m_c = new Mock <IBond>(); var c = m_c.Object; var bonds = new[] { a, b, c }; m_atom.SetupGet(n => n.Hybridization).Returns(Hybridization.SP2); m_a.SetupGet(n => n.Order).Returns(BondOrder.Double); Assert.IsTrue(GeometricDoubleBondEncoderFactory.Accept(atom, bonds)); m_b.SetupGet(n => n.Order).Returns(BondOrder.Double); Assert.IsFalse(GeometricDoubleBondEncoderFactory.Accept(atom, bonds)); }
public void TestCreate() { var m_mol = new Mock <IAtomContainer>(); var mol = m_mol.Object; // a d 0 3 // \ / \ / // b = c 1 = 2 // / \ / \ // e f 4 5 var m_a = new Mock <IAtom>(); var a = m_a.Object; // 0 var m_b = new Mock <IAtom>(); var b = m_b.Object; // 1 var m_c = new Mock <IAtom>(); var c = m_c.Object; // 2 var m_d = new Mock <IAtom>(); var d = m_d.Object; // 3 var m_e = new Mock <IAtom>(); var e = m_e.Object; // 4 var m_f = new Mock <IAtom>(); var f = m_f.Object; // 5 m_mol.Setup(n => n.Atoms.IndexOf(a)).Returns(0); m_mol.Setup(n => n.Atoms.IndexOf(b)).Returns(1); m_mol.Setup(n => n.Atoms.IndexOf(c)).Returns(2); m_mol.Setup(n => n.Atoms.IndexOf(d)).Returns(3); m_mol.Setup(n => n.Atoms.IndexOf(e)).Returns(4); m_mol.Setup(n => n.Atoms.IndexOf(f)).Returns(5); m_mol.Setup(n => n.Atoms[0]).Returns(a); m_mol.Setup(n => n.Atoms[1]).Returns(b); m_mol.Setup(n => n.Atoms[2]).Returns(c); m_mol.Setup(n => n.Atoms[3]).Returns(d); m_mol.Setup(n => n.Atoms[4]).Returns(e); m_mol.Setup(n => n.Atoms[5]).Returns(f); m_b.SetupGet(n => n.Hybridization).Returns(Hybridization.SP2); m_c.SetupGet(n => n.Hybridization).Returns(Hybridization.SP2); m_a.SetupGet(n => n.Point2D).Returns(new Vector2()); m_b.SetupGet(n => n.Point2D).Returns(new Vector2()); m_c.SetupGet(n => n.Point2D).Returns(new Vector2()); m_d.SetupGet(n => n.Point2D).Returns(new Vector2()); m_e.SetupGet(n => n.Point2D).Returns(new Vector2()); m_f.SetupGet(n => n.Point2D).Returns(new Vector2()); var m_ba = new Mock <IBond>(); var ba = m_ba.Object; var m_be = new Mock <IBond>(); var be = m_be.Object; var m_bc = new Mock <IBond>(); var bc = m_bc.Object; var m_cd = new Mock <IBond>(); var cd = m_cd.Object; var m_cf = new Mock <IBond>(); var cf = m_cf.Object; m_ba.SetupGet(n => n.Begin).Returns(b); m_ba.SetupGet(n => n.End).Returns(a); m_be.SetupGet(n => n.Begin).Returns(b); m_be.SetupGet(n => n.End).Returns(e); m_bc.SetupGet(n => n.Begin).Returns(b); m_bc.SetupGet(n => n.End).Returns(c); m_cd.SetupGet(n => n.Begin).Returns(c); m_cd.SetupGet(n => n.End).Returns(d); m_cf.SetupGet(n => n.Begin).Returns(c); m_cf.SetupGet(n => n.End).Returns(f); m_bc.SetupGet(n => n.Order).Returns(BondOrder.Double); var bonds = new[] { ba, be, bc, cd, cf }; m_mol.SetupGet(n => n.Bonds).Returns(bonds); m_mol.Setup(n => n.GetConnectedBonds(a)).Returns(new[] { ba }); m_mol.Setup(n => n.GetConnectedBonds(b)).Returns(new[] { ba, bc, be }); m_mol.Setup(n => n.GetConnectedBonds(c)).Returns(new[] { bc, cd, cf }); m_mol.Setup(n => n.GetConnectedBonds(d)).Returns(new[] { cd }); m_mol.Setup(n => n.GetConnectedBonds(e)).Returns(new[] { be }); m_mol.Setup(n => n.GetConnectedBonds(f)).Returns(new[] { cf }); var factory = new GeometricDoubleBondEncoderFactory(); int[][] g = new int[][] { new[] { 1 }, new[] { 0, 2, 4 }, new[] { 1, 3, 5 }, new[] { 2 }, new[] { 1 }, new[] { 2 } }; Assert.IsTrue(factory.Create(mol, g) is MultiStereoEncoder); }
/// <summary> /// Create a stereo encoder for cumulative double bonds. /// </summary> /// <param name="container">the container</param> /// <param name="graph">adjacency list representation of the container</param> /// <returns>a stereo encoder</returns> public IStereoEncoder Create(IAtomContainer container, int[][] graph) { int n = container.Atoms.Count; BondMap map = new BondMap(n); var encoders = new List <IStereoEncoder>(1); // index double bonds by their atoms foreach (var bond in container.Bonds) { if (IsDoubleBond(bond)) { map.Add(bond); } } var visited = new HashSet <IAtom>(); // find atoms which are connected between two double bonds foreach (var a in map.Atoms) { var bonds = map.bonds[a]; if (bonds.Count == 2) { // (s)tart/(e)nd of cumulated system: -s=a=e- IAtom s = bonds[0].GetOther(a); IAtom e = bonds[1].GetOther(a); // need the parents to re-use the double bond encoder IAtom sParent = a; IAtom eParent = a; visited.Add(a); visited.Add(s); visited.Add(e); int size = 2; // expand out from 'l' while (s != null && map.Cumulated(s)) { IAtom p = map.bonds[s][0].GetOther(s); IAtom q = map.bonds[s][1].GetOther(s); sParent = s; s = visited.Add(p) ? p : visited.Add(q) ? q : null; size++; } // expand from 'r' while (e != null && map.Cumulated(e)) { IAtom p = map.bonds[e][0].GetOther(e); IAtom q = map.bonds[e][1].GetOther(e); eParent = e; e = visited.Add(p) ? p : visited.Add(q) ? q : null; size++; } // s and e are null if we had a cumulative cycle... if (s != null && e != null) { // system has now be expanded, size is the number of double // bonds. For odd numbers we use E/Z whilst for even are // axial M/P. // \ / // s = = = = e // / \ if (IsOdd(size)) { IStereoEncoder encoder = GeometricDoubleBondEncoderFactory.NewEncoder(container, s, sParent, e, eParent, graph); if (encoder != null) { encoders.Add(encoder); } } else { IStereoEncoder encoder = AxialEncoder(container, s, e); if (encoder != null) { encoders.Add(encoder); } } } } } return(encoders.Count == 0 ? StereoEncoder.Empty : new MultiStereoEncoder(encoders)); }