/// <summary>
        /// Create an encoder for axial 3D stereochemistry for the given start and end atoms.
        /// </summary>
        /// <param name="container">the molecule</param>
        /// <param name="start">start of the cumulated system</param>
        /// <param name="startBonds">bonds connected to the start</param>
        /// <param name="end">end of the cumulated system</param>
        /// <param name="endBonds">bonds connected to the end</param>
        /// <returns>an encoder</returns>
        private static IStereoEncoder Axial3DEncoder(IAtomContainer container, IAtom start, IEnumerable <IBond> startBonds,
                                                     IAtom end, IEnumerable <IBond> endBonds)
        {
            Vector3[]         coordinates = new Vector3[4];
            PermutationParity perm        = new CombinedPermutationParity(Fill3DCoordinates(container, start, startBonds, coordinates, 0), Fill3DCoordinates(container, end, endBonds, coordinates, 2));
            GeometricParity   geom        = new Tetrahedral3DParity(coordinates);

            int u = container.Atoms.IndexOf(start);
            int v = container.Atoms.IndexOf(end);

            return(new GeometryEncoder(new int[] { u, v }, perm, geom));
        }
Пример #2
0
        public void TestParity()
        {
            var m_left = new Mock <PermutationParity>(); var left = m_left.Object;
            var m_right = new Mock <PermutationParity>(); var right = m_right.Object;
            PermutationParity parity = new CombinedPermutationParity(left, right);

            long[] dummy             = new long[5];

            m_left.Setup(n => n.Parity(dummy)).Returns(-1);
            m_right.Setup(n => n.Parity(dummy)).Returns(-1);
            Assert.AreEqual(1, parity.Parity(dummy));

            m_left.Verify(n => n.Parity(dummy), Times.Exactly(1));
            m_right.Verify(n => n.Parity(dummy), Times.Exactly(1));

            m_left.Setup(n => n.Parity(dummy)).Returns(-1);
            m_right.Setup(n => n.Parity(dummy)).Returns(1);
            Assert.AreEqual(-1, parity.Parity(dummy));

            m_left.Setup(n => n.Parity(dummy)).Returns(1);
            m_right.Setup(n => n.Parity(dummy)).Returns(-1);
            Assert.AreEqual(-1, parity.Parity(dummy));

            m_left.Setup(n => n.Parity(dummy)).Returns(1);
            m_right.Setup(n => n.Parity(dummy)).Returns(1);
            Assert.AreEqual(1, parity.Parity(dummy));

            m_left.Setup(n => n.Parity(dummy)).Returns(0);
            m_right.Setup(n => n.Parity(dummy)).Returns(1);
            Assert.AreEqual(0, parity.Parity(dummy));

            m_left.Setup(n => n.Parity(dummy)).Returns(1);
            m_right.Setup(n => n.Parity(dummy)).Returns(0);
            Assert.AreEqual(0, parity.Parity(dummy));

            m_left.Setup(n => n.Parity(dummy)).Returns(0);
            m_right.Setup(n => n.Parity(dummy)).Returns(-1);
            Assert.AreEqual(0, parity.Parity(dummy));

            m_left.Setup(n => n.Parity(dummy)).Returns(-1);
            m_right.Setup(n => n.Parity(dummy)).Returns(0);
            Assert.AreEqual(0, parity.Parity(dummy));
        }
        /// <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));
        }