コード例 #1
0
        public void TestGeometric_3D()
        {
            var m_l = new Mock <IAtom>(); var l = m_l.Object;    // 0
            var m_r = new Mock <IAtom>(); var r = m_r.Object;    // 1
            var m_l1 = new Mock <IAtom>(); var l1 = m_l1.Object; // 2
            var m_l2 = new Mock <IAtom>(); var l2 = m_l2.Object; // 3
            var m_r1 = new Mock <IAtom>(); var r1 = m_r1.Object; // 4
            var m_r2 = new Mock <IAtom>(); var r2 = m_r2.Object; // 5

            var m_m = new Mock <IAtomContainer>(); var m = m_m.Object;

            m_m.SetupGet(n => n.Atoms[0]).Returns(l);
            m_m.SetupGet(n => n.Atoms[1]).Returns(r);
            m_m.SetupGet(n => n.Atoms[2]).Returns(l1);
            m_m.SetupGet(n => n.Atoms[3]).Returns(l2);
            m_m.SetupGet(n => n.Atoms[4]).Returns(r1);
            m_m.SetupGet(n => n.Atoms[5]).Returns(r2);

            m_l.SetupGet(n => n.Point3D).Returns(new Vector3());
            m_r.SetupGet(n => n.Point3D).Returns(new Vector3());
            m_l1.SetupGet(n => n.Point3D).Returns(new Vector3());
            m_l2.SetupGet(n => n.Point3D).Returns(new Vector3());
            m_r1.SetupGet(n => n.Point3D).Returns(new Vector3());
            m_r2.SetupGet(n => n.Point3D).Returns(new Vector3());

            GeometricParity p = Geometric(m, 0, 1, 2, 3, 4, 5);

            Assert.IsTrue(p is DoubleBond3DParity);
        }
コード例 #2
0
        public void TestCreate_2D_Implicit()
        {
            var m_container = new Mock <IAtomContainer>(); var container = m_container.Object;

            m_container.SetupGet(n => n.Atoms.Count).Returns(4);

            var m_c1 = new Mock <IAtom>(); var c1 = m_c1.Object;
            var m_o2 = new Mock <IAtom>(); var o2 = m_o2.Object;
            var m_n3 = new Mock <IAtom>(); var n3 = m_n3.Object;
            var m_c4 = new Mock <IAtom>(); var c4 = m_c4.Object;

            m_container.SetupGet(n => n.Atoms[0]).Returns(c1);
            m_container.SetupGet(n => n.Atoms[1]).Returns(o2);
            m_container.SetupGet(n => n.Atoms[2]).Returns(n3);
            m_container.SetupGet(n => n.Atoms[3]).Returns(c4);

            Vector2 p1 = new Vector2(1.23, -0.29);
            Vector2 p2 = new Vector2(-0.30, -0.29);
            Vector2 p3 = new Vector2(2.00, -1.63);
            Vector2 p4 = new Vector2(2.00, 1.03);

            m_c1.SetupGet(n => n.Point2D).Returns(p1);
            m_o2.SetupGet(n => n.Point2D).Returns(p2);
            m_n3.SetupGet(n => n.Point2D).Returns(p3);
            m_c4.SetupGet(n => n.Point2D).Returns(p4);

            var m_c1c4 = new Mock <IBond>(); var c1c4 = m_c1c4.Object;
            var m_c1o2 = new Mock <IBond>(); var c1o2 = m_c1o2.Object;
            var m_c1n3 = new Mock <IBond>(); var c1n3 = m_c1n3.Object;
            var m_c1h5 = new Mock <IBond>(); var c1h5 = m_c1h5.Object;

            int[][] graph = new int[][] { new[] { 1, 2, 3 }, new[] { 0 }, new[] { 0 }, new[] { 0 }, };

            m_container.Setup(n => n.GetConnectedBonds(c1)).Returns(new[] { c1c4, c1o2, c1n3 });

            // let's say c1 is a chiral carbon
            m_c1.SetupGet(n => n.Hybridization).Returns(Hybridization.SP3);
            // with a hatch bond from c1 to n3
            m_c1n3.SetupGet(n => n.Stereo).Returns(BondStereo.Down);
            m_c1n3.SetupGet(n => n.Begin).Returns(c1);
            m_c1n3.SetupGet(n => n.End).Returns(n3);
            m_c1o2.SetupGet(n => n.Stereo).Returns(BondStereo.None);
            m_c1o2.SetupGet(n => n.Begin).Returns(c1);
            m_c1o2.SetupGet(n => n.End).Returns(o2);
            m_c1c4.SetupGet(n => n.Stereo).Returns(BondStereo.None);
            m_c1c4.SetupGet(n => n.Begin).Returns(c1);
            m_c1c4.SetupGet(n => n.End).Returns(c4);

            IStereoEncoder encoder = new GeometricTetrahedralEncoderFactory().Create(container, graph);

            Assert.AreEqual(1, ExtractEncoders(encoder).Count);

            GeometricParity geometricParity = GetGeometricParity(ExtractEncoders(encoder)[0]);

            Assert.IsTrue(geometricParity is Tetrahedral2DParity);

            Assert.IsTrue(Compares.AreDeepEqual(
                              new Vector2[] { p2, p3, p4, p1 // p1 is from central atom
                              }, Coords2D(geometricParity)));
        }
コード例 #3
0
        public void ValueOf()
        {
            GeometricParity odd  = GeometricParity.ValueOf(-1);
            GeometricParity even = GeometricParity.ValueOf(1);

            Assert.AreEqual(-1, odd.Parity);
            Assert.AreEqual(+1, even.Parity);
        }
コード例 #4
0
 /// <summary>
 /// Create a new encoder for multiple stereo centres (specified as an array).
 /// </summary>
 /// <param name="centres">the stereo centres which will be configured</param>
 /// <param name="permutation">calculator for permutation parity</param>
 /// <param name="geometric">geometric calculator</param>
 /// <exception cref="ArgumentException">if the centres[] were empty</exception>
 public GeometryEncoder(int[] centres, PermutationParity permutation, GeometricParity geometric)
 {
     if (centres.Length == 0)
     {
         throw new ArgumentException("no centres[] provided");
     }
     this.permutation = permutation;
     this.geometric   = geometric;
     this.centres     = new int[centres.Length];
     Array.Copy(centres, this.centres, centres.Length);
 }
コード例 #5
0
        /// <summary>
        /// Create an encoder for the <see cref="ITetrahedralChirality"/> element.
        /// </summary>
        /// <param name="tc">stereo element from an atom container</param>
        /// <param name="atomToIndex">map of atoms to indices</param>
        /// <returns>a new geometry encoder</returns>
        private static GeometryEncoder Encoder(ITetrahedralChirality tc, IDictionary <IAtom, int> atomToIndex)
        {
            var ligands = tc.Ligands;

            var centre  = atomToIndex[tc.ChiralAtom];
            var indices = new int[4];

            int offset = -1;
            {
                int i = 0;
                foreach (var ligand in ligands)
                {
                    indices[i] = atomToIndex[ligands[i]];
                    if (indices[i] == centre)
                    {
                        offset = i;
                    }
                    i++;
                }
            }

            // convert clockwise/anticlockwise to -1/+1
            var parity = tc.Stereo == TetrahedralStereo.Clockwise ? -1 : 1;

            // now if any atom is the centre (indicating an implicit
            // hydrogen) we need to adjust the indicies and the parity
            if (offset >= 0)
            {
                // remove the 'implicit' central from the first 3 vertices
                for (int i = offset; i < indices.Length - 1; i++)
                {
                    indices[i] = indices[i + 1];
                }

                // we now take how many vertices we moved which is
                // 3 (last index) minus the index where we started. if the
                // value is odd we invert the parity (odd number of
                // inversions)
                if ((3 - offset) % 2 == 1)
                {
                    parity *= -1;
                }

                // trim the array to size we don't include the last (implicit)
                // vertex when checking the invariants
                var sindices = new int[indices.Length - 1];
                Array.Copy(indices, sindices, indices.Length - 1);
                indices = sindices;
            }

            return(new GeometryEncoder(centre, new BasicPermutationParity(indices), GeometricParity.ValueOf(parity)));
        }
コード例 #6
0
 private static Vector3[] Coords3D(GeometricParity parity)
 {
     if (parity is Tetrahedral3DParity)
     {
         FieldInfo field = null;
         field = parity.GetType().GetField("coordinates", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
         if (field == null)
         {
             Console.Error.WriteLine("Error on accessing coordinates field.");
             return(null);
         }
         return((Vector3[])field.GetValue(parity));
     }
     return(null);
 }
コード例 #7
0
        /// <summary>
        /// Create an encoder for the <see cref="IDoubleBondStereochemistry"/> element.
        /// </summary>
        /// <param name="dbs">stereo element from an atom container</param>
        /// <param name="atomToIndex">map of atoms to indices</param>
        /// <param name="graph">adjacency list of connected vertices</param>
        /// <returns>a new geometry encoder</returns>
        private static GeometryEncoder GetEncoder(IDoubleBondStereochemistry dbs, IDictionary <IAtom, int> atomToIndex, int[][] graph)
        {
            var db = dbs.StereoBond;
            var u  = atomToIndex[db.Begin];
            var v  = atomToIndex[db.End];

            // we now need to expand our view of the environment - the vertex arrays
            // 'us' and <paramref name="vs"/> hold the neighbors of each end point of the double bond
            // (<paramref name="u"/> or 'v'). The first neighbor is always the one stored in the
            // stereo element. The second is the other non-double bonded vertex
            // which we must find from the neighbors list (findOther). If there is
            // no additional atom attached (or perhaps it is an implicit Hydrogen)
            // we use either double bond end point.
            var bs = dbs.Bonds;
            var us = new int[2];
            var vs = new int[2];

            us[0] = atomToIndex[bs[0].GetOther(db.Begin)];
            us[1] = graph[u].Length == 2 ? u : FindOther(graph[u], v, us[0]);

            vs[0] = atomToIndex[bs[1].GetOther(db.End)];
            vs[1] = graph[v].Length == 2 ? v : FindOther(graph[v], u, vs[0]);

            var parity = dbs.Stereo == DoubleBondConformation.Opposite ? +1 : -1;

            var geomParity = GeometricParity.ValueOf(parity);

            // the permutation parity is combined - but note we only use this if we
            // haven't used <paramref name="u"/> or 'v' as place holders (i.e. implicit hydrogens)
            // otherwise there is only '1' and the parity is just '1' (identity)
            PermutationParity permParity = new CombinedPermutationParity(us[1] ==
                                                                         u ? BasicPermutationParity.Identity
                  : new BasicPermutationParity(us), vs[1] == v
                  ? BasicPermutationParity.Identity
                  : new BasicPermutationParity(vs));

            return(new GeometryEncoder(new int[] { u, v }, permParity, geomParity));
        }
コード例 #8
0
        /// <summary>
        /// Create a new encoder for the specified left and right atoms. The parent
        /// is the atom which is connected by a double bond to the left and right
        /// atom. For simple double bonds the parent of each is the other atom, in
        /// cumulenes the parents are not the same.
        /// </summary>
        /// <param name="container">the molecule</param>
        /// <param name="left">the left atom</param>
        /// <param name="leftParent">the left atoms parent (usually <paramref name="right"/>)</param>
        /// <param name="right">the right atom</param>
        /// <param name="rightParent">the right atoms parent (usually <paramref name="left"/>)</param>
        /// <param name="graph">adjacency list representation of the molecule</param>
        /// <returns>a stereo encoder (or null)</returns>
        internal static IStereoEncoder NewEncoder(IAtomContainer container, IAtom left, IAtom leftParent, IAtom right, IAtom rightParent, int[][] graph)
        {
            var leftBonds  = container.GetConnectedBonds(left);
            var rightBonds = container.GetConnectedBonds(right);

            // check the left and right bonds are acceptable
            if (Accept(left, leftBonds) && Accept(right, rightBonds))
            {
                int leftIndex  = container.Atoms.IndexOf(left);
                int rightIndex = container.Atoms.IndexOf(right);

                int leftParentIndex  = container.Atoms.IndexOf(leftParent);
                int rightParentIndex = container.Atoms.IndexOf(rightParent);

                // neighbors of u/v with the bonded atoms (left,right) moved
                // to the back of each array. this is important as we can
                // drop it when we build the permutation parity
                int[] leftNeighbors  = MoveToBack(graph[leftIndex], leftParentIndex);
                int[] rightNeighbors = MoveToBack(graph[rightIndex], rightParentIndex);

                int l1 = leftNeighbors[0];
                int l2 = leftNeighbors[1] == leftParentIndex ? leftIndex : leftNeighbors[1];
                int r1 = rightNeighbors[0];
                int r2 = rightNeighbors[1] == rightParentIndex ? rightIndex : rightNeighbors[1];

                // make 2D/3D geometry
                GeometricParity geometric = Geometric(container, leftIndex, rightIndex, l1, l2, r1, r2);

                // geometric is null if there were no coordinates
                if (geometric != null)
                {
                    return(new GeometryEncoder(new int[] { leftIndex, rightIndex }, new CombinedPermutationParity(
                                                   Permutation(leftNeighbors), Permutation(rightNeighbors)), geometric));
                }
            }
            return(null);
        }
コード例 #9
0
 /// <summary>
 /// Convenience method to create a new encoder for a single stereo centre.
 /// </summary>
 /// <param name="centre">a stereo centre which will be configured</param>
 /// <param name="permutation">calculator for permutation parity</param>
 /// <param name="geometric">geometric calculator</param>
 /// <exception cref="ArgumentException">if the centres[] were empty</exception>
 public GeometryEncoder(int centre, PermutationParity permutation, GeometricParity geometric)
     : this(new int[] { centre }, permutation, geometric)
 {
 }