예제 #1
0
        public void ValueOf()
        {
            GeometricParity odd  = GeometricParity.ValueOf(-1);
            GeometricParity even = GeometricParity.ValueOf(1);

            Assert.AreEqual(-1, odd.Parity);
            Assert.AreEqual(+1, even.Parity);
        }
        /// <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)));
        }
        /// <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));
        }