예제 #1
0
        /// <summary>
        /// Recognise the cyclic carbohydrate projections.
        /// </summary>
        /// <param name="projections">the types of projections to recognise</param>
        /// <returns>recognised stereocenters</returns>
        public IEnumerable <IStereoElement <IChemObject, IChemObject> > Recognise(ICollection <Projection> projections)
        {
            if (!projections.Contains(Projection.Haworth) && !projections.Contains(Projection.Chair))
            {
                yield break;
            }

            var ringSearch = new RingSearch(container, graph);

            foreach (var isolated in ringSearch.Isolated())
            {
                if (isolated.Length < 5 || isolated.Length > 7)
                {
                    continue;
                }

                var cycle = Arrays.CopyOf(GraphUtil.Cycle(graph, isolated),
                                          isolated.Length);

                var points     = CoordinatesOfCycle(cycle, container);
                var turns      = GetTurns(points);
                var projection = WoundProjection.OfTurns(turns);

                if (!projections.Contains(projection.Projection))
                {
                    continue;
                }

                // ring is not aligned correctly for Haworth
                if (projection.Projection == Projection.Haworth && !CheckHaworthAlignment(points))
                {
                    continue;
                }

                var horizontalXy = HorizontalOffset(points, turns, projection.Projection);

                // near vertical, should also flag as potentially ambiguous
                if (1 - Math.Abs(horizontalXy.Y) < QuartCardinalityThreshold)
                {
                    continue;
                }

                var above = (int[])cycle.Clone();
                var below = (int[])cycle.Clone();

                if (!AssignSubstituents(cycle, above, below, projection, horizontalXy))
                {
                    continue;
                }

                foreach (var center in NewTetrahedralCenters(cycle, above, below, projection))
                {
                    yield return(center);
                }
            }

            yield break;
        }
예제 #2
0
        /// <summary>
        /// Compute all rings up to and including the <paramref name="maxRingSize"/>. The
        /// container is first partitioned into ring systems which are then processed
        /// separately. If the molecule has already be partitioned, consider using <see cref="FindAllRingsInIsolatedRingSystem(IAtomContainer, int)"/>.
        /// </summary>
        /// <param name="container">The AtomContainer to be searched for rings</param>
        /// <param name="maxRingSize">Maximum ring size to consider. Provides a possible
        ///                    breakout from recursion for complex compounds.</param>
        /// <returns>A RingSet with all rings in the AtomContainer</returns>
        /// <exception cref="CDKException">An exception thrown if the threshold was exceeded</exception>
        public IRingSet FindAllRings(IAtomContainer container, int maxRingSize)
        {
            var edges = EdgeToBondMap.WithSpaceFor(container);
            var graph = GraphUtil.ToAdjList(container, edges);

            var rs      = new RingSearch(container, graph);
            var ringSet = container.Builder.NewRingSet();

            // don't need to run on isolated rings, just need to put vertices in
            // cyclic order
            foreach (var isolated in rs.Isolated())
            {
                if (isolated.Length <= maxRingSize)
                {
                    var ring = ToRing(container, edges, GraphUtil.Cycle(graph, isolated));
                    ringSet.Add(ring);
                }
            }

            // for each set of fused cyclic vertices run the separate search
            foreach (var fused in rs.Fused())
            {
                var ac = new AllCycles(GraphUtil.Subgraph(graph, fused), Math.Min(maxRingSize, fused.Length), threshold.Value);

                if (!ac.Completed)
                {
                    throw new CDKException("Threshold exceeded for AllRingsFinder");
                }

                foreach (var path in ac.GetPaths())
                {
                    IRing ring = ToRing(container, edges, path, fused);
                    ringSet.Add(ring);
                }
            }

            return(ringSet);
        }